电量提醒

本文探讨了小屏终端设备遇到电量提醒导致界面显示问题的情况。通常,电量提醒功能在SystemUI下实现,通过分析alps/frameworks/base/packages/SystemUI源代码,发现PowerUI.java中的广播接收器处理电量警告。通过修改PowerNotificationWarnings.java中的showLowBatteryWarning方法,注释掉发送通知的代码,可以解决小屏设备因电量提醒遮挡屏幕的问题。

        生活中我们会发现一个现象,手机到了某个电量的时候就会进行提醒(比如说我的手机到了15%和5%的电量时都会有电量提醒),这个功能能够告诉用户:“该充电了!”。但是我最经就遇到了一个问题,因为我做了一个小屏终端(比240*320还小的),所以有很多东西都显示不全,出这个提醒的时候不但会状态栏变空(因为有通知,而客户是不需要的),还会出现一个问题——会有三个横线把屏幕给遮挡了(因为发了通知之后显示不全),那这个问题就得改了。

        根据经验,这个功能应该是在systemui下实现的,果不其然,在alps/frameworks/base/packages/SystemUI/src/com/android/systemui/power这个目录下有两个文件:PowerNotificationWarnings.java和PowerUI.java,里面就有关于该功能的实现。

         首先在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);
            updateSaverMode();
        }

        private void updateSaverMode() {
            setSaverMode(mPowerManager.isPowerSaveMode());
        }

        @Override
        public 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);

                if (DEBUG) {
                    Slog.d(TAG, "buckets   ....." + mLowBatteryAlertCloseLevel
                            + " .. " + mLowBatteryReminderLevels[0]
                            + " .. " + mLowBatteryReminderLevels[1]);
                    Slog.d(TAG, "level          " + oldBatteryLevel + " --> " + mBatteryLevel);
                    Slog.d(TAG, "status         " + oldBatteryStatus + " --> " + mBatteryStatus);
                    Slog.d(TAG, "plugType       " + oldPlugType + " --> " + mPlugType);
                    Slog.d(TAG, "invalidCharger " + oldInvalidCharger + " --> " + mInvalidCharger);
                    Slog.d(TAG, "bucket         " + oldBucket + " --> " + bucket);
                    Slog.d(TAG, "plugged        " + oldPlugged + " --> " + plugged);
                }

                mWarnings.update(mBatteryLevel, bucket, mScreenOffTime);
                if (oldInvalidCharger == 0 && mInvalidCharger != 0) {
                    Slog.d(TAG, "showing invalid charger warning");
                    mWarnings.showInvalidChargerWarning();
                    return;
                } else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {
                    mWarnings.dismissInvalidChargerWarning();
                } else if (mWarnings.isInvalidChargerWarningShowing()) {
                    // if invalid charger is showing, don't show low battery
                    return;
                }

                if (!plugged
                        && (bucket < oldBucket || oldPlugged)
                        && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
                        && bucket < 0) {
                    // only play SFX when the dialog comes up or the bucket changes
                    final boolean playSound = bucket != oldBucket || oldPlugged;
                    mWarnings.showLowBatteryWarning(playSound);
                } else if (plugged || (bucket > oldBucket && bucket > 0)) {
                    mWarnings.dismissLowBatteryWarning();
                } else {
                    mWarnings.updateLowBatteryWarning();
                }
            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
                mScreenOffTime = SystemClock.elapsedRealtime();
            } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
                mScreenOffTime = -1;
            } else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
                mWarnings.userSwitched();
            } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) {
                updateSaverMode();
            } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGING.equals(action)) {
                setSaverMode(intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false));
            } else {
                Slog.w(TAG, "unknown intent: " + intent);
            }
        }
    };

       我们可以看到其中有一句:

       mWarnings.showLowBatteryWarning(playSound);

       这里就是发生警告的地方。

       我们来看一下这个方法从何而来,在PowerUI.java类中有一个接口:

    public interface WarningsUI {
        void update(int batteryLevel, int bucket, long screenOffTime);
        void showSaverMode(boolean mode);
        void dismissLowBatteryWarning();
        void showLowBatteryWarning(boolean playSound);
        void dismissInvalidChargerWarning();
        void showInvalidChargerWarning();
        void updateLowBatteryWarning();
        boolean isInvalidChargerWarningShowing();
        void dump(PrintWriter pw);
        void userSwitched();
    }

      showLowBatteryWarning方法就在其中,那哪个类有实现了该方法呢,就是该包中的另一个类PowerNotificationWarnings.java了:

  

public class PowerNotificationWarnings implements PowerUI.WarningsUI

在该类中也有具体功能的一些实现,比如15%电量的警告或者5%电量的警告等:

 

152     private void showInvalidChargerNotification() {
 153         final Notification.Builder nb = new Notification.Builder(mContext)
 154                 .setSmallIcon(R.drawable.ic_power_low)
 155                 .setWhen(0)
 156                 .setShowWhen(false)
 157                 .setOngoing(true)
 158                 .setContentTitle(mContext.getString(R.string.invalid_charger_title))
 159                 .setContentText(mContext.getString(R.string.invalid_charger_text))
 160                 .setPriority(Notification.PRIORITY_MAX)
 161                 .setVisibility(Notification.VISIBILITY_PUBLIC)
 162                 .setColor(mContext.getColor(
 163                         com.android.internal.R.color.system_notification_accent_color));
 164         final Notification n = nb.build();
 165         if (n.headsUpContentView != null) {
 166             n.headsUpContentView.setViewVisibility(com.android.internal.R.id.right_icon, View.GONE);
 167         }
 168         mNoMan.notifyAsUser(TAG_NOTIFICATION, R.id.notification_power, n, UserHandle.ALL);
 169     }
 170 
 171     private void showWarningNotification() {
 172         final int textRes = mSaver ? R.string.battery_low_percent_format_saver_started
 173                 : R.string.battery_low_percent_format;
 174         final String percentage = NumberFormat.getPercentInstance().format((double) mBatteryLevel / 100.0);
 175         final Notification.Builder nb = new Notification.Builder(mContext)
 176                 .setSmallIcon(R.drawable.ic_power_low)
 177                 // Bump the notification when the bucket dropped.
 178                 .setWhen(mBucketDroppedNegativeTimeMs)
 179                 .setShowWhen(false)
 180                 .setContentTitle(mContext.getString(R.string.battery_low_title))
 181                 .setContentText(mContext.getString(textRes, percentage))
 182                 .setOnlyAlertOnce(true)
 183                 .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_WARNING))
 184                 .setPriority(Notification.PRIORITY_MAX)
 185                 .setVisibility(Notification.VISIBILITY_PUBLIC)
 186                 .setColor(mContext.getColor(
 187                         com.android.internal.R.color.battery_saver_mode_color));
 188         if (hasBatterySettings()) {
 189             nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
 190         }
 191         if (!mSaver) {
 192             nb.addAction(0,
 193                     mContext.getString(R.string.battery_saver_start_action),
 194                     pendingBroadcast(ACTION_START_SAVER));
 195         } else {
 196             addStopSaverAction(nb);
 197         }
 198         if (mPlaySound) {
 199             attachLowBatterySound(nb);
 200             mPlaySound = false;
 201         }
 202         final Notification n = nb.build();
 203         if (n.headsUpContentView != null) {
 204             n.headsUpContentView.setViewVisibility(com.android.internal.R.id.right_icon, View.GONE);
 205         }
 206         mNoMan.notifyAsUser(TAG_NOTIFICATION, R.id.notification_power, n, UserHandle.ALL);
 207     }
 208 
 209     private void showSaverNotification() {
 210         final Notification.Builder nb = new Notification.Builder(mContext)
 211                 .setSmallIcon(R.drawable.ic_power_saver)
 212                 .setContentTitle(mContext.getString(R.string.battery_saver_notification_title))
 213                 .setContentText(mContext.getString(R.string.battery_saver_notification_text))
 214                 .setOngoing(true)
 215                 .setShowWhen(false)
 216                 .setVisibility(Notification.VISIBILITY_PUBLIC)
 217                 .setColor(mContext.getColor(
 218                         com.android.internal.R.color.battery_saver_mode_color));
 219         addStopSaverAction(nb);
 220         if (hasSaverSettings()) {
 221             nb.setContentIntent(pendingActivity(mOpenSaverSettings));
 222         }
 223         mNoMan.notifyAsUser(TAG_NOTIFICATION, R.id.notification_power, nb.build(), UserHandle.ALL);
 224     }

找到位置了那修改起来就简单了,把mNoMan.notifyAsUser(TAG_NOTIFICATION, R.id.notification_power, n, UserHandle.ALL);注释掉让它不能发通知就行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值