android 低电量卡,[转载]Android 中低电量的处理方法

news/2024/12/22 13:37:40/

261

262

15

下面代码是具体发送

315

if (sendBatteryLow) {

316

mSentLowBatteryBroadcast= true;

317

statusIntent.setAction(Intent.ACTION_BATTERY_LOW);

318

mContext.sendBroadcast(statusIntent);

319

} else if (mSentLowBatteryBroadcast&& mLastBatteryLevel >= mLowBatteryCloseWarningLevel) {

320

mSentLowBatteryBroadcast= false;

321

statusIntent.setAction(Intent.ACTION_BATTERY_OKAY);

322

mContext.sendBroadcast(statusIntent);

其中if分支是发送Intent.ACTION_BATTERY_LOW,else分析负责发送Intent.ACTION_BATTERY_OKAY);

if 分支只要满足上面两个条件就回发送,而else什么时候发送呢?

根据代码可以这么理解:当发送Intent.ACTION_BATTERY_LOW时,会把mSentLowBatteryBroadcast置为true,

同时mBatteryLevel 会小于15;由于电池更新较快,也就是此update函数较频繁,可以推断mLastBatteryLevel 将会略大约else分支用到mBatteryLevel 的值(可能为16),是否会满足else分支的mLastBatteryLevel >= mLowBatteryCloseWarningLevel条件呢?

此时就需要我们来查看mLowBatteryCloseWarningLevel的值具体是多少,定义方式与mLowBatteryWarningLevel类似,如下

129

mLowBatteryCloseWarningLevel = mContext.getResources().getInteger(

130

com.android.internal.R.integer.config_lowBatteryCloseWarningLevel);

也是通过config.xml读取到的

文件位于frameworks/base/core/res/res/values/config.xml

264

265

20

按照如上分析,貌似else分析永远都不会执行,也就是Intent.ACTION_BATTERY_OKAY不会发出

但其实有一种情况会执行的,当电池电量小于mLowBatteryWarningLevel,并且已经成功发送了Intent.ACTION_BATTERY_LOW信息,此时用户插上USB或充电器充电,当电池电量达到mLowBatteryCloseWarningLevel,此时才会发送Intent.ACTION_BATTERY_OKAY信息

2、接收:Intent.ACTION_BATTERY_LOW &&

Intent.ACTION_BATTERY_OKAY)

1)StatusBarPolicy.java

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java

这个类在2.3之前的版本中放在frameworks/base/services/java/com/android/server/status/目录下,现在做了代码归整

首先需要注册

671

IntentFilter filter = new IntentFilter();

673

// Register for Intent broadcasts for...

674

filter.addAction(Intent.ACTION_BATTERY_CHANGED);

675

filter.addAction(Intent.ACTION_BATTERY_LOW);

676

filter.addAction(Intent.ACTION_BATTERY_OKAY);

700

mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);

接收部分

529

public void onReceive(Context context, Intent intent) {

530

String action = intent.getAction();

531

if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {

532

updateBattery(intent);

534

else if (action.equals(Intent.ACTION_ALARM_CHANGED)) {

535

updateAlarm(intent);

537

else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) {

538

updateSyncState(intent);

540

else if (action.equals(Intent.ACTION_BATTERY_LOW)) {

541

onBatteryLow(intent);

543

else if (action.equals(Intent.ACTION_BATTERY_OKAY)

544

|| action.equals(Intent.ACTION_POWER_CONNECTED)) {

545

onBatteryOkay(intent);

当收到Intent.ACTION_BATTERY_LOW时,做如下处理

759

private void onBatteryLow(Intent intent) {

760

if (SHOW_LOW_BATTERY_WARNING) {

761

if (false) {

762

Slog.d(TAG, "mPhoneState=" + mPhoneState

763

+ " mLowBatteryDialog=" + mLowBatteryDialog

764

+ " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);

767

if (SHOW_BATTERY_WARNINGS_IN_CALL || mPhoneState == TelephonyManager.CALL_STATE_IDLE) {

768

showLowBatteryWarning();

769

} else {

770

mBatteryShowLowOnEndCall= true;

其中SHOW_LOW_BATTERY_WARNING和SHOW_BATTERY_WARNINGS_IN_CALL 定义为常量 115

private static final boolean SHOW_LOW_BATTERY_WARNING = true;

116

private static final boolean SHOW_BATTERY_WARNINGS_IN_CALL = true;

1.1)

可以看到当此时电话状态为TelephonyManager.CALL_STATE_IDLE状态时,做如下处理,否则标记mBatteryShowLowOnEndCall为true

794

private void showLowBatteryWarning() {

795

closeLastBatteryView();

797

// Show exact battery level.

798

CharSequence levelText = mContext.getString(

799

R.string.battery_low_percent_format, mBatteryLevel);

801

if (mBatteryLevelTextView != null) {

802

mBatteryLevelTextView.setText(levelText);

803

} else {

804

View v = View.inflate(mContext, R.layout.battery_low, null);

805

mBatteryLevelTextView=(TextView)v.findViewById(R.id.level_percent);

807

mBatteryLevelTextView.setText(levelText);

809

AlertDialog.Builder b = new AlertDialog.Builder(mContext);

810

b.setCancelable(true);

811

b.setTitle(R.string.battery_low_title);

812

b.setView(v);

813

b.setIcon(android.R.drawable.ic_dialog_alert);

814

b.setPositiveButton(android.R.string.ok, null);

816

final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);

817

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK

818

| Intent.FLAG_ACTIVITY_MULTIPLE_TASK

819

| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

820

| Intent.FLAG_ACTIVITY_NO_HISTORY);

821

if (intent.resolveActivity(mContext.getPackageManager()) != null) {

822

b.setNegativeButton(R.string.battery_low_why,

823

new DialogInterface.OnClickListener() {

824

public void onClick(DialogInterface dialog, int which) {

825

mContext.startActivity(intent);

826

if (mLowBatteryDialog != null) {

827

mLowBatteryDialog.dismiss();

830

});

833

AlertDialog d = b.create();

834

d.setOnDismissListener(mLowBatteryListener);

835

d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

836

d.show();

837

mLowBatteryDialog = d;

840

final ContentResolver cr = mContext.getContentResolver();

841

if (Settings.System.getInt(cr,

842

Settings.System.POWER_SOUNDS_ENABLED, 1) == 1)

844

final String soundPath = Settings.System.getString(cr,

845

Settings.System.LOW_BATTERY_SOUND);

846

if (soundPath != null) {

847

final Uri soundUri = Uri.parse("file://" + soundPath);

848

if (soundUri != null) {

849

final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);

850

if (sfx != null) {

851

sfx.setStreamType(AudioManager.STREAM_SYSTEM);

852

sfx.play();

此函数主要分两部分,第一部分是根据mBatteryLevelTextView是否为null,有选择的创建并显示mLowBatteryDialog,为什么不始终创建呢?

这时候需要看一下mLowBatteryListener

881

private DialogInterface.OnDismissListener mLowBatteryListener

882

= new DialogInterface.OnDismissListener() {

883

public void onDismiss(DialogInterface dialog) {

884

mLowBatteryDialog = null;

885

mBatteryLevelTextView = null;

可以看出,如果mLowBatteryDialog已经被Dismiss掉,则选择创建mLowBatteryDialog,如果没有Dismiss,为了节省资源,只需要更新mLowBatteryDialog中的界面就可以了。

第二部分则是低电提示音,在网上看帖子,这个功能令很多人恼火啊,特别是学生深受其害,那么是否让用户有选择的打开此功能呢?

实现这部分功能需要两步

POWER_SOUNDS_ENABLED

841

if (Settings.System.getInt(cr,

842

Settings.System.POWER_SOUNDS_ENABLED, 1) == 1)

我们知道Settings.System.POWER_SOUNDS_ENABLED是一个系统属性,通过在源码中并没有查找到有用此属性的地方

Settings.System.LOW_BATTERY_SOUND

844

final String soundPath = Settings.System.getString(cr,

845

Settings.System.LOW_BATTERY_SOUND);

846

if (soundPath != null) {

定义在文件Settings.java

1660

public static final String POWER_SOUNDS_ENABLED = "power_sounds_enabled";

1678

public static final String LOW_BATTERY_SOUND = "low_battery_sound";

通过如下方式读取默认值

1081

private void loadUISoundEffectsSettings(SQLiteStatement stmt) {

1082

loadIntegerSetting(stmt, Settings.System.POWER_SOUNDS_ENABLED,

1083

R.integer.def_power_sounds_enabled);

1084

loadStringSetting(stmt, Settings.System.LOW_BATTERY_SOUND,

1085

R.string.def_low_battery_sound);

1098

loadIntegerSetting(stmt, Settings.System.LOCKSCREEN_SOUNDS_ENABLED,

1099

R.integer.def_lockscreen_sounds_enabled);

1100

loadStringSetting(stmt, Settings.System.LOCK_SOUND,

1101

R.string.def_lock_sound);

1102

loadStringSetting(stmt, Settings.System.UNLOCK_SOUND,

1103

R.string.def_unlock_sound);

上面包括是否开启解锁屏声音,默认值定义在如下文件中

61

62

1

63 /system/media/audio/ui/LowBattery.ogg

64

0

69

0

70

/system/media/audio/ui/Lock.ogg

71

/system/media/audio/ui/Unlock.ogg

通过以上分析可以知道,低点提示音始终是有的,并且用户不可以定制

有了以上的分析,可以很清楚的知道,可以在Settings应用里加个可以配置低点提示音的功能

如可以在SoundSettings中多定义一个CheckboxPreference用来控制,当用户选中时,操作也很简单

final ContentResolver cr = mContext.getContentResolver();

Settings.System.putInt(cr, Settings.System.POWER_SOUNDS_ENABLED, 0);

1.2)如果此时电话不为TelephonyManager.CALL_STATE_IDLE状态,而是如下两种状态

当电话状态变更为CALL_STATE_IDLE时,会调用如下函数

859

private final void updateCallState(int state) {

860

mPhoneState = state;

861

if (false) {

862

Slog.d(TAG, "mPhoneState=" + mPhoneState

863

+ " mLowBatteryDialog=" + mLowBatteryDialog

864

+ " mBatteryShowLowOnEndCall=" + mBatteryShowLowOnEndCall);

866

if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) {

867

if (mBatteryShowLowOnEndCall) {

868

if (!mBatteryPlugged) {

869

showLowBatteryWarning();

871

mBatteryShowLowOnEndCall= false;

873

} else {

874

if (mLowBatteryDialog != null) {

875

mLowBatteryDialog.dismiss();

876

mBatteryShowLowOnEndCall= true;

由于mBatteryShowLowOnEndCall已经被置为true,如果此时没有在充电状态,则也会调到showLowBatteryWarning,与以上的处理方式一样。

以上知识处理了Intent.ACTION_BATTERY_LOW,下面简单看一下如何处理Intent.ACTION_BATTERY_OKAY

775

private void onBatteryOkay(Intent intent) {

776

if (mLowBatteryDialog != null

777

&& SHOW_LOW_BATTERY_WARNING) {

778 mLowBatteryDialog .dismiss();

779

mBatteryShowLowOnEndCall= false;

从以上代码中可以看出只是把mLowBatteryDialog给Dismiss掉,并把mBatteryShowLowOnEndCall复位

1)Phone应用

还有Phone应用也会接收Intent.ACTION_BATTERY_LOW消息,但是跟下去,看懂了代码实现者的意图,如果在通话中,电池电量较低时,会给用户一个提示,但是最终并没有真正的实现这一功能。

首先PhoneApp中注册监听Intent.ACTION_BATTERY_LOW

499

intentFilter.addAction(Intent.ACTION_BATTERY_LOW);

1440

} else if (action.equals(Intent.ACTION_BATTERY_LOW)) {

1441

if (VDBG) Log.d(LOG_TAG, "mReceiver: ACTION_BATTERY_LOW");

1442

notifier.sendBatteryLow(); // Play a warning tone if in-call

通过CallNotifier来处理信息

1226

void sendBatteryLow() {

1227

Message message = Message.obtain(this, PHONE_BATTERY_LOW);

1228

sendMessage(message);

通过Handler来处理PHONE_BATTERY_LOW信息

266

case PHONE_BATTERY_LOW:

267

onBatteryLow();

268

break;


http://www.ppmy.cn/news/787067.html

相关文章

app内中英文切换

随着时代的发展,应用程序相继出现了不同语言的版本方案,中文,英文,法文,韩文等等;想在应用程序中实现语言的自由切换,需要配置多个语言的文件,根据用户的动态选择获取不同语言文件下…

android 8.1 MTK 方案修改记录

目录 Music播放音乐时锁屏不需要显示专辑封面默认日期文件分享列表去掉某个app入口手势双击power键无需打开相机通话时按power键挂机SystemUI 下拉状态栏去掉第三方应用快捷选项SystemUI 去掉关闭数据后状态栏显示X图标SystemUI 锁屏界面12小时显示上下午12小时制,锁…

android 4.4 电池电量显示分析(低电量提醒与电池图标)Java 层

最近工作接触到这么的东西,这是我对整个电池管理方面Java 层的分析。如果想了解底层的话,请看我的博客: android 4.4 电池电量管理底层分析(C\C层) (http://blog.csdn.net/daweibalang717/article/details/41446993) …

android开发笔记之电池低电处理

公司最近在搞个KMS,鼓励大家技术分享。好吧,我是一个好员工,积极响应领导的各种要求。但是,这个我不会写的,你可以说我没有分享精神,可以说我技术水平low,我就是不会写。如果公司一定要强制要求…

android 4.4 batteryservice 电池电量显示分析

最近工作接触到这么的东西,这是我对整个电池管理方面Java 层的分析。如果想了解底层的话,请看我的博客: android 4.4 电池电量管理底层分析(C\C层) (http://blog.csdn.NET/daweibalang717/article/details/41446993) 先…

AOSP ~ 默认属性值

在定制化开发中,有些需求是要给个默认状态的,例如应用安装的允许安装未知来源,默认开启蓝牙,开启wifi,休眠时间,等等各种配置. 在系统framework/base/packages/SettingsProvider/res/values/ 目录下有个defaults.xml文件,里面就包含了大部分系统自带功能属性的配置, <resou…

Android 11.0 SystemUI增加低电量弹窗功能

目录 1.概述 2.SystemUI中实现低电量弹窗功能分析 3.SystemUI中实现低电量弹窗功能代码分析

如何在Apple Watch上启用和禁用电量储备

The battery in the Apple Watch lasts approximately 18 hours, depending on use. If your battery gets too low, you can put the watch into Power Reserve mode so you can see the time for up to 72 hours. 在苹果的手表电池持续大约18小时&#xff0c; 这取决于使用 。…