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

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

复制代码
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

 

posted on   Hello-World3  阅读(687)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示