Android编程之电池电量信息更新的方法(基于BatteryService实现)
本文实例讲述了Android编程之电池电量信息更新的方法。分享给大家供大家参考,具体如下:
电池的信息,电压,温度,充电状态等等,都是由BatteryService来提供的。BatteryService是跑在system_process当中,在系统初始化的时候启动,如下
在SystemServer.java中可以看到启动BatteryService的代码:
Log.i(TAG,"StartingBatteryService."); BatteryServicebattery=newBatteryService(context); ServiceManager.addService("battery",battery);
1.数据来源
BatteryService通过JNI(com_android_server_BatteryService.cpp)读取数据。BatteryService通过JNI注册的不仅有函数,还有变量。如下:
//##############在BatteryService.java中声明的变量################ privatebooleanmAcOnline; privatebooleanmUsbOnline; privateintmBatteryStatus; privateintmBatteryHealth; privatebooleanmBatteryPresent; privateintmBatteryLevel; privateintmBatteryVoltage; privateintmBatteryTemperature; privateStringmBatteryTechnology;
在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");
上面这些变量的值,对应是从下面的文件中读取的,一只文件存储一个数值。
#defineAC_ONLINE_PATH"/sys/class/power_supply/ac/online" #defineUSB_ONLINE_PATH"/sys/class/power_supply/usb/online" #defineBATTERY_STATUS_PATH"/sys/class/power_supply/battery/status" #defineBATTERY_HEALTH_PATH"/sys/class/power_supply/battery/health" #defineBATTERY_PRESENT_PATH"/sys/class/power_supply/battery/present" #defineBATTERY_CAPACITY_PATH"/sys/class/power_supply/battery/capacity" #defineBATTERY_VOLTAGE_PATH"/sys/class/power_supply/battery/batt_vol" #defineBATTERY_TEMPERATURE_PATH"/sys/class/power_supply/battery/batt_temp" #defineBATTERY_TECHNOLOGY_PATH"/sys/class/power_supply/battery/technology"
Android是运行在Linux内核上面的,/sys/class/power_supply亦是Linux内核下面的目录。至于这些文件时怎么生成的,则是由Platform来控制的。
2.数据传送
电池的这些信息是通过何种方式,被其他应用所获得的。可以想到的有两种方式,第一种,应用主动从BatteryService获得数据;第二种,BatteryService主动把数据传送给所关心的应用程序。
BatteryService采用的是第二种方式,所有的电池的信息数据是通过Intent传送出去的。在BatteryService.java中,Code如下:
Intentintent=newIntent(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。
注册方法如下:
IntentFiltermIntentFilter=newIntentFilter(); mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); registerReceiver(mIntentReceiver,mIntentFilter); privateBroadcastReceivermIntentReceiver=newBroadcastReceiver(){ @Override publicvoidonReceive(Contextcontext,Intentintent){ //TODOAuto-generatedmethodstub Stringaction=intent.getAction(); if(action.equals(Intent.ACTION_BATTERY_CHANGED)){ intnVoltage=intent.getIntExtra("voltage",0); if(nVoltage!=0){ mVoltage.setText("V:"+nVoltage+"mV-Success..."); } else{ mVoltage.setText("V:"+nVoltage+"mV-fail..."); } } } };
4.数据更新
电池的信息会随着时间不停变化,自然地,就需要考虑如何实时的更新电池的数据信息。在BatteryService启动的时候,会同时通过UEventObserver启动一个onUEventThread。
每一个Process最多只能有一个onUEventThread,即使这个Process中有多个UEventObserver的实例。当在一个Process中,第一次CallstartObserving()方法后,这个UEventthread就启动了。
而一旦这个UEventthread启动之后,就不会停止。
//在BatteryService.java中 mUEventObserver.startObserving("SUBSYSTEM=power_supply"); privateUEventObservermUEventObserver=newUEventObserver(){ @Override publicvoidonUEvent(UEventObserver.UEventevent){ update(); } };
在UEventthread中会不停调用update()方法,来更新电池的信息数据。
希望本文所述对大家Android程序设计有所帮助。