Android的电源管理

电池的信息,电压,温度,充电状态等等,都是由BatteryService来提供的。BatteryService是跑在system_process当中,在系统初始化的时候启动,如下

在BatteryService.java中:
Log.i(TAG, "Starting Battery Service.");BatteryService battery = new BatteryService(context);ServiceManager.addService("battery", battery);



数据来源
电池电量的读取首先需要Kernel的支持,kernel将所得到的电池信息放到/sys/class/power_supply/Battery 中,由frameworks/base/services/jni文件夹下的 com_android_server_BatteryService.cpp进行读取。
总路径的定义:
#define POWER_SUPPLY_PATH “/sys/class/power_supply”
在int register_android_server_BatteryService(JNIEnv* env)中对每个特定路径赋值
如给定batteryCapacityPath的路径:

snprintf(path, sizeof(path), "%s/%s/capacity", POWER_SUPPLY_PATH, name);                if (access(path, R_OK) == 0)                    gPaths.batteryCapacityPath = strdup(path);


最后在static void android_server_BatteryService_update(JNIEnv* env, jobject obj)中读取路径文件中的信息

setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);


BatteryService通过JNI(com_android_server_BatteryService.cpp)读取数据。 BatteryService通过JNI注册的不仅有函数,还有变量。 如下:
private boolean mAcOnline;    private boolean mUsbOnline;    private int mBatteryStatus;    private int mBatteryHealth;    private boolean mBatteryPresent;    private int mBatteryLevel;    private int mBatteryVoltage;    private int mBatteryTemperature;    private String mBatteryTechnology;


在BatteryService.java中声明的变量,在com_android_server_BatteryService.cpp中共用,即在 com_android_server_BatteryService.cpp中其实操作的也是BatteryService.java中声明的变量
gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");    gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z");    gFieldIds.mBatteryStatus = env->GetFieldID(clazz, "mBatteryStatus", "I");    gFieldIds.mBatteryHealth = env->GetFieldID(clazz, "mBatteryHealth", "I");    gFieldIds.mBatteryPresent = env->GetFieldID(clazz, "mBatteryPresent", "Z");    gFieldIds.mBatteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");    gFieldIds.mBatteryTechnology = env->GetFieldID(clazz, "mBatteryTechnology", "Ljava/lang/String;");    gFieldIds.mBatteryVoltage = env->GetFieldID(clazz, "mBatteryVoltage", "I");    gFieldIds.mBatteryTemperature = env->GetFieldID(clazz, "mBatteryTemperature", "I");


上面这些变量的值,对应是从下面的文件中读取的,一只文件存储一个数值。

#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"


Android是运行在Linux内核上面的,/sys/class/power_supply亦是Linux内核下面的目录。至于这些文件时怎么生成的,则是由Platform来控制的。

2. 数据传送
电池的这些信息是通过何种方式,被其他应用所获得的。可以想到的有两种方式,第一种,应用主动从BatteryService获得数据;第二种,BatteryService主动把数据传送给所关心的应用程序。
BatteryService采用的是第二种方式,所有的电池的信息数据是通过Intent传送出去的。在BatteryService.java 中,Code如下:

Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);       intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);         intent.putExtra("status", mBatteryStatus);        intent.putExtra("health", mBatteryHealth);        intent.putExtra("present", mBatteryPresent);        intent.putExtra("level", mBatteryLevel);        intent.putExtra("scale", BATTERY_SCALE);        intent.putExtra("icon-small", icon);        intent.putExtra("plugged", mPlugType);        intent.putExtra("voltage", mBatteryVoltage);        intent.putExtra("temperature", mBatteryTemperature);        intent.putExtra("technology", mBatteryTechnology);        ActivityManagerNative.broadcastStickyIntent(intent, null);


post by 雨天等晴 / 2010-12-1 17:01 Wednesday

android的电源管理 [Android]

电池的信息,电压,温度,充电状态等等,都是由BatteryService来提供的。BatteryService是跑在system_process当中,在系统初始化的时候启动,如下

在BatteryService.java中:
Log.i(TAG, “Starting Battery Service.”);
BatteryService battery = new BatteryService(context);
ServiceManager.addService(“battery”, battery);

1. 数据来源
电池电量的读取首先需要Kernel的支持,kernel将所得到的电池信息放到/sys/class/power_supply/Battery 中,由frameworks/base/services/jni文件夹下的 com_android_server_BatteryService.cpp进行读取。
总路径的定义:
#define POWER_SUPPLY_PATH “/sys/class/power_supply”
在int register_android_server_BatteryService(JNIEnv* env)中对每个特定路径赋值
如给定batteryCapacityPath的路径:

snprintf(path, sizeof(path), “%s/%s/capacity”, POWER_SUPPLY_PATH, name);
if (access(path, R_OK) == 0)
gPaths.batteryCapacityPath = strdup(path);

最后在static void android_server_BatteryService_update(JNIEnv* env, jobject obj)中读取路径文件中的信息
setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);

BatteryService通过JNI(com_android_server_BatteryService.cpp)读取数据。 BatteryService通过JNI注册的不仅有函数,还有变量。 如下:

private boolean mAcOnline;
private boolean mUsbOnline;
private int mBatteryStatus;
private int mBatteryHealth;
private boolean mBatteryPresent;
private int mBatteryLevel;
private int mBatteryVoltage;
private int mBatteryTemperature;
private String mBatteryTechnology;

在BatteryService.java中声明的变量,在com_android_server_BatteryService.cpp中共用,即在 com_android_server_BatteryService.cpp中其实操作的也是BatteryService.java中声明的变量

gFieldIds.mAcOnline = env->GetFieldID(clazz, “mAcOnline”, “Z”);
gFieldIds.mUsbOnline = env->GetFieldID(clazz, “mUsbOnline”, “Z”);
gFieldIds.mBatteryStatus = env->GetFieldID(clazz, “mBatteryStatus”, “I”);
gFieldIds.mBatteryHealth = env->GetFieldID(clazz, “mBatteryHealth”, “I”);
gFieldIds.mBatteryPresent = env->GetFieldID(clazz, “mBatteryPresent”, “Z”);
gFieldIds.mBatteryLevel = env->GetFieldID(clazz, “mBatteryLevel”, “I”);
gFieldIds.mBatteryTechnology = env->GetFieldID(clazz, “mBatteryTechnology”, “Ljava/lang/String;”);
gFieldIds.mBatteryVoltage = env->GetFieldID(clazz, “mBatteryVoltage”, “I”);
gFieldIds.mBatteryTemperature = env->GetFieldID(clazz, “mBatteryTemperature”, “I”);

上面这些变量的值,对应是从下面的文件中读取的,一只文件存储一个数值。

#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”

Android是运行在Linux内核上面的,/sys/class/power_supply亦是Linux内核下面的目录。至于这些文件时怎么生成的,则是由Platform来控制的。

2. 数据传送
电池的这些信息是通过何种方式,被其他应用所获得的。可以想到的有两种方式,第一种,应用主动从BatteryService获得数据;第二种,BatteryService主动把数据传送给所关心的应用程序。
BatteryService采用的是第二种方式,所有的电池的信息数据是通过Intent传送出去的。在BatteryService.java 中,Code如下:

Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);

intent.putExtra(“status”, mBatteryStatus);
intent.putExtra(“health”, mBatteryHealth);
intent.putExtra(“present”, mBatteryPresent);
intent.putExtra(“level”, mBatteryLevel);
intent.putExtra(“scale”, BATTERY_SCALE);
intent.putExtra(“icon-small”, icon);
intent.putExtra(“plugged”, mPlugType);
intent.putExtra(“voltage”, mBatteryVoltage);
intent.putExtra(“temperature”, mBatteryTemperature);
intent.putExtra(“technology”, mBatteryTechnology);

ActivityManagerNative.broadcastStickyIntent(intent, null);

3. 数据接收
应用如果想要接收到BatteryService发送出来的电池信息,则需要注册一个Intent为 Intent.ACTION_BATTERY_CHANGED的BroadcastReceiver。
注册方法如下:

IntentFilter mIntentFilter = new IntentFilter();              mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);              registerReceiver(mIntentReceiver, mIntentFilter);       private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {             @Override             public void onReceive(Context context, Intent intent) {                   // TODO Auto-generated method stub                     String action = intent.getAction();                     if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {                            int nVoltage = intent.getIntExtra("voltage", 0);                           if(nVoltage!=0){                                         mVoltage.setText("V: " + nVoltage + "mV - Success...");                          }                            else{                                   mVoltage.setText("V: " + nVoltage + "mV - fail...");                            }                   }                }        };


4. 数据更新
电池的信息会随着时间不停变化,自然地,就需要考虑如何实时的更新电池的数据信息。在BatteryService启动的时候,会同时通过 UEventObserver启动一个onUEvent Thread。
每一个Process最多只能有一个onUEvent Thread,即使这个Process中有多个UEventObserver的实例。当在一个Process中,第一次Call startObserving()方法后,这个UEvent thread就启动了。
而一旦这个UEvent thread启动之后,就不会停止。
在BatteryService.java中

mUEventObserver.startObserving("SUBSYSTEM=power_supply");      private UEventObserver mUEventObserver = new UEventObserver() {        @Override        public void onUEvent(UEventObserver.UEvent event) {            update();        }     };


在UEvent thread中会不停调用 update()方法,来更新电池的信息数据。



更多相关文章

  1. webKit For Android
  2. 利用drozer进行Android渗透测试 - AndroSecurity
  3. Android的数据存储方式
  4. android如何查看app数据(无root权限)
  5. Android(安卓)Handler
  6. android sharedpreferences工具类
  7. Android(安卓)中数据库查询方法 query() 中的 selectionArgs 的
  8. Android(安卓)使用 MPAndroidChart 实现折线图
  9. mybatisplus的坑 insert标签insert into select无参数问题的解决

随机推荐

  1. opencv for android 教程
  2. Android数据加密之Base64编码算法
  3. Android GWES分析
  4. Fix one bug in Android 官方提供的例子
  5. 【Android】windows系统上安装与使用Andr
  6. Android手机定位应用小解
  7. Delphi XE8 iOS与Android移动应用开发(AP
  8. Android中的popupwindow从底部进入和退出
  9. Android之ActivityGroup实现Tab功能 (转)
  10. 应用程序基础知识:activity和intent——An