Android编程之电池电量信息更新的方法(基于BatteryService实现)
本文实例讲述了android编程之电池电量信息更新的方法。分享给大家供大家参考,具体如下:
电池的信息,电压,温度,充电状态等等,都是由batteryservice来提供的。batteryservice是跑在system_process当中,在系统初始化的时候启动,如下
在systemserver.java中可以看到启动batteryservice的代码:
log.i(tag, "starting battery service."); batteryservice battery = new batteryservice(context); servicemanager.addservice("battery", battery);
1. 数据来源
batteryservice通过jni(com_android_server_batteryservice.cpp)读取数据。batteryservice通过jni注册的不仅有函数,还有变量。 如下:
//##############在batteryservice.java中声明的变量################ private boolean maconline; private boolean musbonline; private int mbatterystatus; private int mbatteryhealth; private boolean mbatterypresent; private int mbatterylevel; private int mbatteryvoltage; private int mbatterytemperature; private string mbatterytechnology;
在batteryservice.java中声明的变量,在com_android_server_batteryservice.cpp*用,即在com_android_server_batteryservice.cpp中其实操作的也是batteryservice.java中声明的变量
gfieldids.maconline = env->getfieldid(clazz, "maconline", "z"); gfieldids.musbonline = env->getfieldid(clazz, "musbonline", "z"); gfieldids.mbatterystatus = env->getfieldid(clazz, "mbatterystatus", "i"); gfieldids.mbatteryhealth = env->getfieldid(clazz, "mbatteryhealth", "i"); gfieldids.mbatterypresent = env->getfieldid(clazz, "mbatterypresent", "z"); gfieldids.mbatterylevel = env->getfieldid(clazz, "mbatterylevel", "i"); gfieldids.mbatterytechnology = env->getfieldid(clazz, "mbatterytechnology", "ljava/lang/string;"); gfieldids.mbatteryvoltage = env->getfieldid(clazz, "mbatteryvoltage", "i"); gfieldids.mbatterytemperature = env->getfieldid(clazz, "mbatterytemperature", "i");
上面这些变量的值,对应是从下面的文件中读取的,一只文件存储一个数值。
#define ac_online_path "/sys/class/power_supply/ac/online" #define usb_online_path "/sys/class/power_supply/usb/online" #define battery_status_path "/sys/class/power_supply/battery/status" #define battery_health_path "/sys/class/power_supply/battery/health" #define battery_present_path "/sys/class/power_supply/battery/present" #define battery_capacity_path "/sys/class/power_supply/battery/capacity" #define battery_voltage_path "/sys/class/power_supply/battery/batt_vol" #define battery_temperature_path "/sys/class/power_supply/battery/batt_temp" #define battery_technology_path "/sys/class/power_supply/battery/technology"
android是运行在linux内核上面的,/sys/class/power_supply亦是linux内核下面的目录。至于这些文件时怎么生成的,则是由platform来控制的。
2. 数据传送
电池的这些信息是通过何种方式,被其他应用所获得的。可以想到的有两种方式,第一种,应用主动从batteryservice获得数据;第二种,batteryservice主动把数据传送给所关心的应用程序。
batteryservice采用的是第二种方式,所有的电池的信息数据是通过intent传送出去的。在batteryservice.java中,code如下:
intent intent = new intent(intent.action_battery_changed); intent.addflags(intent.flag_receiver_registered_only); intent.putextra("status", mbatterystatus); intent.putextra("health", mbatteryhealth); intent.putextra("present", mbatterypresent); intent.putextra("level", mbatterylevel); intent.putextra("scale", battery_scale); intent.putextra("icon-small", icon); intent.putextra("plugged", mplugtype); intent.putextra("voltage", mbatteryvoltage); intent.putextra("temperature", mbatterytemperature); intent.putextra("technology", mbatterytechnology); activitymanagernative.broadcaststickyintent(intent, null);
3. 数据接收
应用如果想要接收到batteryservice发送出来的电池信息,则需要注册一个intent为intent.action_battery_changed的broadcastreceiver。
注册方法如下:
intentfilter mintentfilter = new intentfilter(); mintentfilter.addaction(intent.action_battery_changed); registerreceiver(mintentreceiver, mintentfilter); private broadcastreceiver mintentreceiver = new broadcastreceiver() { @override public void onreceive(context context, intent intent) { // todo auto-generated method stub string action = intent.getaction(); if (action.equals(intent.action_battery_changed)) { int nvoltage = intent.getintextra("voltage", 0); if(nvoltage!=0){ mvoltage.settext("v: " + nvoltage + "mv - success..."); } else{ mvoltage.settext("v: " + nvoltage + "mv - fail..."); } } } };
4. 数据更新
电池的信息会随着时间不停变化,自然地,就需要考虑如何实时的更新电池的数据信息。在batteryservice启动的时候,会同时通过ueventobserver启动一个onuevent thread。
每一个process最多只能有一个onuevent thread,即使这个process中有多个ueventobserver的实例。当在一个process中,第一次call startobserving()方法后,这个uevent thread就启动了。
而一旦这个uevent thread启动之后,就不会停止。
//在batteryservice.java中 mueventobserver.startobserving("subsystem=power_supply"); private ueventobserver mueventobserver = new ueventobserver() { @override public void onuevent(ueventobserver.uevent event) { update(); } };
在uevent thread中会不停调用 update()方法,来更新电池的信息数据。
希望本文所述对大家android程序设计有所帮助。