Android 5.1 - 狀態欄充電標志問題


Android 5.1 Ubuntu14.04  SourceInsigh

電量已滿,插着USB頭,觀察Settings - Battery,電量為100%,狀態為full,但仍有充電圖標rust

之前有讀過關於StatusBar的代碼。這次直接用SourceInsight找到 StatusBarHeaderView.java  

里面關於電池的方法有

    @Override     public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {         String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0);         mBatteryLevel.setText(percentage);     }

似乎沒什么幫助,我們找的是圖標,不是數字

猜測一下,電池狀態變化的時候,肯定會發出通知,十有八九是用廣播發出的

用SourceInsight直接搜索battery,搜到關於Battery的一些文件

/** BatteryManager.java (base/core/java/android/os)*/     // values for "status" field in the ACTION_BATTERY_CHANGED Intent     public static final int BATTERY_STATUS_FULL = 5;    // 定義了狀態值

在 BatteryService.java 中,可以發現一個獲取icon的方法

/** BatteryService.java (base/services/core/java/com/android/server) */ private int getIconLocked(int level) {         if (mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {             return com.android.internal.R.drawable.stat_sys_battery_charge; ......

根據stat_sys_battery_charge,可以找到 Stat_sys_battery_charge.xml  (framework/base/core/res/res/drawable)

find一下就能值得圖標存放在frameworks/base/core/res/res/drawable-mdpi/ 等目錄下

 

修改 BatteryService.java  getIconLocked中的判斷條件或返回值

找到了很多資源文件,修改一下返回值。比如:

if (mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {             return com.android.internal.R.drawable.stat_sys_battery;    // 顯示未充電的圖標

編譯后push進去,發現沒效果

不成功,為何?發出的廣播沒有人接收?icon被塞進了 BatteryManager.EXTRA_ICON_SMALL

int icon = getIconLocked(mBatteryProps.batteryLevel); intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon);

grep一下EXTRA_ICON_SMALL,發現沒地方接收。發出的廣播沒人收,那電池圖標rust是怎么放上去的?

 

換一個尋找思路

我知道狀態欄屬於SystemUI,觀察SystemUI的文件目錄;打開 AndroidManifest.xml 看到

<service android:name="SystemUIService" android:exported="true"/>

接下來找到並打開 SystemUIService.java ;在onCreate()中提到了SystemUIApplication

 SystemUIApplication.java 里啟動了一系列的服務,其中就包括

com.android.systemui.statusbar.SystemBars.class

打開 SystemBars.java  frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar

可以看到BaseStatusBar

 mStatusBar = (BaseStatusBar) cls.newInstance(); 

順藤摸瓜

在 BaseStatusBar.java 中搜索R.layout,卻只找到notification相關的

BaseStatusBar是基礎狀態欄的意思,會不會有別的類來繼承它?grep一下發現

TvStatusBar和PhoneStatusBar繼承自BaseStatusBar

在 PhoneStatusBar.java 中搜索“R.layout.”,得到幾個layout:

R.layout.super_status_bar

R.layout.heads_up

R.layout.navigation_bar

R.layout.status_bar_notification_keyguard_overflow 等等

mStatusBarWindow = (StatusBarWindowView) View.inflate(context,                 R.layout.super_status_bar, null);

重點關注一下super_status_bar,里面裝載了很多子布局,比如status_bar

打開 status_bar.xml  ,找到system_icon_area;它include了system_icons

打開 system_icons.xml 我們發現,有一個自定義控件com.android.systemui.BatteryMeterView

現在知道電池圖標是畫出來的了

//BatteryMeterView.java (framework/base/packages/systemui/src/com/android/systemui) public class BatteryMeterView extends View implements DemoMode,         BatteryController.BatteryStateChangeCallback

實現了BatteryController.BatteryStateChangeCallback接口,電池狀態改變,電池圖標會更新

private class BatteryTracker extends BroadcastReceiver {

接收廣播,取出電池各項信息;得到電池信息要更新圖標

觀察draw方法,里面有用tracker來進行判斷

        if (tracker.plugged) {             // define the bolt shape

如果插上了USB頭,就畫出閃電標志;我們的要求是充電狀態下才能有閃電標志

那么多加入一個判斷,當充滿電的時候,不要畫閃電標志

        if (tracker.plugged && (batteryStatus != BatteryManager.BATTERY_STATUS_FULL)) {             // define the bolt shape

batteryStatus是rust自行定義的int變量,從BatteryTracker中取出電池status,再用來判斷

重新編譯燒寫,發現充滿電后,無充電標志

原來充電的標志rust是畫上去的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM