StickyBroadcast在获取电池状态中的妙用

StickyBroadcast在获取电池状态中的妙用

今天在做开发的时候,突然遇到这样的一个问题,当你的设备电量低于15%的时候这个时候设备的闪光灯是无法打开的,但是我们平台的解决方案对这一块没有做出任何的提示,于是直接导致了用户认为他的闪光灯坏掉了,于是老大要求我们解决这个问题。

我们都知道电池的电量信息获取我们是通过广播来实现的。

标准做法如下:

private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
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");  

String statusString = "";  

switch (status) {
case BatteryManager.BATTERY_STATUS_UNKNOWN:
statusString = "unknown";
break;
case BatteryManager.BATTERY_STATUS_CHARGING:
statusString = "charging";
break;
case BatteryManager.BATTERY_STATUS_DISCHARGING:
statusString = "discharging";
break;
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
statusString = "not charging";
break;
case BatteryManager.BATTERY_STATUS_FULL:
statusString = "full";
break;
}  

String healthString = "";  

switch (health) {
case BatteryManager.BATTERY_HEALTH_UNKNOWN:
healthString = "unknown";
break;
case BatteryManager.BATTERY_HEALTH_GOOD:
healthString = "good";
break;
case BatteryManager.BATTERY_HEALTH_OVERHEAT:
healthString = "overheat";
break;
case BatteryManager.BATTERY_HEALTH_DEAD:
healthString = "dead";
break;
case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
healthString = "voltage";
break;
case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
healthString = "unspecified failure";
break;
}  

String acString = "";  

switch (plugged) {
case BatteryManager.BATTERY_PLUGGED_AC:
acString = "plugged ac";
break;
case BatteryManager.BATTERY_PLUGGED_USB:
acString = "plugged usb";
break;
}  

}

获取的具体信息如下:

   “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等等。

更详细的我们不深究了,继续回归我们上面的问题

我最开始的想法是通过接受如下广播

    <action android:name="android.intent.action.ACTION_BATTERY_LOW"/>
     <action android:name="android.intent.action.ACTION_BATTERY_OKAY"/>

在SharedPreference 中保持一个状态值来监控,但后来发现根本没有这个必要

这里就要来说一说我们强大的StickyBroadcast

在Google的开发者文档中我们发现

public abstract void sendStickyBroadcast (Intent intent) 

Since: API Level 1
Perform a sendBroadcast(Intent) that is "sticky," meaning the Intent you are sending stays around after the broadcast is complete, so that others can quickly retrieve that data through the return value of registerReceiver(BroadcastReceiver, IntentFilter). In all other ways, this behaves the same as sendBroadcast(Intent).
You must hold the BROADCAST_STICKY  permission in order to use this API. If you do not hold that permission, SecurityException will be thrown.
Parameters intent    The Intent to broadcast;
 all receivers matching this Intent will receive the broadcast, and the Intent will be held to be re-broadcast to future receivers.

具体来说是什么意思呢,从字面上来看就是说

这个函数用一种 "sticky"的方式来发送Intent广播,而这样就意味着这个广播在他发出后就会一直滞留(等待),从而让其他所有的注册过本广播的注册者都能够快速的收到本广播。在其他的方式上,他和一般的广播就没有什么差别了。

同时,如果我们希望这样做的话,我们需要

    <uses-permission android:name="android.permission.BROADCAST_STICKY"/> 

这里,我们需要重点关注他关于参数intent的解释:

所有注册了改intent的注册者都将受到该广播。该intent将会保留到该广播被重新发送给它未来的注册者。

可能我解释的不是很清楚,但是有两点我们要说清楚:

一、所有的注册者随时随地都能收到。(随时 的意思是从他发出开始直到他的下次更新为止这段时间内所有注册该广播的都能收到)

二、这条广播会更新,而且一直会维持最新的广播发送给接受者。

好了,解释就到这里,接下来我们来说说他的强大之处

获取当前的电池状态

BatteryManager 会发送“sticky”类型的系统广播,在 Intent 中包括了当前的电池电量状态和充电状态等信息。

因为电池状态的广播类型是 “sticky”类型的,所以我们不需要注册相应的BroadcastReceiver。只需要在调用 registerReceiver 的时候传递空参数null就可以,然后函数的返回值 intent 中就包括了当前电池状态的各种信息。

当然您也可以传递一个自定义的 BroadcastReceiver ,不过实际上也是没有什么必要的。

示例代码:

IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);

从返回的 Intent 中我们可以获得当前的电池信息,获得方式见上:

例如:

int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);

float batteryPct = level / (float)scale;

这样我们就可以获取到电池的电量,从而来判断是否能够开启闪光灯

推荐阅读:

Android
电源管理专题之监测电池电量和充电状态Monitoring the Battery Level and Charging State

http://blog.csdn.net/g_rrrr/article/details/7999026

时间: 2024-10-04 14:08:09

StickyBroadcast在获取电池状态中的妙用的相关文章

android 获得电池状态

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientati

几个有趣的WEB设备API 前端提高B格必备(一)——电池状态&amp;震动api

受到同事启发,突然发现了几个有趣又实用的web api,没想到前端还有这么多有趣的东西可以玩~~简直过分. 1.电池状态API navigator.getBattery():这个api返回的是一个promise对象,会给出一个BatteryManager对象,对象中包含了:设备是否在充电,电量,以及还需充电时长和剩余时长等信息. chrome浏览器.安卓的webview.iphone都可以使用.ie,safari不管是pc还是移动端都不支持. 调用方法如下: navigator.getBatte

Android - 电池状态

为了解决电池图标的问题,顺带看了看电池信息的获取方法 :自己写了一个小栗子,来验证一下效果 电池的信息,一般都在BatteryManager里面,信息是用广播发出的.我们更新信息需要一个广播接收器 注册一个广播接收器,接收  Intent.ACTION_BATTERY_CHANGED ,从intent中读出想要的电池信息 比如 BatteryManager.EXTRA_STATUS     BatteryManager.BATTERY_STATUS_CHARGING  等等 在Android 5

Android 通过广播获取网络状态

Android系统网络连接状态的改变会发一个广播,注册一个广播接收者,实时动态的检测网络状态,及时提醒用户,优化用户体验. 本文仅提供WIFI 状态的检测作为参考,其他网络连接方式请对比WIFI连接作出调整. 首先写一个WifiStateBroadcast类继承BroadcastReceiver,重写onRecevie方法,获取网络连接状态管理器,通过管理器拿到对应的网络信息,得到网络状态,判断网络状态,作出相应的业务逻辑. 1 public class WifiStateBroadCast e

获取当前网络中的电脑数目及MAC-通过MAC查找IP-通过IP查询机器名

1 Microsoft Windows [版本 6.1.7601] 2 版权所有 (c) 2009 Microsoft Corporation.保留所有权利. 3 4 C:\Users\Administrator>netsh 5 netsh>wlan 6 netsh wlan>show hostednetwork 7 8 承载网络设置 9 ----------------------- 10 模式 : 已启用 11 SSID 名称 :“BCOJBConnect_PCWifi” 12 最多

16_Android生命周期再介绍,通过androidconfigChanges属性让界面旋转时不改变状态中保留的值

?? A  android:configChanges属性 对android:configChanges属性,一般认为有以下几点: 1 不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次. 2 设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横.竖屏时只会执行一次. 3.设置Activity的android:config

Android获取手机状态和监听手机来电状态

获取手机状态: import android.content.Context; import android.telephony.TelephonyManager; //获得相应的系统服务 TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); /** * 返回电话状态 * * CALL_STATE_IDLE 无任何状态时 * CALL_STATE_OFFHOOK 接起电话时 *

Android实现获取本机中所有图片

本示例演示如何在Android中使用加载器(Loader)来实现获取本机中的所有图片,并进行查看图片的效果. 在这个示例中,我使用android-support-v4.jar中的加载器(Loader)来实现获取本机中所有图片,关于这个包在以前的文章中也提到,是一个非常有用的包,关于这个包的详细信息请大家查看官方文档:http://developer.android.com/sdk/compatibility-library.html. 关于加载器(Loader)是在Android3.0中才开始引

Jenkins获取编译状态

背景:在通过python的API调用Jenkins,启动Jenkins的job任务时,是需要知道Jenkins的编译状态,获取编译状态为 status=server.get_build_info(jobname, get_number2)['result'] #jobname,为任务的job名称,get_number2为编译版本号 目前是以前项目中截取的代码,我连接Jenkins是用了两种方式,因为有一种方式不能进行编译job,另外一种获取其他数据有问题,也是一直存在的bug def conne