1. 程式人生 > >android6.0 新增電量百分比

android6.0 新增電量百分比

要完成這個功能需要修改SystemUI和Settings兩部分
一、Settings新增開關——控制是否開啟此功能
我選擇把開關新增到display模組下

diff --git a/packages/apps/Settings/res/xml/display_settings.xml b/packages/apps/Settings/res/xml/display_settings.xml
index 7150150..590bee9 100644
--- a/packages/apps/Settings/res/xml/display_settings.xml
+++ b/packages/apps/Settings/res/xml/display_settings.xml
@@ -110,4 +110,9 @@ settings:keywords="@string/keywords_display_cast_screen" android:fragment="com.android.settings.wfd.WifiDisplaySettings" /> + <SwitchPreference + android:key="battery_pct" + android:title="@string/show_battery_percentage" + android:persistent="false" />
+ </PreferenceScreen>

然後在packages/apps/Settings/src/com/android/settings/DisplaySettings.java 對SwitchPreference進行控制監聽

diff --git a/packages/apps/Settings/src/com/android/settings/DisplaySettings.java b/packages/apps/Settings/src/com/android/s
index 9f29ca5..d1eafba 100755
--- a/packages/apps/Settings/src/com/android/settings/DisplaySettings.java
+++ b/packages/apps/Settings/src/com/android/settings/DisplaySettings.java
@@ -42
,16 +42,22 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; +import android.database.ContentObserver; import android.hardware.Sensor; import android.hardware.SensorManager; +import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.Handler; import android.os.RemoteException; import android.os.SystemProperties; import android.preference.ListPreference; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; +import android.preference.Preference.OnPreferenceChangeListener; import android.preference.PreferenceScreen; +import android.provider.Settings; +import android.provider.Settings.System; import android.preference.SwitchPreference; import android.provider.SearchIndexableResource; import android.provider.Settings; @@ -78,6 +84,7 @@ public class DisplaySettings extends SettingsPreferenceFragment implements private static final String KEY_AUTO_ROTATE = "auto_rotate"; private static final String KEY_NIGHT_MODE = "night_mode"; private static final String KEY_CAMERA_GESTURE = "camera_gesture"; + private static final String KEY_BATTERY_PCT = "battery_pct"; private static final String KEY_CAMERA_DOUBLE_TAP_POWER_GESTURE = "camera_double_tap_power_gesture"; @@ -96,6 +103,8 @@ public class DisplaySettings extends SettingsPreferenceFragment implements private SwitchPreference mAutoBrightnessPreference; private SwitchPreference mCameraGesturePreference; private SwitchPreference mCameraDoubleTapPowerGesturePreference; + private SwitchPreference mBatteryPct; + private final SettingObserver mSettingObserver = new SettingObserver(); @Override protected int getMetricsCategory() { @@ -130,6 +139,8 @@ public class DisplaySettings extends SettingsPreferenceFragment implements mFontSizePref.setOnPreferenceChangeListener(this); mFontSizePref.setOnPreferenceClickListener(this); + mBatteryPct = (SwitchPreference) findPreference(KEY_BATTERY_PCT); + if (hasLightSensor && isAutomaticBrightnessAvailable(getResources())) { mAutoBrightnessPreference = (SwitchPreference) findPreference(KEY_AUTO_BRIGHTNESS); mAutoBrightnessPreference.setOnPreferenceChangeListener(this); @@ -221,6 +232,23 @@ public class DisplaySettings extends SettingsPreferenceFragment implements } } + public final String SHOW_PERCENT_SETTING = "status_bar_show_battery_percent"; + private final OnPreferenceChangeListener mBatteryPctChange = new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean v = (Boolean) newValue; + MetricsLogger.action(getContext(), MetricsLogger.TUNER_BATTERY_PERCENTAGE, v); + System.putInt(getContext().getContentResolver(), SHOW_PERCENT_SETTING, v ? 1 : 0); + return true; + } + }; + private void updateBatteryPct() { + mBatteryPct.setOnPreferenceChangeListener(null); + mBatteryPct.setChecked(System.getInt(getContext().getContentResolver(), + SHOW_PERCENT_SETTING, 0) != 0); + mBatteryPct.setOnPreferenceChangeListener(mBatteryPctChange); + } + private static boolean allowAllRotations(Context context) { return Resources.getSystem().getBoolean( com.android.internal.R.bool.config_allowAllRotations); @@ -370,6 +398,17 @@ public class DisplaySettings extends SettingsPreferenceFragment implements public void onResume() { super.onResume(); updateState(); + updateBatteryPct(); + getContext().getContentResolver().registerContentObserver( + System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, true); + } + + @Override + public void onPause(){ + super.onPause(); + getContext().getContentResolver().unregisterContentObserver(mSettingObserver); + MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, false); } @Override @@ -575,4 +614,16 @@ public class DisplaySettings extends SettingsPreferenceFragment implements return result; } }; + + private final class SettingObserver extends ContentObserver { + public SettingObserver() { + super(new Handler()); + } + + @Override + public void onChange(boolean selfChange, Uri uri, int userId) { + super.onChange(selfChange, uri, userId); + updateBatteryPct(); + } + }

其中使用到了[ContentObserver]這個類用來監聽資料庫中某個數值的變化可以去看這篇文章。
到此settings部分完成。
二、SystemUI部分—–新增顯示百分比
首先在frameworks/base/packages/SystemUI/res/layout/status_bar.xml新增一個TextView如下

diff --git a/frameworks/base/packages/SystemUI/res/layout/status_bar.xml b/frameworks/base/packages/SystemUI/res/layout/stat
index 8d4e33f..cb74062 100644
--- a/frameworks/base/packages/SystemUI/res/layout/status_bar.xml
+++ b/frameworks/base/packages/SystemUI/res/layout/status_bar.xml
@@ -96,6 +96,15 @@

             <include layout="@layout/system_icons" />

+           <TextView  
+                android:id="@+id/percentage"  
+                android:layout_height="wrap_content"  
+                android:layout_width="wrap_content"  
+                android:visibility = "gone"  
+                android:paddingLeft="4dip"  
+                android:textSize="@dimen/status_bar_clock_size"  
+                android:textColor="@color/qs_text"/>
+
             <com.android.systemui.statusbar.policy.Clock
                 android:id="@+id/clock"
                 android:textAppearance="@style/TextAppearance.StatusBar.Clock"

新增萬textView後就可以到程式碼中進行控制我們可以在frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java中對它進行顯示/隱藏/賦值
在這之前需要把textview傳到BatteryController

diff --git a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/frameworks/bas
index 6bde992..e8751c0 100644
--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

@@ -821,6 +821,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
         mLocationController = new LocationControllerImpl(mContext,
                 mHandlerThread.getLooper()); // will post a notification
         mBatteryController = new BatteryController(mContext);
+       mBatteryController.setTextView((TextView) mStatusBarWindow.findViewById(R.id.percentage));
         mBatteryController.addStateChangedCallback(new BatteryStateChangeCallback() {
             @Override
diff --git a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/frameworks
index d1b69ab..0fd4961 100644
--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java
@@ -20,9 +20,15 @@ import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
 import android.os.BatteryManager;
+import android.os.Handler;
 import android.os.PowerManager;
+import android.provider.Settings;
 import android.util.Log;
+import android.widget.TextView;
+import android.view.View;

 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -31,7 +37,7 @@ import java.util.ArrayList;
 public class BatteryController extends BroadcastReceiver {
     private static final String TAG = "BatteryController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
+    private final String SHOW_PERCENT_SETTING = "status_bar_show_battery_percent";
     private final ArrayList<BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
     private final PowerManager mPowerManager;

@@ -40,16 +46,23 @@ public class BatteryController extends BroadcastReceiver {
     private boolean mCharging;
     private boolean mCharged;
     private boolean mPowerSave;
+    private TextView mBatteryPercent;
+    private boolean mShowPercent;
+    private String mPercent = "100%";
+    private Context mContext;
+    private final SettingObserver mSettingObserver = new SettingObserver();

     public BatteryController(Context context) {
         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-
+        mContext = context;
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_BATTERY_CHANGED);
         filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
         filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING);
         context.registerReceiver(this, filter);
-
+        context.getContentResolver().registerContentObserver(
+                Settings.System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
+       updateShowPercent();
         updatePowerSave();
     }

@@ -71,6 +84,26 @@ public class BatteryController extends BroadcastReceiver {
         mChangeCallbacks.remove(cb);
     }

+    public void setTextView(TextView batteryPercent){
+       mBatteryPercent = batteryPercent;
+    }
+
+    private String getBatteryPercentage(Intent batteryChangedIntent) {  
+        int level = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);  
+        int scale = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);  
+        return String.valueOf(level * 100 / scale) + "%";  
+    }
+
+    private void setPercent() {
+       if (mBatteryPercent == null) return;
+       if (mShowPercent) {
+           mBatteryPercent.setText(mPercent);
+           mBatteryPercent.setVisibility(View.VISIBLE);
+       } else {
+           mBatteryPercent.setVisibility(View.GONE);
+       }
+    } 
+
     public void onReceive(Context context, Intent intent) {
         final String action = intent.getAction();
         if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
@@ -83,7 +116,8 @@ public class BatteryController extends BroadcastReceiver {
                     BatteryManager.BATTERY_STATUS_UNKNOWN);
             mCharged = status == BatteryManager.BATTERY_STATUS_FULL;
             mCharging = mCharged || status == BatteryManager.BATTERY_STATUS_CHARGING;
-
+           mPercent = getBatteryPercentage(intent);
+           setPercent();
             fireBatteryLevelChanged();
         } else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
             updatePowerSave();
@@ -125,4 +159,28 @@ public class BatteryController extends BroadcastReceiver {
         void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging);
         void onPowerSaveChanged();
     }
+
+    private void updateShowPercent() {
+        mShowPercent = 0 != Settings.System.getInt(mContext.getContentResolver(),
+                SHOW_PERCENT_SETTING, 0);
+    }
+
+    private final class SettingObserver extends ContentObserver {
+        public SettingObserver() {
+            super(new Handler());
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            super.onChange(selfChange, uri);
+            updateShowPercent();
+           if (mBatteryPercent != null){
+               if (mShowPercent) {
+                   mBatteryPercent.setVisibility(View.VISIBLE);
+               } else {
+                    mBatteryPercent.setVisibility(View.GONE);
+               }
+           }
+        }
+    }
 }

這樣只是在statubar顯示電量百分比,系統有個地方還會顯示,當充電時鎖屏介面會顯示。所以我們要改一下它的邏輯讓它也由SHOW_PERCENT_SETTING控制如下更改

diff --git a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/framewo
index b93fc76..e75bbcf 100644
--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -35,9 +35,11 @@ import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
-
+import android.provider.Settings;
 import java.text.NumberFormat;
-
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
 /**
  * The header group on Keyguard.
  */
@@ -59,9 +61,13 @@ public class KeyguardStatusBarView extends RelativeLayout

     private int mSystemIconsSwitcherHiddenExpandedMargin;
     private Interpolator mFastOutSlowInInterpolator;
-
+    private final String SHOW_PERCENT_SETTING = "status_bar_show_battery_percent";
+    private final SettingObserver mSettingObserver = new SettingObserver();  
     public KeyguardStatusBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
+       context.getContentResolver().registerContentObserver(
+                Settings.System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
+
     }

     @Override
@@ -76,6 +82,7 @@ public class KeyguardStatusBarView extends RelativeLayout
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
                 android.R.interpolator.fast_out_slow_in);
         updateUserSwitcher();
+       updateVisibilities();
     }

     @Override
@@ -94,6 +101,22 @@ public class KeyguardStatusBarView extends RelativeLayout
         mSystemIconsSwitcherHiddenExpandedMargin = getResources().getDimensionPixelSize(
                 R.dimen.system_icons_switcher_hidden_expanded_margin);
     }
+       
+    private final class SettingObserver extends ContentObserver {
+        public SettingObserver() {
+            super(new Handler());
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            super.onChange(selfChange, uri);
+            updateVisibilities();
+       }
+    }
+    
+
+
+

     private void updateVisibilities() {
         if (mMultiUserSwitch.getParent() != this && !mKeyguardUserSwitcherShowing) {
@@ -104,7 +127,15 @@ public class KeyguardStatusBarView extends RelativeLayout
         } else if (mMultiUserSwitch.getParent() == this && mKeyguardUserSwitcherShowing) {
             removeView(mMultiUserSwitch);
         }
-        mBatteryLevel.setVisibility(mBatteryCharging ? View.VISIBLE : View.GONE);
+       int isDisplay=Settings.System.getInt(mContext.getContentResolver(),
+                SHOW_PERCENT_SETTING, 0);
+       if(isDisplay==0){
+               mBatteryLevel.setVisibility(View.GONE); 
+       }else{
+               mBatteryLevel.setVisibility(View.VISIBLE);
+       }
+        //mBatteryLevel.setVisibility(isDisplay ? View.VISIBLE : View.GONE);
+       //mBatteryLevel.setVisibility(mBatteryCharging ? View.VISIBLE : View.GONE);
     }

到此顯示也完成了。
但是SHOW_PERCENT_SETTING這個值還會控制Android自帶的一個功能(把電量顯示到電池圖示內)。所以我們要把這個功能遮蔽了
遮蔽如下

diff --git a/frameworks/base/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/frameworks/base/packages/Sys
index 95b58e5..21de480 100755
--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -54,7 +54,7 @@ public class BatteryMeterView extends View implements DemoMode,

     private final int[] mColors;

-    private boolean mShowPercent;
+    private boolean mShowPercent = false;
     private float mButtonHeightFraction;
     private float mSubpixelSmoothingLeft;
     private float mSubpixelSmoothingRight;
@@ -231,8 +231,8 @@ public class BatteryMeterView extends View implements DemoMode,
     }

     private void updateShowPercent() {
-        mShowPercent = 0 != Settings.System.getInt(getContext().getContentResolver(),
-                SHOW_PERCENT_SETTING, 0);
+       // mShowPercent = 0 != Settings.System.getInt(getContext().getContentResolver(),
+         //       SHOW_PERCENT_SETTING, 0);
     }

     private int getColorForLevel(int percent) {