标签:
MSM8909+Android5.1.1之BSP开发---电池管理2---BatteryInfo.java
先来借用MTK对电池管理的框架图
图1
通过电话测试指令:*#*#4636#*#*可以弹出Testing界面
图2
选择Battery information,进入:
图3
我们接入USB或是DC充电的时候,Power plug都显示的时Unknown
说明底层就判断为Unknown类型,此问题要查清楚
BatteryInfo对应的代码为packages\apps\Settings\src\com\android\settings\BatteryInfo.java
1. \packages\apps\Settings\AndroidManifest.xml
<activityandroid:name="BatteryInfo" android:label="@string/battery_info_label"
android:taskAffinity="com.android.settings"
android:parentActivityName="Settings">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN" />
<categoryandroid:name="android.intent.category.DEVELOPMENT_PREFERENCE" />
<categoryandroid:name="android.intent.category.VOICE_LAUNCH" />
</intent-filter>
</activity>(1) android:label
android:label="@string/battery_info_label",label表示标签,@表示引用,表示从string这个文件中引用battery_info_label这个键值的值,
\packages\apps\Settings\res\values\ strings.xml中对应的值如下:
<!-- The title of the activity to seebattery info. -->
<stringname="battery_info_label">Battery info</string>
(2) android:taskAffinity
android:taskAffinity="com.android.settings"表示BatteryInfo Activity希望进入com.android.settings这个task。
Activity的归属,也就是Activity应该在哪个Task中,Activity与Task的吸附关系。我们知道,一般情况下在同一个应用中,启动的Activity都在同一个Task中,它们在该Task中度过自己的生命周期,这些Activity是从一而终的好榜样。
那么为什么我们创建的Activity会进入这个Task中?它们会转到其它的Task中吗?如果转到其它的Task中,它们会到什么样的Task中去?
解决这些问题的关键,在于每个Activity的taskAffinity属性。
每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明该Activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果Application也没有指明,那么该taskAffinity的值就等于包名。而Task也有自己的affinity属性,它的值等于它的根Activity的taskAffinity的值。
2. BatteryInfo.java代码分析
2.1 onCreate()
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.battery_info);
// create the IntentFilter that will be used to listen
// to battery status broadcasts
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
}(1) R.layout.battery_info
其值在packages\apps\Settings\res\layout\battery_info.xml定义
(2) 创建一个IntentFilter类的对象mIntentFilter
用于监听电池状态广播。
(3) mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
为此IntentFilter增加一个ACTION_BATTERY_CHANGED的action,也就是说当其他Activity、或是Service等发送包含有ACTION_BATTERY_CHANGED的intent时,BatteryInfo就执行更新电池状态的动作
2.2 onResume()
public void onResume() {
super.onResume();
mStatus = (TextView)findViewById(R.id.status);
mPower = (TextView)findViewById(R.id.power);
mLevel = (TextView)findViewById(R.id.level);
mScale = (TextView)findViewById(R.id.scale);
mHealth = (TextView)findViewById(R.id.health);
mTechnology = (TextView)findViewById(R.id.technology);
mVoltage = (TextView)findViewById(R.id.voltage);
mTemperature = (TextView)findViewById(R.id.temperature);
mUptime = (TextView) findViewById(R.id.uptime);
// Get awake time plugged in and on battery
mBatteryStats =IBatteryStats.Stub.asInterface(ServiceManager.getService(
BatteryStats.SERVICE_NAME));
mScreenStats = IPowerManager.Stub.asInterface(ServiceManager.getService(POWER_SERVICE));
mHandler.sendEmptyMessageDelayed(EVENT_TICK, 3000);
registerReceiver(mIntentReceiver, mIntentFilter);
}在onResume()方法中通过registerReceiver(mIntentReceiver,mIntentFilter);注册一个Receiver,最终在onReceive()方法中收到值为ACTION_BATTERY_CHANGED的action时,BatteryInfo这个Activity要更新电池状态信息。
(1) 创建一个Handler
mHandler.sendEmptyMessageDelayed(EVENT_TICK,3000);使用到Handler,其创建如下:
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case EVENT_TICK:
updateBatteryStats();
sendEmptyMessageDelayed(EVENT_TICK, 1000);
break;
}
}
};重写handleMessage()用于处理消息EVENT_TICK,在收到此消息后,调用updateBatteryStats()更新电池状态,并1000ms后发送EVENT_TICK消息。
(2) 注册一个监听器
/**
*Listens for intent broadcasts
*/
private IntentFilter mIntentFilter;
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
int plugType =intent.getIntExtra("plugged", 0);
mLevel.setText("" +intent.getIntExtra("level", 0));
mScale.setText("" +intent.getIntExtra("scale", 0));
mVoltage.setText("" +intent.getIntExtra("voltage", 0) + " "
+getString(R.string.battery_info_voltage_units));
mTemperature.setText("" +tenthsToFixedString(intent.getIntExtra("temperature", 0))
+getString(R.string.battery_info_temperature_units));
mTechnology.setText("" +intent.getStringExtra("technology"));
mStatus.setText(Utils.getBatteryStatus(getResources(), intent));
switch (plugType) {
case 0: mPower.setText(getString(R.string.battery_info_power_unplugged));
break;
case BatteryManager.BATTERY_PLUGGED_AC: mPower.setText(getString(R.string.battery_info_power_ac));
break;
case BatteryManager.BATTERY_PLUGGED_USB: mPower.setText(getString(R.string.battery_info_power_usb));
break;
caseBatteryManager.BATTERY_PLUGGED_WIRELESS:
mPower.setText(getString(R.string.battery_info_power_wireless));
break;
case(BatteryManager.BATTERY_PLUGGED_AC|BatteryManager.BATTERY_PLUGGED_USB): mPower.setText(getString(R.string.battery_info_power_ac_usb));
break;
default: mPower.setText(getString(R.string.battery_info_power_unknown));
break;
}
int health =intent.getIntExtra("health", BatteryManager.BATTERY_HEALTH_UNKNOWN);
String healthString;
if (health ==BatteryManager.BATTERY_HEALTH_GOOD) {
healthString =getString(R.string.battery_info_health_good);
} else if (health ==BatteryManager.BATTERY_HEALTH_OVERHEAT) {
healthString =getString(R.string.battery_info_health_overheat);
} else if (health ==BatteryManager.BATTERY_HEALTH_DEAD) {
healthString =getString(R.string.battery_info_health_dead);
} else if (health ==BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE) {
healthString =getString(R.string.battery_info_health_over_voltage);
} else if (health ==BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE) {
healthString =getString(R.string.battery_info_health_unspecified_failure);
} else if (health ==BatteryManager.BATTERY_HEALTH_COLD) {
healthString =getString(R.string.battery_info_health_cold);
} else {
healthString =getString(R.string.battery_info_health_unknown);
}
mHealth.setText(healthString);
}
}
};1) Battery status信息的更新
其中Battery status有些特别:
mStatus.setText(Utils.getBatteryStatus(getResources(),intent));
看packages\apps\Settings\src\com\android\settings\Utils.java\getBatteryStatus()的实现:
public static StringgetBatteryStatus(Resources res, Intent batteryChangedIntent) {
final Intent intent = batteryChangedIntent;
int plugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
BatteryManager.BATTERY_STATUS_UNKNOWN);
String statusString;
if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
int resId;
if (plugType == BatteryManager.BATTERY_PLUGGED_AC) {
resId =R.string.battery_info_status_charging_ac;
} else if (plugType == BatteryManager.BATTERY_PLUGGED_USB) {
resId =R.string.battery_info_status_charging_usb;
} else if (plugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) {
resId =R.string.battery_info_status_charging_wireless;
} else {
resId =R.string.battery_info_status_charging;
}
statusString = res.getString(resId);
} else if (status ==BatteryManager.BATTERY_STATUS_DISCHARGING) {
statusString = res.getString(R.string.battery_info_status_discharging);
} else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
statusString = res.getString(R.string.battery_info_status_not_charging);
} else if (status == BatteryManager.BATTERY_STATUS_FULL) {
statusString = res.getString(R.string.battery_info_status_full);
} else {
statusString = res.getString(R.string.battery_info_status_unknown);
}
return statusString;
}从上面可知,plugType是unknown,所以从\packages\apps\Settings\res\values\strings.xml的battery_info_status_charging获取到充电状态是Charing,如下:
<stringname="battery_info_status_charging">Charging</string>
2) 如何获取电池的信息
public void onReceive(Context context,Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
int plugType =intent.getIntExtra("plugged", 0);这是上面其中一段代码,收到广播,且其中intent的action的值为 ACTION_BATTERY_CHANGED时就从intent中读取plugged的值,这个intent是由BatteryService广播出来的。
2.3 onPause()
@Override
public void onPause() {
super.onPause();
mHandler.removeMessages(EVENT_TICK);
Slog.e(TAG, "BatteryInfo--->onPause()");
// we are no longer on the screen stop the observers
unregisterReceiver(mIntentReceiver);
}比较简单,就是删除EVENT_TICK消息和注销监听器mIntentReceiver
MSM8909+Android5.1.1之BSP开发---电池管理2---BatteryInfo.java
标签:
原文地址:http://blog.csdn.net/loongembedded/article/details/50364648