BUG1.关于android中USB充电跟AC充电的识别错误。
首先找到在Settings的显示Battery状态的Status类。可以看到,关于电池状态的信息接收是由一个BroadCastReciever完成的。
- private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
- int level = intent.getIntExtra("level", 0);
- int scale = intent.getIntExtra("scale", 100);
- mBatteryLevel.setSummary(String.valueOf(level * 100 / scale) + "%");
- int plugType = intent.getIntExtra("plugged", 0);
- int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
- String statusString;
- if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
- statusString = getString(R.string.battery_info_status_charging);
- if (plugType > 0) {
- statusString = statusString + " " + getString(
- (plugType == BatteryManager.BATTERY_PLUGGED_AC)
- ? R.string.battery_info_status_charging_ac
- : R.string.battery_info_status_charging_usb);
- }
- } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
- statusString = getString(R.string.battery_info_status_discharging);
- } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
- statusString = getString(R.string.battery_info_status_not_charging);
- } else if (status == BatteryManager.BATTERY_STATUS_FULL) {
- statusString = getString(R.string.battery_info_status_full);
- } else {
- statusString = getString(R.string.battery_info_status_unknown);
- }
- mBatteryStatus.setSummary(statusString);
- }
- }
- };
其中关于AC还是USB充电是通过Intent中的plugged标签接收的插入类型判断的。
通过对这个标签的搜索分析。可以找到在BatteryService类中有这个广播信息的发送。
- private final void sendIntent() {
- // Pack up the values and broadcast them to everyone
- Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
- | Intent.FLAG_RECEIVER_REPLACE_PENDING);
- int icon = getIcon(mBatteryLevel);
- intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryStatus);
- intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryHealth);
- intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryPresent);
- intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryLevel);
- intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE);
- intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon);
- intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);
- intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryVoltage);
- intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryTemperature);
- intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryTechnology);
- if (false) {
- Slog.d(TAG, "updateBattery level:" + mBatteryLevel +
- " scale:" + BATTERY_SCALE + " status:" + mBatteryStatus +
- " health:" + mBatteryHealth + " present:" + mBatteryPresent +
- " voltage: " + mBatteryVoltage +
- " temperature: " + mBatteryTemperature +
- " technology: " + mBatteryTechnology +
- " AC powered:" + mAcOnline + " USB powered:" + mUsbOnline +
- " icon:" + icon );
- }
- ActivityManagerNative.broadcastStickyIntent(intent, null);
- }
现在需要搞清楚这些属性是在什么地方进行赋值的。
通过查找关键字可以看到在BatteryService类中有一个方法。
- private synchronized final void update() {
- native_update();
其中的native_update()定义为JNI方法。
- private native void native_update();
在frameworks/base/services/jni目录下可以找到对应的jni实现。
com_android_server_BatteryService.cpp
- static void android_server_BatteryService_update(JNIEnv* env, jobject obj)
- {
- setBooleanField(env, obj, gPaths.acOnlinePath, gFieldIds.mAcOnline);
- setBooleanField(env, obj, gPaths.usbOnlinePath, gFieldIds.mUsbOnline);
- setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent);
- setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);
- setVoltageField(env, obj, gPaths.batteryVoltagePath, gFieldIds.mBatteryVoltage);
- setIntField(env, obj, gPaths.batteryTemperaturePath, gFieldIds.mBatteryTemperature);
- const int SIZE = 128;
- char buf[SIZE];
- if (readFromFile(gPaths.batteryStatusPath, buf, SIZE) > 0)
- env->SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf));
- else
- env->SetIntField(obj, gFieldIds.mBatteryStatus,
- gConstants.statusUnknown);
- if (readFromFile(gPaths.batteryHealthPath, buf, SIZE) > 0)
- env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf));
- if (readFromFile(gPaths.batteryTechnologyPath, buf, SIZE) > 0)
- env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf));
- }
完成属性的赋值。
sys系统中读取的值为:
- #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"
确定问题的产生为底层对USB状态的识别错误。
参考信息:
http://blog.csdn.net/liangshengyang/article/details/5821031#