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

时间: 2024-08-05 05:09:56

MSM8909+Android5.1.1之BSP开发---电池管理2---BatteryInfo.java的相关文章

MSM8909+Android5.1.1之BSP开发---开关机充电三色灯控制

图1 1.     充电三色灯控制 1.1   关机充电三色灯控制 相关文件:system\core\healthd\healthd_mode_charger.cpp 当前电量不等于之前电量时,调用handle_power_supply_state()--->set_battery_soc_leds()来控制三色灯,先来看其中用到的全局数组 #define RED_LED_PATH "/sys/class/leds/red/brightness" #define GREEN_LE

MSM8909+Android5.1.1 SPI驱动开发(PSAM部分)

MSM8909+Android5.1.1SPI驱动开发(PSAM部分) 1.     PSAM部分的硬件设计 图1 CS   片选信号 SCK  时钟信号 MISO 主设备的数据输入.从设备的数据输出脚 MOSI 主设备的数据输出.从设备的数据输入脚 2.     PSAM部分软件设计 图2 (1)  PSAM应用 这部分只需要调用API函数即可. (2)  PSAM API API的主要工作就是给M0上电.设置SPI读写模式.设置SPI读写的每字节的位数.SPI的工作频率等. (3)  SPI

现在可以把小程序交给第三方开发或管理了

刚刚,小程序又放出了一波新能力,第三方平台支持小程序.小程序新增数据分析接口和小程序代码包大小限制扩大为2M三项新能力上线. 一.第三方平台支持小程序 开发管理更省心现在,不用交出帐号密码,也能把小程序交给第三方开发或管理了.如果你是不懂开发或者没有精力开发和管理的企业,现在可以把小程序授权给第三方平台,他们可以帮你进行小程序的代码开发与管理.客服服务等.托管方式很简单:小程序管理员在支持小程序的第三方平台上,扫码同意即可授权.授权的具体能力:配置服务器地址,代码开发.上传提交与发布,模版消息与

《连载 | 物联网框架ServerSuperIO教程》1.4种通讯模式机制。附小文:招.NET开发,结果他转JAVA了,一切都是为了生活

参考文章: 1.SuperIO通讯框架介绍,含通信本质 一.感慨 上大学的时候,没有学过C#,花了5块钱在地坛书市买了一本教程,也就算是正式入行了.后来深造,学过JAVA,后来迫于生计,打算转JAVA了.后来考虑考虑,自己写的框架还是有很大发展余地,后来还是在C#的阵地上坚持了下来.从一开始的雏形,到SuperIO的产品化,再到服务器端的ServerSuperIO,也是慢慢演化而来.后期打算把ServerSuperIO移植到嵌入式设备上,以及完善开发文档.本来不想提这些,但是今天打算招一个C#开

atitit.软件开发GUI 布局管理优缺点总结java swing wpf web html c++ qt php asp.net winform

atitit.软件开发GUI 布局管理优缺点总结java swing wpf web html c++ qt php asp.net winform 1. Absoluti 布局(经常使用) 1 2. Flow 布局(不经常使用) 1 3. BorderLayout (不经常使用) 1 4. BoxLayout( html默认布局) 2 5. CardLayout (tab 布局) 2 6. GridLayout 3 7. GridBagLayout 3 8. Fixed 定位(不经常使用) 3

信息系统开发有管理

做了一套题,又总结了下<信息系统开发与管理>,感觉又有了新的认识.这本书应该说整体的设计都是很具有逻辑性的,内容设计的有些水到渠成.要说结构的话,应该算是总-分结构吧.一开始就以一篇概述全面的介绍了此书.我总结了下面的图. 信息.系统.开发与管理和我这幅图特别像.我感觉这本书主要围绕这四个方面来说.看完书我们知道其中大部分都是开发的讲述,总体规划-系统分析-系统设计-系统实施-运行管理,这是每个软件系统必不可少的步骤,开发出来了就少不了管理,二者总是相辅相成的,缺一不可. 具体的内容不多说了,

自考《信息系统开发与管理》之数据流图

自考中,数据流图是一个一大考点.小题和大题中都有出现.我们怎么样才能画好一个数据流图呢?在这里,我做了一下梳理. 首先,数据流图有四种基本符号组成,即数据流.加工(或称为处理).文件.数据源点或终点.坦白来说,这四种符号并没有一种公认图形形成,但是我们考试的时候必须按这个教材上的画法. 数据流.数据流用带有名字的箭头表示.但是对流进或流出文件的数据流不需标注名字,其他的数据流必须标出.数据流用名词或名词短语命名. 加工(或称处理).也叫数据处理.它用椭圆来表示.在分层中,必须写编号来标识它在层次

仿OpenStack开发云计算管理软件

仿OpenStack开发云计算管理软件 使用Python语言开发一套类似OpenStack的云计算管理平台LouCloud,具备基本的用户,服务器,镜像与 虚拟机管理功能,学习IaaS,虚拟化,Libvirt API,Flask Web开发等知识.课程随到随学,加入即可获得6周有问必答及1个月会员服务,完成所有实验并公开实验报告可获得课程证书. 课程购买有疑问? (0/6) 1 门课程,6 个实验 专属环境,无限延时 课程难题,有问必答 ¥199.00 (年会员8折¥159.2) 立即购买 课程

Android4.4电池管理

一.概述 Android4.4的电池管理功能用于管理电池的充.放电功能.整个电池管理的部分包括Linux电池驱动.Android电池服务.电池属性和参数.电池曲线优化四个部分. Linux电池驱动用于和PMIC交互.负责监听电池产生的相关事件,例如低电报警.电量发生变化.高温报警.USB插拔等等. Android电池服务,用来监听内核上报的电池事件,并将最新的电池数据上报给系统,系统收到新数据后会去更新电池显示状态.剩余电量等信息.如果收到过温报警和低电报警,系统会自动触发关机流程,保护电池和机