BUG1.关于android中USB充电跟AC充电的识别错误。

首先找到在Settings的显示Battery状态的Status类。可以看到,关于电池状态的信息接收是由一个BroadCastReciever完成的。

 

  1. private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() { 
  2.  
  3.         @Override 
  4.         public void onReceive(Context context, Intent intent) { 
  5.             String action = intent.getAction(); 
  6.             if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { 
  7.  
  8.                 int level = intent.getIntExtra("level"0); 
  9.                 int scale = intent.getIntExtra("scale"100); 
  10.  
  11.                 mBatteryLevel.setSummary(String.valueOf(level * 100 / scale) + "%"); 
  12.  
  13.                 int plugType = intent.getIntExtra("plugged"0); 
  14.                 int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN); 
  15.                 String statusString; 
  16.                 if (status == BatteryManager.BATTERY_STATUS_CHARGING) { 
  17.                     statusString = getString(R.string.battery_info_status_charging); 
  18.                     if (plugType > 0) { 
  19.                         statusString = statusString + " " + getString( 
  20.                                 (plugType == BatteryManager.BATTERY_PLUGGED_AC) 
  21.                                         ? R.string.battery_info_status_charging_ac 
  22.                                         : R.string.battery_info_status_charging_usb); 
  23.                     } 
  24.                 } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) { 
  25.                     statusString = getString(R.string.battery_info_status_discharging); 
  26.                 } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) { 
  27.                     statusString = getString(R.string.battery_info_status_not_charging); 
  28.                 } else if (status == BatteryManager.BATTERY_STATUS_FULL) { 
  29.                     statusString = getString(R.string.battery_info_status_full); 
  30.                 } else { 
  31.                     statusString = getString(R.string.battery_info_status_unknown); 
  32.                 } 
  33.                 mBatteryStatus.setSummary(statusString); 
  34.             } 
  35.         } 
  36.     }; 

其中关于AC还是USB充电是通过Intent中的plugged标签接收的插入类型判断的。

通过对这个标签的搜索分析。可以找到在BatteryService类中有这个广播信息的发送。

  1. private final void sendIntent() { 
  2.         //  Pack up the values and broadcast them to everyone 
  3.         Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED); 
  4.         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 
  5.                 | Intent.FLAG_RECEIVER_REPLACE_PENDING); 
  6.  
  7.         int icon = getIcon(mBatteryLevel); 
  8.  
  9.         intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryStatus); 
  10.         intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryHealth); 
  11.         intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryPresent); 
  12.         intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryLevel); 
  13.         intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE); 
  14.         intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon); 
  15.         intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType); 
  16.         intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryVoltage); 
  17.         intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryTemperature); 
  18.         intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryTechnology); 
  19.  
  20.         if (false) { 
  21.             Slog.d(TAG, "updateBattery level:" + mBatteryLevel + 
  22.                     " scale:" + BATTERY_SCALE + " status:" + mBatteryStatus + 
  23.                     " health:" + mBatteryHealth +  " present:" + mBatteryPresent + 
  24.                     " voltage: " + mBatteryVoltage + 
  25.                     " temperature: " + mBatteryTemperature + 
  26.                     " technology: " + mBatteryTechnology + 
  27.                     " AC powered:" + mAcOnline + " USB powered:" + mUsbOnline + 
  28.                     " icon:" + icon ); 
  29.         } 
  30.  
  31.         ActivityManagerNative.broadcastStickyIntent(intent, null); 
  32.     } 

现在需要搞清楚这些属性是在什么地方进行赋值的。

通过查找关键字可以看到在BatteryService类中有一个方法。

  1. private synchronized final void update() { 
  2.         native_update(); 

其中的native_update()定义为JNI方法。

  1. private native void native_update(); 

在frameworks/base/services/jni目录下可以找到对应的jni实现。

com_android_server_BatteryService.cpp

  1. static void android_server_BatteryService_update(JNIEnv* env, jobject obj) 
  2.     setBooleanField(env, obj, gPaths.acOnlinePath, gFieldIds.mAcOnline); 
  3.     setBooleanField(env, obj, gPaths.usbOnlinePath, gFieldIds.mUsbOnline); 
  4.     setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent); 
  5.      
  6.     setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel); 
  7.     setVoltageField(env, obj, gPaths.batteryVoltagePath, gFieldIds.mBatteryVoltage); 
  8.     setIntField(env, obj, gPaths.batteryTemperaturePath, gFieldIds.mBatteryTemperature); 
  9.      
  10.     const int SIZE = 128; 
  11.     char buf[SIZE]; 
  12.      
  13.     if (readFromFile(gPaths.batteryStatusPath, buf, SIZE) > 0) 
  14.         env->SetIntField(obj, gFieldIds.mBatteryStatus, getBatteryStatus(buf)); 
  15.     else 
  16.         env->SetIntField(obj, gFieldIds.mBatteryStatus, 
  17.                          gConstants.statusUnknown); 
  18.      
  19.     if (readFromFile(gPaths.batteryHealthPath, buf, SIZE) > 0) 
  20.         env->SetIntField(obj, gFieldIds.mBatteryHealth, getBatteryHealth(buf)); 
  21.  
  22.     if (readFromFile(gPaths.batteryTechnologyPath, buf, SIZE) > 0) 
  23.         env->SetObjectField(obj, gFieldIds.mBatteryTechnology, env->NewStringUTF(buf)); 

完成属性的赋值。

sys系统中读取的值为:

 

  1. #define AC_ONLINE_PATH "/sys/class/power_supply/ac/online" 
  2. #define USB_ONLINE_PATH "/sys/class/power_supply/usb/online" 
  3. #define BATTERY_STATUS_PATH "/sys/class/power_supply/battery/status" 
  4. #define BATTERY_HEALTH_PATH "/sys/class/power_supply/battery/health" 
  5. #define BATTERY_PRESENT_PATH "/sys/class/power_supply/battery/present" 
  6. #define BATTERY_CAPACITY_PATH "/sys/class/power_supply/battery/capacity" 
  7. #define BATTERY_VOLTAGE_PATH "/sys/class/power_supply/battery/batt_vol" 
  8. #define BATTERY_TEMPERATURE_PATH "/sys/class/power_supply/battery/batt_temp" 
  9. #define BATTERY_TECHNOLOGY_PATH "/sys/class/power_supply/battery/technology" 

确定问题的产生为底层对USB状态的识别错误。

参考信息:

http://blog.csdn.net/liangshengyang/article/details/5821031#