Android 电量监控

本身就是一个广播接收器(BroadcastReceiver),因此我们最初企图直接用这个Widget接受ACTION_BATTERY_CHANGED广播并作出反应,但却发现这个接收器并不会接受电池更新的广播(不论我们在配置文件中配置与否)。所以只能另寻出路,我们想到,可以使用一个单独的为本Widget服务的Service,该Service检测到电池电量更新后就更新桌面的Widget显示。

Broadcast Action: This is a sticky broadcast containing the charging state, level, and other information about the battery. See BatteryManager for documentation on the contents of the Intent.

You can not receive this through components declared in manifests, only by explicitly registering for it with Context.registerReceiver(). See ACTION_BATTERY_LOW, ACTION_BATTERY_OKAY, ACTION_POWER_CONNECTED, and ACTION_POWER_DISCONNECTED for distinct battery-related broadcasts that are sent and can be received through manifest receivers.

This is a protected intent that can only be sent by the system.

package com.billhoo.study;

import android.app.Notification;  //通知,即显示在屏幕左上角的小图标

import android.app.NotificationManager;

import android.app.PendingIntent;

import android.app.Service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.BatteryManager;

import android.os.IBinder;

public class MonitorService extends Service {

@Override

public IBinder onBind(Intent intent) {

return null;

}

@Override

public void onStart(Intent intent, int startId) {

// 定义电池电量更新广播的过滤器,只接受带有ACTION_BATTERRY_CHANGED事件的Intent

IntentFilter batteryChangedReceiverFilter = new IntentFilter();

batteryChangedReceiverFilter.addAction(Intent.ACTION_BATTERY_CHANGED);

// 向系统注册batteryChangedReceiver接收器,本接收器的实现见代码字段处

registerReceiver(batteryChangedReceiver, batteryChangedReceiverFilter);

// 实例化Notification通知的管理器,即字段notification manager

notifyManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

// 由于初始化本服务时系统可能没有发出ACTION_BATTERY_CHANGED广播,那么刚才注册的那个接收器将不会在本服务启动时被激活,这种情况下就无法显示当前电量,因此在这里添加一个匿名广播接收器。

new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

int level = intent.getIntExtra("level", 0);  //电池电量等级

int scale = intent.getIntExtra("scale", 100);  //电池满时百分比

int status = intent.getIntExtra("status", 0);  //电池状态

// 若正在充电

if (status == BatteryManager.BATTERY_STATUS_CHARGING)

notification = getNotification(getChargingIcon(level * 100 / scale),

"电池监控", System.currentTimeMillis(), "电池电量", "正在充电");

else

notification = getNotification(getStateIcon(level * 100 / scale),

"电池监控", System.currentTimeMillis(), "电池电量", "请及时充电");

//向系统发送此通知,为方便起见,通知ID简单设为0

notifyManager.notify(0, notification);

}

};

}

@Override

public void onDestroy() {

//当本服务终止时,通过通知ID注销左上角的通知

notifyManager.cancel(0);

}

// --------------------------------------私有方法------------------------------

// 获得一个notification

private Notification getNotification(int notificationIcon, String tickerText,

long when, String contentTitle, String contentText) {

// 定义该notification的扩展文本和intent

Notification notification = new Notification(notificationIcon, tickerText,

when);

Context context = getApplicationContext();

Intent notificationIntent = new Intent(context, BatteryInfo.class);

PendingIntent contentIntent = PendingIntent.getActivity(this, 0,

notificationIntent, 0);

notification.setLatestEventInfo(context, contentTitle, contentText,

contentIntent);

// 设置本状态出现在“正在进行”而非“通知”栏目,不允许用户清除状态图标

notification.flags |= Notification.FLAG_ONGOING_EVENT;

return notification;

}

// 获得对应的电池状态图标

private int getStateIcon(int batteryHealth) {

if (batteryHealth >= 0 || batteryHealth <= 100)

return batteryStateIcons[batteryHealth]; //这里是为了方便起见而硬编码的资源数组,直接从R.java文件中提取的十六进制资源ID

return R.drawable.stat_sys_battery_unknown;

}

// 获得对应的充电状态图标

private int getChargingIcon(int batteryHealth) {

if (batteryHealth >= 0 && batteryHealth < 5)

return R.drawable.stat_sys_battery_charge_anim0;

if (batteryHealth >= 5 && batteryHealth < 10)

return R.drawable.stat_sys_battery_charge_anim01;

if (batteryHealth >= 10 && batteryHealth < 15)

return R.drawable.stat_sys_battery_charge_anim02;

if (batteryHealth >= 15 && batteryHealth < 20)

return R.drawable.stat_sys_battery_charge_anim03;

if (batteryHealth >= 20 && batteryHealth < 25)

return R.drawable.stat_sys_battery_charge_anim04;

if (batteryHealth >= 25 && batteryHealth < 30)

return R.drawable.stat_sys_battery_charge_anim05;

if (batteryHealth >= 30 && batteryHealth < 35)

return R.drawable.stat_sys_battery_charge_anim06;

if (batteryHealth >= 35 && batteryHealth < 40)

return R.drawable.stat_sys_battery_charge_anim07;

if (batteryHealth >= 40 && batteryHealth < 45)

return R.drawable.stat_sys_battery_charge_anim08;

if (batteryHealth >= 45 && batteryHealth < 50)

return R.drawable.stat_sys_battery_charge_anim09;

if (batteryHealth >= 50 && batteryHealth < 55)

return R.drawable.stat_sys_battery_charge_anim10;

if (batteryHealth >= 55 && batteryHealth < 60)

return R.drawable.stat_sys_battery_charge_anim11;

if (batteryHealth >= 60 && batteryHealth < 65)

return R.drawable.stat_sys_battery_charge_anim12;

if (batteryHealth >= 65 && batteryHealth < 70)

return R.drawable.stat_sys_battery_charge_anim13;

if (batteryHealth >= 70 && batteryHealth < 75)

return R.drawable.stat_sys_battery_charge_anim14;

if (batteryHealth >= 75 && batteryHealth < 80)

return R.drawable.stat_sys_battery_charge_anim15;

if (batteryHealth >= 80 && batteryHealth < 85)

return R.drawable.stat_sys_battery_charge_anim16;

if (batteryHealth >= 85 && batteryHealth < 90)

return R.drawable.stat_sys_battery_charge_anim17;

if (batteryHealth >= 90 && batteryHealth < 95)

return R.drawable.stat_sys_battery_charge_anim18;

if (batteryHealth >= 95 && batteryHealth < 100)

return R.drawable.stat_sys_battery_charge_anim19;

if (batteryHealth == 100)

return R.drawable.stat_sys_battery_charge_animfull;

return R.drawable.stat_sys_battery_unknown;

}

// -------------------------------私有字段--------------------------------------

private NotificationManager notifyManager = null;

private Notification notification = null;

//这里是为了方便起见而硬编码的icon资源数组,直接从R.java文件中提取的十六进制资源ID,本数组的0号元素0x7f020002表示资源stat_sys_battery_0.png(见附件),以后累加。不同配置的ID可能不同,请读者自行修改。

private int batteryStateIcons[] = { 0x7f020002, 0x7f020003, 0x7f020004,

0x7f020005, 0x7f020006, 0x7f020007, 0x7f020008, 0x7f020009, 0x7f02000a,

0x7f02000b, 0x7f02000c, 0x7f02000d, 0x7f02000e, 0x7f02000f, 0x7f020010,

0x7f020011, 0x7f020012, 0x7f020013, 0x7f020014, 0x7f020015, 0x7f020016,

0x7f020017, 0x7f020018, 0x7f020019, 0x7f02001a, 0x7f02001b, 0x7f02001c,

0x7f02001d, 0x7f02001e, 0x7f02001f, 0x7f020020, 0x7f020021, 0x7f020022,

0x7f020023, 0x7f020024, 0x7f020025, 0x7f020026, 0x7f020027, 0x7f020028,

0x7f020029, 0x7f02002a, 0x7f02002b, 0x7f02002c, 0x7f02002d, 0x7f02002e,

0x7f02002f, 0x7f020030, 0x7f020031, 0x7f020032, 0x7f020033, 0x7f020034,

0x7f020035, 0x7f020036, 0x7f020037, 0x7f020038, 0x7f020039, 0x7f02003a,

0x7f02003b, 0x7f02003c, 0x7f02003d, 0x7f02003e, 0x7f02003f, 0x7f020040,

0x7f020041, 0x7f020042, 0x7f020043, 0x7f020044, 0x7f020045, 0x7f020046,

0x7f020047, 0x7f020048, 0x7f020049, 0x7f02004a, 0x7f02004b, 0x7f02004c,

0x7f02004d, 0x7f02004e, 0x7f02004f, 0x7f020050, 0x7f020051, 0x7f020052,

0x7f020053, 0x7f020054, 0x7f020055, 0x7f020056, 0x7f020057, 0x7f020058,

0x7f020059, 0x7f02005a, 0x7f02005b, 0x7f02005c, 0x7f02005d, 0x7f02005e,

0x7f02005f, 0x7f020060, 0x7f020061, 0x7f020062, 0x7f020063, 0x7f020064,

0x7f020065, 0x7f02007b };

// 接受电池信息更新的广播

private BroadcastReceiver batteryChangedReceiver = new BroadcastReceiver() {

public void onReceive(Context context, Intent intent) {

int level = intent.getIntExtra("level", 0);

int scale = intent.getIntExtra("scale", 100);

int status = intent.getIntExtra("status", 0);

// 若正在充电

if (status == BatteryManager.BATTERY_STATUS_CHARGING)

notification = getNotification(getChargingIcon(level * 100 / scale),

"Battery Monitor", System.currentTimeMillis(), "电池电量", "正在充电");

else

notification = getNotification(getStateIcon(level * 100 / scale),

"Battery Monitor", System.currentTimeMillis(), "电池电量", "请及时充电");

notifyManager.notify(0, notification);

}

};

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,123评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,031评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,723评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,357评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,412评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,760评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,904评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,672评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,118评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,456评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,599评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,264评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,857评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,731评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,956评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,286评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,465评论 2 348

推荐阅读更多精彩内容