欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android编程之电池电量信息更新的方法(基于BatteryService实现)

程序员文章站 2023-12-13 13:23:16
本文实例讲述了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程序设计有所帮助。

上一篇:

下一篇: