在BroadcastReceiver的onReceive()事件,接收到的Intent.ACTION_BATTERY_CHANGED,包括下面的信息。
“status”(int类型)…状态,定义值是BatteryManager.BATTERY_STATUS_XXX。
“health”(int类型)…健康,定义值是BatteryManager.BATTERY_HEALTH_XXX。
“present”(boolean类型)
“level”(int类型)…电池剩余容量
“scale”(int类型)…电池最大值。通常为100。
“icon-small”(int类型)…图标ID。
“plugged”(int类型)…连接的电源插座,定义值是BatteryManager.BATTERY_PLUGGED_XXX。
“voltage”(int类型)…mV。
“temperature”(int类型)…温度,0.1度单位。例如 表示197的时候,意思为19.7度。
“technology”(String类型)…电池类型,例如,Li-ion等等。
int status = intent.getIntExtra("status", 0);
int health = intent.getIntExtra("health", 0);
boolean present = intent.getBooleanExtra("present", false);
int level = intent.getIntExtra("level", 0);
int scale = intent.getIntExtra("scale", 0);
int icon_small = intent.getIntExtra("icon-small", 0);
int plugged = intent.getIntExtra("plugged", 0);
int voltage = intent.getIntExtra("voltage", 0);
int temperature = intent.getIntExtra("temperature", 0);
String technology = intent.getStringExtra("technology");
应用程序为了取得电池的状态,通常的做法是监听ACTION_BATTERY_CHANGED这个intent,只能在收到这个intent的时候才能取得电池的状态信息,有没有同步取得电池信息的办法呢?
实际上,系统driver维护着保存电池信息的一组文件。
/sys/class/power_supply/ac/online AC电源连接状态
/sys/class/power_supply/usb/online USB电源连接状态
/sys/class/power_supply/battery/status 充电状态
/sys/class/power_supply/battery/health 电池状态
/sys/class/power_supply/battery/present 使用状态
/sys/class/power_supply/battery/capacity 电池level
/sys/class/power_supply/battery/batt_vol 电池电压
/sys/class/power_supply/battery/batt_temp 电池温度
/sys/class/power_supply/battery/technology 电池技术
当电池状态发生变化时,driver会更新这些文件,因此在应用程序中通过读取这些文件的办法,可以做到同步取得电池信息。经过验证可行。
看看batteryservice的代码,也是通过读取这些文件内容到内存中,然后对系统上层提供电池信息,当信息发生变化的时候,向系统中广播ACTION_BATTERY_CHANGED这个intent。但是因为一般应用程序无法取得batteryservice的实例,因此无法直接使用batteryservice的方法。
http://www.eoeandroid.com/thread-2148-1-1.html
Android之手机电池电量应用
原理概述:
手机电池电量的获取在应用程序的开发中也很常用,Android系统中手机电池电量发生变化的消息是通过Intent广播来实现的,常用的Intent的Action有 Intent.ACTION_BATTERY_CHANGED(电池电量发生改变时)、Intent.ACTION_BATTERY_LOW(电池电量达到下限时)、和Intent.ACTION_BATTERY_OKAY(电池电量从低恢复到高时)。
当需要在程序中获取电池电量的信息时,需要为应用程序注册BroadcastReceiver组件,当特定的Action事件发生时,系统将会发出相应的广播,应用程序就可以通过BroadcastReceiver来接受广播,并进行相应的处理。
main.xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ToggleButton android:id="@+id/tb"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textOn="停止获取电量信息"
android:textOff="获取电量信息" />
<TextView android:id="@+id/tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
BatteryActivity类
package com.ljq.activity;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.TextView;
import android.widget.ToggleButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
public class BatteryActivity extends Activity {
private ToggleButton tb=null;
private TextView tv=null;
private BatteryReceiver receiver=null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
receiver=new BatteryReceiver();
tv=(TextView)findViewById(R.id.tv);
tb=(ToggleButton)findViewById(R.id.tb);
tb.setOnCheckedChangeListener(new OnCheckedChangeListener(){
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
//获取电池电量
if(isChecked){
IntentFilter filter=new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(receiver, filter);//注册BroadcastReceiver
}else {
//停止获取电池电量
unregisterReceiver(receiver);
tv.setText(null);
}
}
});
}
private class BatteryReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
int current=intent.getExtras().getInt("level");//获得当前电量
int total=intent.getExtras().getInt("scale");//获得总电量
int percent=current*100/total;
tv.setText("现在的电量是"+percent+"%。");
}
}
}
下这之前先说点显示电量的基本知识:
1、Android的上层实现显示手机电池电量是通过监听实现,当电池电量改变时会通知到程序。
当然这个有朋友就要问了我不是想监听电池电量,我是想直接获取当前的电池电量。
其实这是同一个问题,当你在初始化监听器的时候他会自动首先获取电池的电量信息,然后后续当电池改变时同时也会通知当前电池电量的改变情况。
代码:
view plain
package com.jli.battery;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.widget.ImageView;
public class Main extends Activity {
private ImageView tvBatteryChanged;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tvBatteryChanged = (ImageView)findViewById(R.id.test);
//注册一个接受广播类型
registerReceiver(new BatteryBroadcastReceiver(), new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
/**接受电量改变广播*/
class BatteryBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)){
int level = intent.getIntExtra("level", 0);
int scale = intent.getIntExtra("scale", 100);
int curPower = (level * 100 / scale)/25;
switch (curPower) {
case 0:
tvBatteryChanged.setImageBitmap(BitmapFactory.decodeResource(Main.this.getResources(), R.drawable.power0));
break;
case 1:
tvBatteryChanged.setImageBitmap(BitmapFactory.decodeResource(Main.this.getResources(), R.drawable.power1));
break;
case 2:
tvBatteryChanged.setImageBitmap(BitmapFactory.decodeResource(Main.this.getResources(), R.drawable.power2));
break;
case 3:
tvBatteryChanged.setImageBitmap(BitmapFactory.decodeResource(Main.this.getResources(), R.drawable.power3));
break;
case 4:
tvBatteryChanged.setImageBitmap(BitmapFactory.decodeResource(Main.this.getResources(), R.drawable.power4));
break;
}
}
}
}
}
Xml:
view plain
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jli.battery"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Main"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".Main$BatteryUpDateService"/>
</application>
<uses-permission android:name="android.permission.BATTERY_STATS" />
<uses-sdk android:minSdkVersion="8" />
</manifest>
上面只是实现显示电源的电量的简单例子,源码放于末尾。
这里补充如果还涉及到充电放电等状态处理的一些源码资料请不要粘贴复制,下面代码是不能运行的,自己看懂了后在例子里添加。
view plain
private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() {
int intLevel = 0;
int intScale = 0;
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
/*
* 如果捕捉到的action是ACTION_BATTERY_CHANGED, 就运行onBatteryInfoReceiver()
*/
if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
intLevel = intent.getIntExtra("level", 0);
intScale = intent.getIntExtra("scale", 100);
// 电池伏数
Log.d("Battery V", "" + intent.getIntExtra("voltage", 0));
// 电池温度
Log.d("Battery T", "" + intent.getIntExtra("temperature", 0));
BatteryV = "当前电压为:" + intent.getIntExtra("voltage", 0);
BatteryT = "当前温度为:" + intent.getIntExtra("temperature", 0);
switch (intent.getIntExtra("status",
BatteryManager.BATTERY_STATUS_UNKNOWN)) {
case BatteryManager.BATTERY_STATUS_CHARGING:
BatteryStatus = "充电状态";
break;
case BatteryManager.BATTERY_STATUS_DISCHARGING:
BatteryStatus = "放电状态";
break;
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
BatteryStatus = "未充电";
break;
case BatteryManager.BATTERY_STATUS_FULL:
BatteryStatus = "充满电";
break;
case BatteryManager.BATTERY_STATUS_UNKNOWN:
BatteryStatus = "未知道状态";
break;
}
switch (intent.getIntExtra("plugged",
BatteryManager.BATTERY_PLUGGED_AC)) {
case BatteryManager.BATTERY_PLUGGED_AC:
BatteryStatus2 = "AC充电";
break;
case BatteryManager.BATTERY_PLUGGED_USB:
BatteryStatus2 = "USB充电";
break;
}
switch (intent.getIntExtra("health",
BatteryManager.BATTERY_HEALTH_UNKNOWN)) {
case BatteryManager.BATTERY_HEALTH_UNKNOWN:
BatteryTemp = "未知错误";
break;
case BatteryManager.BATTERY_HEALTH_GOOD:
BatteryTemp = "状态良好";
break;
case BatteryManager.BATTERY_HEALTH_DEAD:
BatteryTemp = "电池没有电";
break;
case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
BatteryTemp = "电池电压过高";
break;
case BatteryManager.BATTERY_HEALTH_OVERHEAT:
BatteryTemp = "电池过热";
break;
}
}
}
};
Android Widget开发实例-电量监控
作者: Android开发网原创 时间: 2009-07-04
一个简单的电量监控代码可以很好的演示Android平台下Widget开发中的基础方式,比如appWidget如何于Service交互以及RemoteViews的演示。完成的工程代码我们稍作美化后提供下载,同时下次开始我们提供一些国外比较优秀的开源工程实例做剖析,从2007年11月至今SDK发布已经近两年了,相信大家可以看到整个Google Android平台的开发还是十分简单的,难度等级和J2ME相似,相信入门的网友只要经常光顾Android123开发站点一定会很好掌握的。
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.widget.RemoteViews;
public class BatteryMonitorWidget extends AppWidgetProvider
{
public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds )
{
context.startService(new Intent(context, BatteryMonitorReceiver.class));
}
public static class BatteryMonitorReceiver extends Service
{
private int currentBatteryLevel = 0;
private BroadcastReceiver batteryReceiver = new BroadcastReceiver()
{
@Override
public void onReceive( Context context, Intent intent )
{
currentBatteryLevel = intent.getIntExtra( "level", 0 );
}
};
@Override
public void onStart( Intent intent, int startId )
{
registerReceiver( batteryReceiver, new IntentFilter( Intent.ACTION_BATTERY_CHANGED ) ); //注册一个动作改变事件捕获,这里为电量改变时即ACTION_BATTERY_CHANGED
RemoteViews views = new RemoteViews( getPackageName(), R.layout.main ); //从layout下main.xml中构造widgets
//这里我们应该判断currentBatteryLevel的数值来显示图片电量等级,比如battery_level_1或battery_level_5等等,下面是n
views.setImageViewResource( R.id.ImageView01, R.drawable.battery_level_n );
views.setTextViewText( R.id.myText, currentBatteryLevel + "%" ); //从BroadcastReceiver读取当前的电量等级
ComponentName thisWidget = new ComponentName( this, BatteryMonitorWidget.class );
AppWidgetManager manager = AppWidgetManager.getInstance( this );
manager.updateAppWidget( thisWidget, updateViews ); //开始执行了
}
@Override
public IBinder onBind( Intent intent )
{
return null;
}
}
}