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

news/2024/12/22 19:55:35/

这里写图片描述

公司最近在搞个KMS,鼓励大家技术分享。好吧,我是一个好员工,积极响应领导的各种要求。但是,这个我不会写的,你可以说我没有分享精神,可以说我技术水平low,我就是不会写。如果公司一定要强制要求我写,我也一定是乱写凑数,这完全不能怪我,只能怪这个无情的世界,无情的季节,无情的………….。(请不要问我具体的原因,谢谢!)

但是,有一个好朋友,在上面发表了一个电池低电处理的文章,我看了一下,确实是说的非常清楚,只是是一个比较低版本的代码流程,我在android 7.1的代码上看了一下,和他说的有一点出入,不过,这没有关系不影响我们来学习。

我可以不写,但是我们可以学习。

BatteryService.java

./frameworks/base/services/core/java/com/android/server/BatteryService.java

当电池电量少于我们配置的低电量警告值(config_lowBatteryWarningLevel)时,发送低电量通知,弹出低电量通知对话框。
./frameworks/base/core/res/res/values/config.xml

<integer name="config_lowBatteryWarningLevel">15</integer>

只我满足shouldSendBatteryLowLocked的条件就可以发送低电量通知:

private boolean shouldSendBatteryLowLocked() {final boolean plugged = mPlugType != BATTERY_PLUGGED_NONE;final boolean oldPlugged = mLastPlugType != BATTERY_PLUGGED_NONE;/* The ACTION_BATTERY_LOW broadcast is sent in these situations:* - is just un-plugged (previously was plugged) and battery level is*   less than or equal to WARNING, or* - is not plugged and battery level falls to WARNING boundary*   (becomes <= mLowBatteryWarningLevel).*/
        return !plugged&& mBatteryProps.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN&& mBatteryProps.batteryLevel <= mLowBatteryWarningLevel&& (oldPlugged || mLastBatteryLevel > mLowBatteryWarningLevel);}

发送低电量通知Intent.ACTION_BATTERY_LOW:

private void processValuesLocked(boolean force)if (shouldSendBatteryLowLocked()) {mSentLowBatteryBroadcast = true;mHandler.post(new Runnable() {@Overridepublic void run() {Intent statusIntent = new Intent(Intent.ACTION_BATTERY_LOW);statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);}});

当电量为0时,发出关闭通知Intent.ACTION_REQUEST_SHUTDOWN:

private void shutdownIfWeakChargerEmptySOCLocked() {if (mBatteryProps.batteryLevel == 0) {if (mInitiateShutdown) {if (ActivityManagerNative.isSystemReady()) {Intent intent = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);intent.putExtra(Intent.EXTRA_KEY_CONFIRM, false);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);mContext.startActivityAsUser(intent, UserHandle.CURRENT);}   

PowerNotificationWarnings.java

./frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java

当电量低时,弹出低电量通知对话框:

private void showWarningNotification() {final int textRes = R.string.battery_low_percent_format;final String percentage = NumberFormat.getPercentInstance().format((double) mBatteryLevel / 100.0);final Notification.Builder nb = new Notification.Builder(mContext).setSmallIcon(R.drawable.ic_power_low)// Bump the notification when the bucket dropped..setWhen(mBucketDroppedNegativeTimeMs).setShowWhen(false).setContentTitle(mContext.getString(R.string.battery_low_title)).setContentText(mContext.getString(textRes, percentage)).setOnlyAlertOnce(true).setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_WARNING)).setPriority(Notification.PRIORITY_MAX).setVisibility(Notification.VISIBILITY_PUBLIC).setColor(mContext.getColor(com.android.internal.R.color.battery_saver_mode_color));if (hasBatterySettings()) {nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));}nb.addAction(0,mContext.getString(R.string.battery_saver_start_action),pendingBroadcast(ACTION_START_SAVER));if (mPlaySound) {attachLowBatterySound(nb);mPlaySound = false;}SystemUI.overrideNotificationAppName(mContext, nb);mNoMan.notifyAsUser(TAG_NOTIFICATION, R.id.notification_power, nb.build(), UserHandle.ALL);}

并播放低电量声音:

private void attachLowBatterySound(Notification.Builder b) {final ContentResolver cr = mContext.getContentResolver();final int silenceAfter = Settings.Global.getInt(cr,Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0);final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime;if (silenceAfter > 0&& mScreenOffTime > 0&& offTime > silenceAfter) {Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter+ "ms): not waking up the user with low battery sound");return;}if (DEBUG) {Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated}if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) {final String soundPath = Settings.Global.getString(cr,Settings.Global.LOW_BATTERY_SOUND);if (soundPath != null) {final Uri soundUri = Uri.parse("file://" + soundPath);if (soundUri != null) {b.setSound(soundUri, AUDIO_ATTRIBUTES);if (DEBUG) Slog.d(TAG, "playing sound " + soundUri);}}}}

我们一般在配置文件中设置低电量的声音文件和超时时间:
./frameworks/base/packages/SettingsProvider/res/values/defaults.xml

<string name="def_low_battery_sound" translatable="false">/system/media/audio/ui/LowBattery.ogg</string>
<!-- Default for Settings.Global.LOW_BATTERY_SOUND_TIMEOUT.
<integer name="def_low_battery_sound_timeout">0</integer>

而事实上调用showWarningNotification方法,弹出低电量通知对话框的地方为updateNotification():

    private void updateNotification() {if (mInvalidCharger) {showInvalidChargerNotification();mShowing = SHOWING_INVALID_CHARGER;} else if (mWarning) {showWarningNotification();

再往上查找调用updateNotification() 为:

    public void showLowBatteryWarning(boolean playSound) {mPlaySound = playSound;mWarning = true;updateNotification();}

再往上查找调用showLowBatteryWarning() 为:
./frameworks/base/packages/SystemUI/src/com/android/systemui/power/PowerUI.java

private final class Receiver extends BroadcastReceiver {public void init() {// Register for Intent broadcasts for...IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_BATTERY_CHANGED);filter.addAction(Intent.ACTION_SCREEN_OFF);filter.addAction(Intent.ACTION_SCREEN_ON);filter.addAction(Intent.ACTION_USER_SWITCHED);filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);mContext.registerReceiver(this, filter, null, mHandler);}@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {final int oldBatteryLevel = mBatteryLevel;mBatteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 100);final int oldBatteryStatus = mBatteryStatus;mBatteryStatus = intent.getIntExtra(BatteryManager.EXTRA_STATUS,BatteryManager.BATTERY_STATUS_UNKNOWN);final int oldPlugType = mPlugType;mPlugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 1);final int oldInvalidCharger = mInvalidCharger;mInvalidCharger = intent.getIntExtra(BatteryManager.EXTRA_INVALID_CHARGER, 0);final boolean plugged = mPlugType != 0;final boolean oldPlugged = oldPlugType != 0;int oldBucket = findBatteryLevelBucket(oldBatteryLevel);int bucket = findBatteryLevelBucket(mBatteryLevel);mWarnings.update(mBatteryLevel, bucket, mScreenOffTime);if (oldInvalidCharger == 0 && mInvalidCharger != 0) {mWarnings.showInvalidChargerWarning();return;} else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {mWarnings.dismissInvalidChargerWarning();} else if (mWarnings.isInvalidChargerWarningShowing()) {return;}boolean isPowerSaver = mPowerManager.isPowerSaveMode();if (!plugged&& !isPowerSaver&& (bucket < oldBucket || oldPlugged)&& mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN&& bucket < 0) {// only play SFX when the dialog comes up or the bucket changesfinal boolean playSound = bucket != oldBucket || oldPlugged;mWarnings.showLowBatteryWarning(playSound);

可见,现在弹出低电量通知对话框是接受广播Intent.ACTION_BATTERY_CHANGED来实现的。


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

相关文章

android 4.4 batteryservice 电池电量显示分析

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

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; 这取决于使用 。…

C#学习之路-方法

一个方法是把一些相关的语句组织在一起&#xff0c;用来执行一个任务的语句块。每一个 C# 程序至少有一个带有 Main 方法的类。 要使用一个方法&#xff0c;您需要&#xff1a; 定义方法调用方法 C# 中定义方法 当定义一个方法时&#xff0c;从根本上说是在声明它的结构的元…

三张表学会MySQL的单表操作!

表单一信息 1、查询表中所有学生的信息 mysql> select * from student; 2、 查询表中所有学生的姓名和英语成绩 mysql> select name,english from student; 3、过滤表中的重复数据 mysql> select DISTINCT * from student; 4、统计每个学生的总分 mysql> sele…

video 满屏显示_微信H5视频自动弹出全屏播放的解决方案

微信播放最大坑 h5页面分享到微信上播放视频&#xff0c;最大的坑就是在Android手机上&#xff0c;X5浏览器会劫持Video标签用腾讯播放器弹出全屏播放&#xff0c;处于最上层&#xff0c;覆盖DOM元素&#xff0c;更可恶的是播放完毕时&#xff0c;会出现很多腾讯的广告视频&…

bili弹幕姬_bilibili弹幕姬怎么用 - 卡饭网

哔哩哔哩发弹幕怎么换行?bilibili弹幕换行快捷键介绍 哔哩哔哩发弹幕怎么换行?bilibili弹幕换行快捷键介绍 哔哩哔哩弹幕怎么换行?很多朋友想知道bilibili弹幕换行方法,为什么别的小伙伴发的弹幕有很多行呢?该如何设置呢?如果你想知道的话就请继续往下看吧。 第一种方法:…