Skip to main content
 首页 » 编程设计

Android灯光系统(4)——电池灯分析实验

2022年07月19日183webabcd

一、电池事件的广播的注册

1.运行init进程创建SystemServer 
 
2.一方面,创建BatteryService,获得电池灯,创建BatteryListener用来监听底层的上报事件。 
(1)SystemServer.java :  
startCoreServices() 
    mSystemServiceManager.startService(BatteryService.class); 
 
(2)SystemServiceManager.java:  
startService() 
    BatteryService() //构造函数 
        mLed = new Led(context, getLocalService(LightsManager.class)); 
            Led() 
                mBatteryLight = lights.getLight(LightsManager.LIGHT_ID_BATTERY); 
 
    service.onStart(); //BatteryService.java 
        /* 
         * 电池监听器,当电池的属性发生变化的时候BatteryListener的batteryPropertiesChanged() 
         * 就会被调用,它会去调用update()方法,然后调用sendIntentLockd(),然后调用updateLightsLocked() 
         * 或设置电池属性。 
         */ 
        batteryPropertiesRegistrar.registerListener(new BatteryListener()); 
        publishBinderService("battery", new BinderService()); 
        publishLocalService(BatteryManagerInternal.class, new LocalService()); 
 
 
3.另一方,创建PowerManagerService 
SystemServer.java :  
startBootstrapServices() 
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); 
 
获得BatteryService 
SystemServer.java:  
startOtherServices() 
    mPowerManagerService.systemReady(mActivityManagerService.getAppOpsService()); //PowerManagerService.java 
        mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class); 
 
        /* 注册电池广播接收器,监听ACTION_BATTERY_CHANGED */ 
        IntentFilter filter = new IntentFilter(); 
        filter.addAction(Intent.ACTION_BATTERY_CHANGED); 
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 
        /* 
         * 池电量发生变化的时候BatteryReceiver的onReceiver()方法就会被调用。它最终会调用到 
         * updatePowerStateLocked() 
         */ 
        mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);

二、电池事件的广播与处理

1.Linux驱动上报电池事件 
 
2.BatteryListener的监听函数batteryPropertiesChanged被调用 
 
3.广播ACTION_BATTERY_CHANGED更新电池灯,调用细节如下 
(1)BatteryService.java:  
update() 
    processValuesLocked(false); 
        sendIntentLocked(); // 
        mLed.updateLightsLocked(); // 
 
①sendIntentLocked() //BatteryService.java 
final Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); 
    mHandler.post(new Runnable()  
        @Override 
        public void run()  
            ActivityManagerNative.broadcastStickyIntent(intent, null, UserHandle.USER_ALL); 
 
    ); 
 
 
②updateLightsLocked() //BatteryService.java 
    /*调用native方法设置LED*/ 
    mBatteryLight.setColor(mBatteryLowARGB); 
    mBatteryLight.setFlashing(mBatteryLowARGB, Light.LIGHT_FLASH_TIMED, mBatteryLedOn, mBatteryLedOff); 
    mBatteryLight.setColor(mBatteryFullARGB); 
    mBatteryLight.setColor(mBatteryMediumARGB); 
    mBatteryLight.turnOff(); 
 
 
4.收到广播消息后执行BatteryReceiver.onReceive,调用细节如下 
(1)PowerManagerService.java:  
onReceive() 
    handleBatteryStateChangedLocked(); 
        updatePowerStateLocked();

三、笔记

1.启动服务的流程

SystemServiceManager.startService(BatteryService.class); //SystemServer.java 
    /*1.获取构造函数,然后构造这个service*/ 
    Constructor<T> constructor = serviceClass.getConstructor(Context.class); 
    service = constructor.newInstance(mContext); 
 
    /*2.调用add()将所有service放到链表ArrayList<SystemService>中*/ 
    ArrayList<SystemService>.add(service);  
 
    /*3.调用这个服务的onStart()函数*/ 
    service.onStart(); 

所以一个服务的启动,首先构造函数被调用,其次被调用的就是onStart()。

2.获取xml中系统定义的资源

BatteryService.java:Led() 
mBatteryLowARGB = context.getResources().getInteger(com.android.internal.R.integer.config_notificationsBatteryLowARGB); 
 
config_notificationsBatteryLowARGB定义在: 
<integer name="config_notificationsBatteryLowARGB">0xFFFF0000</integer>   //base/core/res/res/values/config.xml 
 
<java-symbol type="integer" name="config_notificationsBatteryLowARGB" />  //base/core/res/res/values/Symbols.xml

3.BatteryService中使用LightsService的方法

/*1.LightsService中使用publishLocalService来"发布"自己*/ 
mSystemServiceManager.startService(LightsService.class); 
publishLocalService(LightsManager.class, mService); 
 
/*2.BatteryService中来获取LightsService发布的Service*/ 
LightsManager lights = getLocalService(LightsManager.class); 
 
/*3.获取LightsService的控制LED的方法并控制LED*/ 
Light mBatteryLight = lights.getLight(LightsManager.LIGHT_ID_BATTERY); 
mBatteryLight.setColor(mBatteryLowARGB); 
mBatteryLight.setFlashing(mBatteryLowARGB, Light.LIGHT_FLASH_TIMED, mBatteryLedOn, mBatteryLedOff); 
mBatteryLight.turnOff();

四、例子App

由于Android5.1的电池灯和通知灯使用的是同一个LED,请见通知灯的Demo


本文参考链接:https://www.cnblogs.com/hellokitty2/p/10819242.html