当前位置: 代码迷 >> Android >> MSM8909+Android5.1.1之BSP开发-电池治理2-BatteryInfo.java
  详细解决方案

MSM8909+Android5.1.1之BSP开发-电池治理2-BatteryInfo.java

热度:195   发布时间:2016-04-24 12:01:43.0
MSM8909+Android5.1.1之BSP开发---电池管理2---BatteryInfo.java

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

 

  相关解决方案