• Introducing XDA Computing: Discussion zones for Hardware, Software, and more!    Check it out!
  • Fill out your device list and let everyone know which phones you have!    Edit Your Device Inventory

[GUIDE] [JAVA to SMALI] Create SystemUI.apk external settings app - v1.1 - 13/04/14

Search This thread

serajr

Recognized Developer / Recognized Themer
Apr 21, 2011
5,022
18,617
São Paulo - SP
Hi community!! Here is a complete guide showing you how to create an "External Settings App" to control SystemUI.apk look and feel.
I have received tons of pm and mentions from users asking me how did I manage such "magic" work into my mods over Xperia's firmware, so I have decided to create this thread to share you "the concept" I've created. I really hope this guide help people to create your own settings apk from scratch, but not just for the SystemUI.apk, but for anyone in which you need/want to control.

I know that Xposed Framework do the same and also it is the right choice, mine choice too, but the meaning of this thread is: Knowledge exchange!!
Talking about Xposed Framework, here is my module to Xperia devices.

Back to topic...

First of all, a brief feedback about my mods over xda that use concept you will see:
- Serajr Swiping Power Toggles - SystemUI
- Xperia SystemUI + 23 JB Toggles + Sliders + Apps
- Xperia GX Home Launcher for All Xperias (Multi-Resolution)



Let's do it!! ;)

Requirements:
- Java programming skills (I'M NOT GOING TO SHOW HOW TO BUILD APPS OUTSIDE THREAD CONTEXT, NEITHER HOW TO DEVELOP ON THAT PLATFORM)
- Apktool decompile/compile skills (I'M NOT GOING TO SHOW HOW DO DO THAT)
- Logcat (in case you face any FC)

My lab:
- Windows 7 x64
- Eclipse
- Android SDK
- Java
- Apktool

My precious:
- Sony Xperia ZQ
- JB 4.3



External Settings App:

It has a very simple ui and code, with a single CheckBoxPreference!
Don't mind about deprecated functions, they are there purposely to make the simplest possible code. We know that the right choice for preferences is PreferenceFragment.

attachment.php
attachment.php




Java - External Settings App - Eclipse Project:

MainActivity.java
Every field and method contents is commented on for better understanding, but here, what really metters is:
Save current preference value to Settings.System

attachment.php


The app needs to have proper permission to write there, and the right one is:
Code:
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>

To make things easier in the future, I've created a "clone" PhoneStatusBar.java class with full package path too, and within it are all related code that "does the magic" (I'll explain every method further). This class has no function over our settings app context (NEVER INSTANTIATE IT), it is there just to allow us to write our SystemUI modifications in Java and get the Smali easily!!!

Take a look:
attachment.php




PHP:
makeStatusBarView()
Here is where SystemUI.apk creates all its contents, so we need to call our setup and handle methods here too.


PHP:
setupExternalSettingsObserver()
Here we setup our content observer (preferences keys we created in our settings app).


PHP:
externalPreferencesObserverCallback(Uri uri)
Here we filter which preference key has changed its state and do proper changes.


PHP:
handleStatusBarChangeClockToRed()
Here we set the status bar clock text color according current preference state.


PHP:
private class MyExternalPreferencesObserver extends ContentObserver
I've also created a inner class that will store our preferences keys Uri's to later pass changed ones to the callback method!



That´s it!!
Now we need to go deep into the "necessary evil" titled: smali !!

1. Get the newly built ExternalPreferences.apk from Eclipse project ( \bin folder )


2. Decompile it


3. Go to ExternalPreferences.apk decompiled folder: ...\smali\com\android\systemui\statusbar\phone\


4. Copy PhoneStatusBar$MyExternalPreferencesObserver.smali file and paste it under SystemUI.apk respective folder, than you will get something like this file structure:
Code:
PhoneStatusBar$FastColorDrawable.smali
PhoneStatusBar$H.smali
[COLOR="Red"]PhoneStatusBar$MyExternalPreferencesObserver.smali[/COLOR]
PhoneStatusBar$MyTicker.smali
PhoneStatusBar.smali


5. While on SystemUI.apk folder, open PhoneStatusBar.smali file (with notepad++)


6. Let's implement our observer class under annotations MemberClasses (in red)
Code:
# annotations
.annotation system Ldalvik/annotation/MemberClasses;
    value = {
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$FastColorDrawable;[COLOR="Red"],[/COLOR]
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyTicker;[COLOR="red"],[/COLOR]
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$H;[COLOR="red"],[/COLOR]
        [COLOR="red"]Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;[/COLOR]
    }
.end annotation
Obs.: JUST last item has no , (comma) after its name!

Now let's copy our three new methods from ExternalPreferences.apk (PhoneStatusBar.smali) file to SystemUI.apk (PhoneStatusBar.smali file)
By copying them you will get (in red):

Under # direct methods
Code:
# direct methods
[COLOR="Red"].method private handleStatusBarChangeClockToRed()V
    .locals 7

    .prologue
    .line 127
    iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    invoke-virtual {v3}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v3

    const-string v4, "clock"

    const-string v5, "id"

    iget-object v6, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    invoke-virtual {v6}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v6

    invoke-virtual {v3, v4, v5, v6}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I

    move-result v1

    .line 128
    .local v1, resId:I
    iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:Landroid/view/View;

    invoke-virtual {v3, v1}, Landroid/view/View;->findViewById(I)Landroid/view/View;

    move-result-object v0

    check-cast v0, Landroid/widget/TextView;

    .line 131
    .local v0, clock:Landroid/widget/TextView;
    iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    invoke-virtual {v3}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v3

    const-string v4, "TextAppearance.StatusBar.Clock"

    const-string v5, "style"

    iget-object v6, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    invoke-virtual {v6}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v6

    invoke-virtual {v3, v4, v5, v6}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I

    move-result v1

    .line 132
    iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    invoke-virtual {v0, v3, v1}, Landroid/widget/TextView;->setTextAppearance(Landroid/content/Context;I)V

    .line 136
    iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    invoke-virtual {v3}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;

    move-result-object v3

    const-string v4, "status_bar_change_clock_to_red"

    const/4 v5, 0x0

    invoke-static {v3, v4, v5}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I

    move-result v2

    .line 137
    .local v2, value:I
    const/4 v3, 0x1

    if-ne v2, v3, :cond_0

    .line 140
    const/high16 v3, -0x1

    invoke-virtual {v0, v3}, Landroid/widget/TextView;->setTextColor(I)V

    .line 143
    :cond_0
    return-void
.end method

.method private setupExternalSettingsObserver()V
    .locals 5

    .prologue
    .line 44
    new-instance v1, Ljava/util/LinkedList;

    invoke-direct {v1}, Ljava/util/LinkedList;-><init>()V

    .line 47
    .local v1, list:Ljava/util/List;,"Ljava/util/List<Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;>;"
    new-instance v2, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;

    iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mHandler:Landroid/os/Handler;

    const-string v4, "status_bar_change_clock_to_red"

    invoke-static {v4}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;

    move-result-object v4

    invoke-direct {v2, p0, v3, v4}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;-><init>(Lcom/android/systemui/statusbar/phone/PhoneStatusBar;Landroid/os/Handler;Landroid/net/Uri;)V

    invoke-interface {v1, v2}, Ljava/util/List;->add(Ljava/lang/Object;)Z

    .line 60
    invoke-interface {v1}, Ljava/util/List;->iterator()Ljava/util/Iterator;

    move-result-object v0

    .line 61
    .local v0, iterator:Ljava/util/Iterator;
    :goto_0
    invoke-interface {v0}, Ljava/util/Iterator;->hasNext()Z

    move-result v2

    if-nez v2, :cond_0

    .line 67
    return-void

    .line 64
    :cond_0
    invoke-interface {v0}, Ljava/util/Iterator;->next()Ljava/lang/Object;

    move-result-object v2

    check-cast v2, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;

    invoke-virtual {v2}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;->observe()V

    goto :goto_0
.end method[/COLOR]

.method public constructor <init>()V
    .locals 5

    .prologue
    const/4 v4, 0x2

    const/4 v3, -0x1

    const/4 v0, 0x0

    const/4 v2, 0x0

    .line 140
    invoke-direct {p0}, Lcom/android/systemui/statusbar/BaseStatusBar;-><init>()V
.
.
.

Under # virtual methods
Code:
# virtual methods
[COLOR="Red"].method public externalPreferencesObserverCallback(Landroid/net/Uri;)V
    .locals 1
    .parameter "uri"

    .prologue
    .line 76
    const-string v0, "status_bar_change_clock_to_red"

    invoke-static {v0}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;

    move-result-object v0

    invoke-virtual {p1, v0}, Landroid/net/Uri;->equals(Ljava/lang/Object;)Z

    move-result v0

    if-eqz v0, :cond_0

    .line 79
    invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->handleStatusBarChangeClockToRed()V

    .line 115
    :cond_0
    return-void
.end method[/COLOR]

.method public addIcon(Ljava/lang/String;IILcom/android/internal/statusbar/StatusBarIcon;)V
    .locals 5
    .parameter "slot"
    .parameter "index"
    .parameter "viewIndex"
    .parameter "icon"

    .prologue
    .line 1323
    new-instance v0, Lcom/android/systemui/statusbar/StatusBarIconView;

    iget-object v1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    const/4 v2, 0x0

    invoke-direct {v0, v1, p1, v2}, Lcom/android/systemui/statusbar/StatusBarIconView;-><init>(Landroid/content/Context;Ljava/lang/String;Landroid/app/Notification;)V
.
.
.

Before going on, we need to fix some stuff within our new methods (just within them) due diffs from our Java "clone" class and real one!!

From (red):
Code:
    iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:[COLOR="red"]Landroid/view/View;[/COLOR]

    invoke-virtual {v3, v1}, [COLOR="red"]Landroid/view/View;[/COLOR]->findViewById(I)Landroid/view/View;

To blue:
Code:
    iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:[COLOR="blue"]Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;[/COLOR]

    invoke-virtual {v3, v1}, [COLOR="blue"]Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;[/COLOR]->findViewById(I)Landroid/view/View;

Pay attention on mContext field too!!


7. While on SystemUI.apk look for this method:
Code:
.method protected makeStatusBarView()Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;


8. Found, now look for its return-object line (in blue), something like (yours can be tottaly different from mine, but return-object is there!!):
Code:
    .line 1005
    const-string v0, "com.sonymobile.notes.NEW_SKETCH"

    invoke-direct {p0, v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->isAppInstalled(Ljava/lang/String;)Z

    move-result v0

    iput-boolean v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mRightVisible:Z
	
    .line 1007
    iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;

    [B][COLOR="Blue"]return-object[/COLOR][/B] v0

    :cond_14
    move v1, v2

    .line 825
    goto/16 :goto_7


9. Found, now let's implement "calls" to our setup and handle methods (in red)
Code:
    .line 1005
    const-string v0, "com.sonymobile.notes.NEW_SKETCH"

    invoke-direct {p0, v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->isAppInstalled(Ljava/lang/String;)Z

    move-result v0

    iput-boolean v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mRightVisible:Z
	
    [COLOR="Red"].line 34
    invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setupExternalSettingsObserver()V

    .line 37
    invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->handleStatusBarChangeClockToRed()V[/COLOR]
	
    .line 1007
    iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;

    [B][COLOR="Blue"]return-object[/COLOR][/B] v0

    :cond_14
    move v1, v2

    .line 825
    goto/16 :goto_7
- First "call" setup our Content Observer preference key list!
- Second "call" ensures that clock text color will be red if preference enabled (just after boot)!


10. Double check your changes, save everything, compile your modified SystemUI.apk and... done!! ;)


11. Don't forget to check out 3th post for new mods in which you can complement your project!!



Known issues:
You tell me!!



To do:
You tell me too!!



Special thanks: (if I forgot someone, please remember me!!)
- Sony
- @poria1999 for the encouragement (I blame you by this guide)



If you like it, press thanks... Simple so!! ;)
.
.
 

Attachments

  • red_clock_720p.zip
    481.1 KB · Views: 282
  • ExternalPreferences_Eclipse_Project.zip
    1.2 MB · Views: 521
  • before_and_after_changes_PhoneStatusBar.smali.zip
    75.2 KB · Views: 266
Last edited:

serajr

Recognized Developer / Recognized Themer
Apr 21, 2011
5,022
18,617
São Paulo - SP
New mods...

Here I'm gonna try to show you other mods you can try!!


Change Battery Icons Guide

attachment.php


1. First you need to put new battery resources within your decompiled SystemUI.apk


2. Go to \res\drawable folder and look for:
Code:
stat_sys_battery.xml
stat_sys_battery_charge.xml


3. Found, these two xml files are where all respective png's are mapped!
Let's name them as our "default" preference value (gonna be 0), so we do nothing with them


4. While at \res\drawable folder, create (CTRL+C and CTRL+V) two new files based on above ones, you will get (in red):
Code:
stat_sys_battery.xml
[COLOR="Red"]stat_sys_battery_1.xml[/COLOR]
stat_sys_battery_charge.xml
[COLOR="red"]stat_sys_battery_charge_1.xml[/COLOR]
New red files gonna be our value 1 preference


5. By editing new red files above, you will get something like this:
Code:
<?xml version="1.0" encoding="utf-8"?>
<level-list
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/stat_sys_battery_0" android:maxLevel="4" />
    <item android:drawable="@drawable/stat_sys_battery_15" android:maxLevel="15" />
    <item android:drawable="@drawable/stat_sys_battery_28" android:maxLevel="35" />
    <item android:drawable="@drawable/stat_sys_battery_43" android:maxLevel="49" />
    <item android:drawable="@drawable/stat_sys_battery_57" android:maxLevel="60" />
    <item android:drawable="@drawable/stat_sys_battery_71" android:maxLevel="75" />
    <item android:drawable="@drawable/stat_sys_battery_85" android:maxLevel="90" />
    <item android:drawable="@drawable/stat_sys_battery_100" android:maxLevel="100" />
</level-list>


6. Here you need to change the drawables mapping to your new battery png's you put within your \res\drawable\YOUR_DENSITY folder:
E.g.: New png's have _1 suffix!!
Code:
<?xml version="1.0" encoding="utf-8"?>
<level-list
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/stat_sys_battery_0[COLOR="red"]_1[/COLOR]" android:maxLevel="4" />
    <item android:drawable="@drawable/stat_sys_battery_15[COLOR="red"]_1[/COLOR]" android:maxLevel="15" />
    <item android:drawable="@drawable/stat_sys_battery_28[COLOR="red"]_1[/COLOR]" android:maxLevel="35" />
    <item android:drawable="@drawable/stat_sys_battery_43[COLOR="red"]_1[/COLOR]" android:maxLevel="49" />
    <item android:drawable="@drawable/stat_sys_battery_57[COLOR="red"]_1[/COLOR]" android:maxLevel="60" />
    <item android:drawable="@drawable/stat_sys_battery_71[COLOR="red"]_1[/COLOR]" android:maxLevel="75" />
    <item android:drawable="@drawable/stat_sys_battery_85[COLOR="red"]_1[/COLOR]" android:maxLevel="90" />
    <item android:drawable="@drawable/stat_sys_battery_100[COLOR="red"]_1[/COLOR]" android:maxLevel="100" />
</level-list>


7. Done with new resources!!!
Remember you can put as much as new ones you want, just change their suffix to next integer value!!!


Java

- New "clone" com.android.systemui.statusbar.policy package
- New "clone" BatteryController.java class with two new methods and all related comments there too
- Added into "clone" PhoneStatusBar.java the new handleStatusBarChangeBatteryIcons method and its "calls", take a look at:
makeStatusBarView
setupExternalSettingsObserver
externalPreferencesObserverCallback
handleStatusBarChangeBatteryIcons

Get new Eclipse Project from attachments!!


Smali

1. Get the newly built ExternalPreferences.apk from Eclipse project ( \bin folder )


2. Decompile it


3. Go to ExternalPreferences.apk decompiled folder: ...\smali\com\android\systemui\statusbar\phone\


4. Open PhoneStatusBar.smali

Now let's copy our new method from ExternalPreferences.apk (PhoneStatusBar.smali) file to SystemUI.apk (PhoneStatusBar.smali file)
By copying it you will get (in red):

Under # direct methods
Code:
# direct methods
[COLOR="red"].method private handleStatusBarChangeBatteryIcons()V
    .locals 9

    .prologue
    const/4 v8, 0x0

    .line 125
    iget-object v4, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    const/4 v5, 0x0

    new-instance v6, Landroid/content/IntentFilter;

    const-string v7, "android.intent.action.BATTERY_CHANGED"

    invoke-direct {v6, v7}, Landroid/content/IntentFilter;-><init>(Ljava/lang/String;)V

    invoke-virtual {v4, v5, v6}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;

    move-result-object v0

    .line 126
    .local v0, getIntent:Landroid/content/Intent;
    const-string v4, "level"

    invoke-virtual {v0, v4, v8}, Landroid/content/Intent;->getIntExtra(Ljava/lang/String;I)I

    move-result v2

    .line 127
    .local v2, level:I
    const-string v4, "plugged"

    invoke-virtual {v0, v4, v8}, Landroid/content/Intent;->getIntExtra(Ljava/lang/String;I)I

    move-result v3

    .line 131
    .local v3, plugged:I
    new-instance v1, Landroid/content/Intent;

    const-string v4, "android.intent.action.BATTERY_CHANGED"

    invoke-direct {v1, v4}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V

    .line 132
    .local v1, intent:Landroid/content/Intent;
    const-string v4, "level"

    invoke-virtual {v1, v4, v2}, Landroid/content/Intent;->putExtra(Ljava/lang/String;I)Landroid/content/Intent;

    .line 133
    const-string v4, "plugged"

    invoke-virtual {v1, v4, v3}, Landroid/content/Intent;->putExtra(Ljava/lang/String;I)Landroid/content/Intent;

    .line 134
    iget-object v4, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    invoke-virtual {v4, v1}, Landroid/content/Context;->sendBroadcast(Landroid/content/Intent;)V

    .line 136
    return-void
.end method[/COLOR]


5. Also replace setupExternalSettingsObserver and externalPreferencesObserverCallback whole methods by the new ones


6. While on SystemUI.apk look for our last implemented method (from original guide, but now in blue) inside makeStatusBarView method, and add red lines
Code:
    .line 1005
    const-string v0, "com.sonymobile.notes.NEW_SKETCH"

    invoke-direct {p0, v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->isAppInstalled(Ljava/lang/String;)Z

    move-result v0

    iput-boolean v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mRightVisible:Z
	
    [COLOR="Blue"].line 34
    invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setupExternalSettingsObserver()V

    .line 37
    invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->handleStatusBarChangeClockToRed()V[/COLOR]
	
    [COLOR="Red"].line 40
    invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->handleStatusBarChangeBatteryIcons()V[/COLOR]

    .line 1007
    iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;

    return-object v0

    :cond_14
    move v1, v2

    .line 825
    goto/16 :goto_7


7. Go to ExternalPreferences.apk decompiled folder: ...\smali\com\android\systemui\statusbar\policy\


8. Open BatteryController.smali

Now let's copy our new methods from ExternalPreferences.apk (BatteryController.smali) file to SystemUI.apk (BatteryController.smali file)
By copying them you will get (in red):

Under # direct methods
Code:
# direct methods
[COLOR="Red"].method private getStatSysBatteryChargeResId()I
    .locals 6

    .prologue
    .line 62
    iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v2

    const-string v3, "stat_sys_battery_charge"

    const-string v4, "drawable"

    iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v5}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v5

    invoke-virtual {v2, v3, v4, v5}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I

    move-result v0

    .line 65
    .local v0, resId:I
    iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v2}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;

    move-result-object v2

    const-string v3, "status_bar_change_battery_icons"

    const/4 v4, 0x0

    invoke-static {v2, v3, v4}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I

    move-result v1

    .line 66
    .local v1, value:I
    packed-switch v1, :pswitch_data_0

    .line 77
    :goto_0
    return v0

    .line 71
    :pswitch_0
    iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v2

    const-string v3, "stat_sys_battery_charge_1"

    const-string v4, "drawable"

    iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v5}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v5

    invoke-virtual {v2, v3, v4, v5}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I

    move-result v0

    goto :goto_0

    .line 66
    :pswitch_data_0
    .packed-switch 0x1
        :pswitch_0
    .end packed-switch
.end method

.method private getStatSysBatteryResId()I
    .locals 6

    .prologue
    .line 36
    iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v2

    const-string v3, "stat_sys_battery"

    const-string v4, "drawable"

    iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v5}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v5

    invoke-virtual {v2, v3, v4, v5}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I

    move-result v0

    .line 39
    .local v0, resId:I
    iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v2}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;

    move-result-object v2

    const-string v3, "status_bar_change_battery_icons"

    const/4 v4, 0x0

    invoke-static {v2, v3, v4}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I

    move-result v1

    .line 40
    .local v1, value:I
    packed-switch v1, :pswitch_data_0

    .line 51
    :goto_0
    return v0

    .line 45
    :pswitch_0
    iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v2

    const-string v3, "stat_sys_battery_1"

    const-string v4, "drawable"

    iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v5}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v5

    invoke-virtual {v2, v3, v4, v5}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I

    move-result v0

    goto :goto_0

    .line 40
    :pswitch_data_0
    .packed-switch 0x1
        :pswitch_0
    .end packed-switch
.end method[/COLOR]


9. While on SystemUI.apk BatteryController.smali file look for this method:
Code:
.method public onReceive(Landroid/content/Context;Landroid/content/Intent;)V


9. Found, now let's implement "calls" to our new "get" methods (in red)
Pay attention on v6 (in green), method must return as v6 (or the v? from your decompiled code)
Code:
.
.
.
    .line 117
    .end local v8           #plugType:I
    :cond_1
    :goto_1
    if-eqz v9, :cond_3

    const [COLOR="SeaGreen"]v6[/COLOR], 0x7f020130

    [COLOR="red"]invoke-direct {p0}, Lcom/android/systemui/statusbar/policy/BatteryController;->getStatSysBatteryChargeResId()I

    move-result [COLOR="SeaGreen"]v6[/COLOR][/COLOR]

    .line 120
    .local [COLOR="SeaGreen"]v6[/COLOR], icon:I
    :goto_2
    move-object/from16 v0, p0

    iget-object v13, v0, Lcom/android/systemui/statusbar/policy/BatteryController;->mIconViews:Ljava/util/ArrayList;

    invoke-virtual {v13}, Ljava/util/ArrayList;->size()I

    move-result v1
.
.
.


.
.
.
    .line 117
    .end local v8           #plugType:I
    :cond_3
    const [COLOR="green"]v6[/COLOR], 0x7f020127
	
    [COLOR="Red"]invoke-direct {p0}, Lcom/android/systemui/statusbar/policy/BatteryController;->getStatSysBatteryResId()I

    move-result [COLOR="SeaGreen"]v6[/COLOR][/COLOR]

    goto :goto_2

    .line 128
    .restart local v1       #N:I
    .restart local v4       #i:I
    .restart local v6       #icon:I
.
.
.
0x7f020130 is the hex value from original stat_sys_battery_charge resource (under SystemUI.apk public.xml)
0x7f020127 is the hex value from original stat_sys_battery resource (under SystemUI.apk public.xml)
Your values may differ!!!


10. Double check your changes, save everything, compile your modified SystemUI.apk and... done!!



Others soon...
.
.
 

Attachments

  • java_eclipse_01.png
    java_eclipse_01.png
    142.8 KB · Views: 20,261
  • red_clock_1.jpg
    red_clock_1.jpg
    37.6 KB · Views: 20,339
  • red_clock_2.jpg
    red_clock_2.jpg
    38.1 KB · Views: 20,252
  • java_eclipse_02.png
    java_eclipse_02.png
    162.4 KB · Views: 19,843
  • ExternalPreferences_ChangeBatteryIcons_Eclipse_Project.zip
    1.4 MB · Views: 268
  • change_battery_icons.jpg
    change_battery_icons.jpg
    54.3 KB · Views: 16,518
Last edited:
F

Fragmentos

Guest
Glad That Im the first person Who says Thank you!
Thanks button is not enough.... :D

Sent from my LT18i using Tapatalk 2
 

serajr

Recognized Developer / Recognized Themer
Apr 21, 2011
5,022
18,617
São Paulo - SP
No words can say how I'm feeling now, I've been searching for a tutorial on how to work with smali and SystemUI.apk, and know I found it by you, the Xperia man. Thanks a lot.

Hi bro... The guide covers just a very small portion in what we can do there, but I think it is a good start to people that want to learn something new (like you) and later say: I did it! Enjoy it !!
 
Last edited:
  • Like
Reactions: DsvCdsSoftware

_that

Recognized Developer / Recognized Contributor
Oct 2, 2012
4,817
4,205
I couldn't care less about a red status bar clock and I don't know if I'm ever going to use this, but this is exactly the kind of post that I'd like to see on xda-developers. :good:
 
  • Like
Reactions: serajr

fernando sor

Inactive Recognized Themer
Sep 7, 2010
9,742
5,640
9
north of the wall
|Pay attention on mContext field too!!

can you explain this? Do those need changed also? Getting fc on systemUI so Im looking at everything.

Really clever mod.


EDIT : ALL GOOD. we actually found an alternative method but this put us on the right track.
 
Last edited:
  • Like
Reactions: serajr

serajr

Recognized Developer / Recognized Themer
Apr 21, 2011
5,022
18,617
São Paulo - SP
|Pay attention on mContext field too!!

can you explain this? Do those need changed also? Getting fc on systemUI so Im looking at everything.

Really clever mod.


EDIT : ALL GOOD. we actually found an alternative method but this put us on the right track.
Great... so have you found its diffs by yourself?
Let me know about your app and how did guide helped you!! Thanks...
 

mohawk97

Senior Member
Mar 25, 2014
60
55
Perak
Sir Can You Add mod

Here I'm gonna try to show you other mods you can try!!


Change Battery Icons Guide

attachment.php


1. First you need to put new battery resources within your decompiled SystemUI.apk


2. Go to \res\drawable folder and look for:
Code:
stat_sys_battery.xml
stat_sys_battery_charge.xml


3. Found, these two xml files are where all respective png's are mapped!
Let's name them as our "default" preference value (gonna be 0), so we do nothing with them


4. While at \res\drawable folder, create (CTRL+C and CTRL+V) two new files based on above ones, you will get (in red):
Code:
stat_sys_battery.xml
[COLOR="Red"]stat_sys_battery_1.xml[/COLOR]
stat_sys_battery_charge.xml
[COLOR="red"]stat_sys_battery_charge_1.xml[/COLOR]
New red files gonna be our value 1 preference


5. By editing new red files above, you will get something like this:
Code:
<?xml version="1.0" encoding="utf-8"?>
<level-list
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/stat_sys_battery_0" android:maxLevel="4" />
    <item android:drawable="@drawable/stat_sys_battery_15" android:maxLevel="15" />
    <item android:drawable="@drawable/stat_sys_battery_28" android:maxLevel="35" />
    <item android:drawable="@drawable/stat_sys_battery_43" android:maxLevel="49" />
    <item android:drawable="@drawable/stat_sys_battery_57" android:maxLevel="60" />
    <item android:drawable="@drawable/stat_sys_battery_71" android:maxLevel="75" />
    <item android:drawable="@drawable/stat_sys_battery_85" android:maxLevel="90" />
    <item android:drawable="@drawable/stat_sys_battery_100" android:maxLevel="100" />
</level-list>


6. Here you need to change the drawables mapping to your new battery png's you put within your \res\drawable\YOUR_DENSITY folder:
E.g.: New png's have _1 suffix!!
Code:
<?xml version="1.0" encoding="utf-8"?>
<level-list
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/stat_sys_battery_0[COLOR="red"]_1[/COLOR]" android:maxLevel="4" />
    <item android:drawable="@drawable/stat_sys_battery_15[COLOR="red"]_1[/COLOR]" android:maxLevel="15" />
    <item android:drawable="@drawable/stat_sys_battery_28[COLOR="red"]_1[/COLOR]" android:maxLevel="35" />
    <item android:drawable="@drawable/stat_sys_battery_43[COLOR="red"]_1[/COLOR]" android:maxLevel="49" />
    <item android:drawable="@drawable/stat_sys_battery_57[COLOR="red"]_1[/COLOR]" android:maxLevel="60" />
    <item android:drawable="@drawable/stat_sys_battery_71[COLOR="red"]_1[/COLOR]" android:maxLevel="75" />
    <item android:drawable="@drawable/stat_sys_battery_85[COLOR="red"]_1[/COLOR]" android:maxLevel="90" />
    <item android:drawable="@drawable/stat_sys_battery_100[COLOR="red"]_1[/COLOR]" android:maxLevel="100" />
</level-list>


7. Done with new resources!!!
Remember you can put as much as new ones you want, just change their suffix to next integer value!!!


Java

- New "clone" com.android.systemui.statusbar.policy package
- New "clone" BatteryController.java class with two new methods and all related comments there too
- Added into "clone" PhoneStatusBar.java the new handleStatusBarChangeBatteryIcons method and its "calls", take a look at:


Get new Eclipse Project from attachments!!


Smali

1. Get the newly built ExternalPreferences.apk from Eclipse project ( \bin folder )


2. Decompile it


3. Go to ExternalPreferences.apk decompiled folder: ...\smali\com\android\systemui\statusbar\phone\


4. Open PhoneStatusBar.smali

Now let's copy our new method from ExternalPreferences.apk (PhoneStatusBar.smali) file to SystemUI.apk (PhoneStatusBar.smali file)
By copying it you will get (in red):

Under # direct methods
Code:
# direct methods
[COLOR="red"].method private handleStatusBarChangeBatteryIcons()V
    .locals 9

    .prologue
    const/4 v8, 0x0

    .line 125
    iget-object v4, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    const/4 v5, 0x0

    new-instance v6, Landroid/content/IntentFilter;

    const-string v7, "android.intent.action.BATTERY_CHANGED"

    invoke-direct {v6, v7}, Landroid/content/IntentFilter;-><init>(Ljava/lang/String;)V

    invoke-virtual {v4, v5, v6}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;

    move-result-object v0

    .line 126
    .local v0, getIntent:Landroid/content/Intent;
    const-string v4, "level"

    invoke-virtual {v0, v4, v8}, Landroid/content/Intent;->getIntExtra(Ljava/lang/String;I)I

    move-result v2

    .line 127
    .local v2, level:I
    const-string v4, "plugged"

    invoke-virtual {v0, v4, v8}, Landroid/content/Intent;->getIntExtra(Ljava/lang/String;I)I

    move-result v3

    .line 131
    .local v3, plugged:I
    new-instance v1, Landroid/content/Intent;

    const-string v4, "android.intent.action.BATTERY_CHANGED"

    invoke-direct {v1, v4}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V

    .line 132
    .local v1, intent:Landroid/content/Intent;
    const-string v4, "level"

    invoke-virtual {v1, v4, v2}, Landroid/content/Intent;->putExtra(Ljava/lang/String;I)Landroid/content/Intent;

    .line 133
    const-string v4, "plugged"

    invoke-virtual {v1, v4, v3}, Landroid/content/Intent;->putExtra(Ljava/lang/String;I)Landroid/content/Intent;

    .line 134
    iget-object v4, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;

    invoke-virtual {v4, v1}, Landroid/content/Context;->sendBroadcast(Landroid/content/Intent;)V

    .line 136
    return-void
.end method[/COLOR]


5. Also replace setupExternalSettingsObserver and externalPreferencesObserverCallback whole methods by the new ones


6. While on SystemUI.apk look for our last implemented method (from original guide, but now in blue) inside makeStatusBarView method, and add red lines
Code:
    .line 1005
    const-string v0, "com.sonymobile.notes.NEW_SKETCH"

    invoke-direct {p0, v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->isAppInstalled(Ljava/lang/String;)Z

    move-result v0

    iput-boolean v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mRightVisible:Z
	
    [COLOR="Blue"].line 34
    invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setupExternalSettingsObserver()V

    .line 37
    invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->handleStatusBarChangeClockToRed()V[/COLOR]
	
    [COLOR="Red"].line 40
    invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->handleStatusBarChangeBatteryIcons()V[/COLOR]

    .line 1007
    iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;

    return-object v0

    :cond_14
    move v1, v2

    .line 825
    goto/16 :goto_7


7. Go to ExternalPreferences.apk decompiled folder: ...\smali\com\android\systemui\statusbar\policy\


8. Open BatteryController.smali

Now let's copy our new methods from ExternalPreferences.apk (BatteryController.smali) file to SystemUI.apk (BatteryController.smali file)
By copying them you will get (in red):

Under # direct methods
Code:
# direct methods
[COLOR="Red"].method private getStatSysBatteryChargeResId()I
    .locals 6

    .prologue
    .line 62
    iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v2

    const-string v3, "stat_sys_battery_charge"

    const-string v4, "drawable"

    iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v5}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v5

    invoke-virtual {v2, v3, v4, v5}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I

    move-result v0

    .line 65
    .local v0, resId:I
    iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v2}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;

    move-result-object v2

    const-string v3, "status_bar_change_battery_icons"

    const/4 v4, 0x0

    invoke-static {v2, v3, v4}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I

    move-result v1

    .line 66
    .local v1, value:I
    packed-switch v1, :pswitch_data_0

    .line 77
    :goto_0
    return v0

    .line 71
    :pswitch_0
    iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v2

    const-string v3, "stat_sys_battery_charge_1"

    const-string v4, "drawable"

    iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v5}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v5

    invoke-virtual {v2, v3, v4, v5}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I

    move-result v0

    goto :goto_0

    .line 66
    :pswitch_data_0
    .packed-switch 0x1
        :pswitch_0
    .end packed-switch
.end method

.method private getStatSysBatteryResId()I
    .locals 6

    .prologue
    .line 36
    iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v2

    const-string v3, "stat_sys_battery"

    const-string v4, "drawable"

    iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v5}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v5

    invoke-virtual {v2, v3, v4, v5}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I

    move-result v0

    .line 39
    .local v0, resId:I
    iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v2}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;

    move-result-object v2

    const-string v3, "status_bar_change_battery_icons"

    const/4 v4, 0x0

    invoke-static {v2, v3, v4}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I

    move-result v1

    .line 40
    .local v1, value:I
    packed-switch v1, :pswitch_data_0

    .line 51
    :goto_0
    return v0

    .line 45
    :pswitch_0
    iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;

    move-result-object v2

    const-string v3, "stat_sys_battery_1"

    const-string v4, "drawable"

    iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;

    invoke-virtual {v5}, Landroid/content/Context;->getPackageName()Ljava/lang/String;

    move-result-object v5

    invoke-virtual {v2, v3, v4, v5}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I

    move-result v0

    goto :goto_0

    .line 40
    :pswitch_data_0
    .packed-switch 0x1
        :pswitch_0
    .end packed-switch
.end method[/COLOR]


9. While on SystemUI.apk BatteryController.smali file look for this method:
Code:
.method public onReceive(Landroid/content/Context;Landroid/content/Intent;)V


9. Found, now let's implement "calls" to our new "get" methods (in red)
Pay attention on v6 (in green), method must return as v6 (or the v? from your decompiled code)
Code:
.
.
.
    .line 117
    .end local v8           #plugType:I
    :cond_1
    :goto_1
    if-eqz v9, :cond_3

    const [COLOR="SeaGreen"]v6[/COLOR], 0x7f020130

    [COLOR="red"]invoke-direct {p0}, Lcom/android/systemui/statusbar/policy/BatteryController;->getStatSysBatteryChargeResId()I

    move-result [COLOR="SeaGreen"]v6[/COLOR][/COLOR]

    .line 120
    .local [COLOR="SeaGreen"]v6[/COLOR], icon:I
    :goto_2
    move-object/from16 v0, p0

    iget-object v13, v0, Lcom/android/systemui/statusbar/policy/BatteryController;->mIconViews:Ljava/util/ArrayList;

    invoke-virtual {v13}, Ljava/util/ArrayList;->size()I

    move-result v1
.
.
.


.
.
.
    .line 117
    .end local v8           #plugType:I
    :cond_3
    const [COLOR="green"]v6[/COLOR], 0x7f020127
	
    [COLOR="Red"]invoke-direct {p0}, Lcom/android/systemui/statusbar/policy/BatteryController;->getStatSysBatteryResId()I

    move-result [COLOR="SeaGreen"]v6[/COLOR][/COLOR]

    goto :goto_2

    .line 128
    .restart local v1       #N:I
    .restart local v4       #i:I
    .restart local v6       #icon:I
.
.
.
0x7f020130 is the hex value from original stat_sys_battery_charge resource (under SystemUI.apk public.xml)
0x7f020127 is the hex value from original stat_sys_battery resource (under SystemUI.apk public.xml)
Your values may differs!!!


10. Double check your changes, save everything, compile your modified SystemUI.apk and... done!!



Others soon...
.
.



Sir Can You Mode Like Show\Hide Left\Right\Center Carrier Logo?:D
 

Top Liked Posts

  • There are no posts matching your filters.
  • 65
    Hi community!! Here is a complete guide showing you how to create an "External Settings App" to control SystemUI.apk look and feel.
    I have received tons of pm and mentions from users asking me how did I manage such "magic" work into my mods over Xperia's firmware, so I have decided to create this thread to share you "the concept" I've created. I really hope this guide help people to create your own settings apk from scratch, but not just for the SystemUI.apk, but for anyone in which you need/want to control.

    I know that Xposed Framework do the same and also it is the right choice, mine choice too, but the meaning of this thread is: Knowledge exchange!!
    Talking about Xposed Framework, here is my module to Xperia devices.

    Back to topic...

    First of all, a brief feedback about my mods over xda that use concept you will see:
    - Serajr Swiping Power Toggles - SystemUI
    - Xperia SystemUI + 23 JB Toggles + Sliders + Apps
    - Xperia GX Home Launcher for All Xperias (Multi-Resolution)



    Let's do it!! ;)

    Requirements:
    - Java programming skills (I'M NOT GOING TO SHOW HOW TO BUILD APPS OUTSIDE THREAD CONTEXT, NEITHER HOW TO DEVELOP ON THAT PLATFORM)
    - Apktool decompile/compile skills (I'M NOT GOING TO SHOW HOW DO DO THAT)
    - Logcat (in case you face any FC)

    My lab:
    - Windows 7 x64
    - Eclipse
    - Android SDK
    - Java
    - Apktool

    My precious:
    - Sony Xperia ZQ
    - JB 4.3



    External Settings App:

    It has a very simple ui and code, with a single CheckBoxPreference!
    Don't mind about deprecated functions, they are there purposely to make the simplest possible code. We know that the right choice for preferences is PreferenceFragment.

    attachment.php
    attachment.php




    Java - External Settings App - Eclipse Project:

    MainActivity.java
    Every field and method contents is commented on for better understanding, but here, what really metters is:
    Save current preference value to Settings.System

    attachment.php


    The app needs to have proper permission to write there, and the right one is:
    Code:
    <uses-permission android:name="android.permission.WRITE_SETTINGS"/>

    To make things easier in the future, I've created a "clone" PhoneStatusBar.java class with full package path too, and within it are all related code that "does the magic" (I'll explain every method further). This class has no function over our settings app context (NEVER INSTANTIATE IT), it is there just to allow us to write our SystemUI modifications in Java and get the Smali easily!!!

    Take a look:
    attachment.php




    PHP:
    makeStatusBarView()
    Here is where SystemUI.apk creates all its contents, so we need to call our setup and handle methods here too.


    PHP:
    setupExternalSettingsObserver()
    Here we setup our content observer (preferences keys we created in our settings app).


    PHP:
    externalPreferencesObserverCallback(Uri uri)
    Here we filter which preference key has changed its state and do proper changes.


    PHP:
    handleStatusBarChangeClockToRed()
    Here we set the status bar clock text color according current preference state.


    PHP:
    private class MyExternalPreferencesObserver extends ContentObserver
    I've also created a inner class that will store our preferences keys Uri's to later pass changed ones to the callback method!



    That´s it!!
    Now we need to go deep into the "necessary evil" titled: smali !!

    1. Get the newly built ExternalPreferences.apk from Eclipse project ( \bin folder )


    2. Decompile it


    3. Go to ExternalPreferences.apk decompiled folder: ...\smali\com\android\systemui\statusbar\phone\


    4. Copy PhoneStatusBar$MyExternalPreferencesObserver.smali file and paste it under SystemUI.apk respective folder, than you will get something like this file structure:
    Code:
    PhoneStatusBar$FastColorDrawable.smali
    PhoneStatusBar$H.smali
    [COLOR="Red"]PhoneStatusBar$MyExternalPreferencesObserver.smali[/COLOR]
    PhoneStatusBar$MyTicker.smali
    PhoneStatusBar.smali


    5. While on SystemUI.apk folder, open PhoneStatusBar.smali file (with notepad++)


    6. Let's implement our observer class under annotations MemberClasses (in red)
    Code:
    # annotations
    .annotation system Ldalvik/annotation/MemberClasses;
        value = {
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$FastColorDrawable;[COLOR="Red"],[/COLOR]
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyTicker;[COLOR="red"],[/COLOR]
            Lcom/android/systemui/statusbar/phone/PhoneStatusBar$H;[COLOR="red"],[/COLOR]
            [COLOR="red"]Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;[/COLOR]
        }
    .end annotation
    Obs.: JUST last item has no , (comma) after its name!

    Now let's copy our three new methods from ExternalPreferences.apk (PhoneStatusBar.smali) file to SystemUI.apk (PhoneStatusBar.smali file)
    By copying them you will get (in red):

    Under # direct methods
    Code:
    # direct methods
    [COLOR="Red"].method private handleStatusBarChangeClockToRed()V
        .locals 7
    
        .prologue
        .line 127
        iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        invoke-virtual {v3}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;
    
        move-result-object v3
    
        const-string v4, "clock"
    
        const-string v5, "id"
    
        iget-object v6, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        invoke-virtual {v6}, Landroid/content/Context;->getPackageName()Ljava/lang/String;
    
        move-result-object v6
    
        invoke-virtual {v3, v4, v5, v6}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
    
        move-result v1
    
        .line 128
        .local v1, resId:I
        iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:Landroid/view/View;
    
        invoke-virtual {v3, v1}, Landroid/view/View;->findViewById(I)Landroid/view/View;
    
        move-result-object v0
    
        check-cast v0, Landroid/widget/TextView;
    
        .line 131
        .local v0, clock:Landroid/widget/TextView;
        iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        invoke-virtual {v3}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;
    
        move-result-object v3
    
        const-string v4, "TextAppearance.StatusBar.Clock"
    
        const-string v5, "style"
    
        iget-object v6, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        invoke-virtual {v6}, Landroid/content/Context;->getPackageName()Ljava/lang/String;
    
        move-result-object v6
    
        invoke-virtual {v3, v4, v5, v6}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
    
        move-result v1
    
        .line 132
        iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        invoke-virtual {v0, v3, v1}, Landroid/widget/TextView;->setTextAppearance(Landroid/content/Context;I)V
    
        .line 136
        iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        invoke-virtual {v3}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
    
        move-result-object v3
    
        const-string v4, "status_bar_change_clock_to_red"
    
        const/4 v5, 0x0
    
        invoke-static {v3, v4, v5}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
    
        move-result v2
    
        .line 137
        .local v2, value:I
        const/4 v3, 0x1
    
        if-ne v2, v3, :cond_0
    
        .line 140
        const/high16 v3, -0x1
    
        invoke-virtual {v0, v3}, Landroid/widget/TextView;->setTextColor(I)V
    
        .line 143
        :cond_0
        return-void
    .end method
    
    .method private setupExternalSettingsObserver()V
        .locals 5
    
        .prologue
        .line 44
        new-instance v1, Ljava/util/LinkedList;
    
        invoke-direct {v1}, Ljava/util/LinkedList;-><init>()V
    
        .line 47
        .local v1, list:Ljava/util/List;,"Ljava/util/List<Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;>;"
        new-instance v2, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;
    
        iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mHandler:Landroid/os/Handler;
    
        const-string v4, "status_bar_change_clock_to_red"
    
        invoke-static {v4}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
    
        move-result-object v4
    
        invoke-direct {v2, p0, v3, v4}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;-><init>(Lcom/android/systemui/statusbar/phone/PhoneStatusBar;Landroid/os/Handler;Landroid/net/Uri;)V
    
        invoke-interface {v1, v2}, Ljava/util/List;->add(Ljava/lang/Object;)Z
    
        .line 60
        invoke-interface {v1}, Ljava/util/List;->iterator()Ljava/util/Iterator;
    
        move-result-object v0
    
        .line 61
        .local v0, iterator:Ljava/util/Iterator;
        :goto_0
        invoke-interface {v0}, Ljava/util/Iterator;->hasNext()Z
    
        move-result v2
    
        if-nez v2, :cond_0
    
        .line 67
        return-void
    
        .line 64
        :cond_0
        invoke-interface {v0}, Ljava/util/Iterator;->next()Ljava/lang/Object;
    
        move-result-object v2
    
        check-cast v2, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;
    
        invoke-virtual {v2}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;->observe()V
    
        goto :goto_0
    .end method[/COLOR]
    
    .method public constructor <init>()V
        .locals 5
    
        .prologue
        const/4 v4, 0x2
    
        const/4 v3, -0x1
    
        const/4 v0, 0x0
    
        const/4 v2, 0x0
    
        .line 140
        invoke-direct {p0}, Lcom/android/systemui/statusbar/BaseStatusBar;-><init>()V
    .
    .
    .

    Under # virtual methods
    Code:
    # virtual methods
    [COLOR="Red"].method public externalPreferencesObserverCallback(Landroid/net/Uri;)V
        .locals 1
        .parameter "uri"
    
        .prologue
        .line 76
        const-string v0, "status_bar_change_clock_to_red"
    
        invoke-static {v0}, Landroid/provider/Settings$System;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
    
        move-result-object v0
    
        invoke-virtual {p1, v0}, Landroid/net/Uri;->equals(Ljava/lang/Object;)Z
    
        move-result v0
    
        if-eqz v0, :cond_0
    
        .line 79
        invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->handleStatusBarChangeClockToRed()V
    
        .line 115
        :cond_0
        return-void
    .end method[/COLOR]
    
    .method public addIcon(Ljava/lang/String;IILcom/android/internal/statusbar/StatusBarIcon;)V
        .locals 5
        .parameter "slot"
        .parameter "index"
        .parameter "viewIndex"
        .parameter "icon"
    
        .prologue
        .line 1323
        new-instance v0, Lcom/android/systemui/statusbar/StatusBarIconView;
    
        iget-object v1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        const/4 v2, 0x0
    
        invoke-direct {v0, v1, p1, v2}, Lcom/android/systemui/statusbar/StatusBarIconView;-><init>(Landroid/content/Context;Ljava/lang/String;Landroid/app/Notification;)V
    .
    .
    .

    Before going on, we need to fix some stuff within our new methods (just within them) due diffs from our Java "clone" class and real one!!

    From (red):
    Code:
        iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:[COLOR="red"]Landroid/view/View;[/COLOR]
    
        invoke-virtual {v3, v1}, [COLOR="red"]Landroid/view/View;[/COLOR]->findViewById(I)Landroid/view/View;

    To blue:
    Code:
        iget-object v3, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:[COLOR="blue"]Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;[/COLOR]
    
        invoke-virtual {v3, v1}, [COLOR="blue"]Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;[/COLOR]->findViewById(I)Landroid/view/View;

    Pay attention on mContext field too!!


    7. While on SystemUI.apk look for this method:
    Code:
    .method protected makeStatusBarView()Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;


    8. Found, now look for its return-object line (in blue), something like (yours can be tottaly different from mine, but return-object is there!!):
    Code:
        .line 1005
        const-string v0, "com.sonymobile.notes.NEW_SKETCH"
    
        invoke-direct {p0, v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->isAppInstalled(Ljava/lang/String;)Z
    
        move-result v0
    
        iput-boolean v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mRightVisible:Z
    	
        .line 1007
        iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;
    
        [B][COLOR="Blue"]return-object[/COLOR][/B] v0
    
        :cond_14
        move v1, v2
    
        .line 825
        goto/16 :goto_7


    9. Found, now let's implement "calls" to our setup and handle methods (in red)
    Code:
        .line 1005
        const-string v0, "com.sonymobile.notes.NEW_SKETCH"
    
        invoke-direct {p0, v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->isAppInstalled(Ljava/lang/String;)Z
    
        move-result v0
    
        iput-boolean v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mRightVisible:Z
    	
        [COLOR="Red"].line 34
        invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setupExternalSettingsObserver()V
    
        .line 37
        invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->handleStatusBarChangeClockToRed()V[/COLOR]
    	
        .line 1007
        iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;
    
        [B][COLOR="Blue"]return-object[/COLOR][/B] v0
    
        :cond_14
        move v1, v2
    
        .line 825
        goto/16 :goto_7
    - First "call" setup our Content Observer preference key list!
    - Second "call" ensures that clock text color will be red if preference enabled (just after boot)!


    10. Double check your changes, save everything, compile your modified SystemUI.apk and... done!! ;)


    11. Don't forget to check out 3th post for new mods in which you can complement your project!!



    Known issues:
    You tell me!!



    To do:
    You tell me too!!



    Special thanks: (if I forgot someone, please remember me!!)
    - Sony
    - @poria1999 for the encouragement (I blame you by this guide)



    If you like it, press thanks... Simple so!! ;)
    .
    .
    15
    New mods...

    Here I'm gonna try to show you other mods you can try!!


    Change Battery Icons Guide

    attachment.php


    1. First you need to put new battery resources within your decompiled SystemUI.apk


    2. Go to \res\drawable folder and look for:
    Code:
    stat_sys_battery.xml
    stat_sys_battery_charge.xml


    3. Found, these two xml files are where all respective png's are mapped!
    Let's name them as our "default" preference value (gonna be 0), so we do nothing with them


    4. While at \res\drawable folder, create (CTRL+C and CTRL+V) two new files based on above ones, you will get (in red):
    Code:
    stat_sys_battery.xml
    [COLOR="Red"]stat_sys_battery_1.xml[/COLOR]
    stat_sys_battery_charge.xml
    [COLOR="red"]stat_sys_battery_charge_1.xml[/COLOR]
    New red files gonna be our value 1 preference


    5. By editing new red files above, you will get something like this:
    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <level-list
      xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/stat_sys_battery_0" android:maxLevel="4" />
        <item android:drawable="@drawable/stat_sys_battery_15" android:maxLevel="15" />
        <item android:drawable="@drawable/stat_sys_battery_28" android:maxLevel="35" />
        <item android:drawable="@drawable/stat_sys_battery_43" android:maxLevel="49" />
        <item android:drawable="@drawable/stat_sys_battery_57" android:maxLevel="60" />
        <item android:drawable="@drawable/stat_sys_battery_71" android:maxLevel="75" />
        <item android:drawable="@drawable/stat_sys_battery_85" android:maxLevel="90" />
        <item android:drawable="@drawable/stat_sys_battery_100" android:maxLevel="100" />
    </level-list>


    6. Here you need to change the drawables mapping to your new battery png's you put within your \res\drawable\YOUR_DENSITY folder:
    E.g.: New png's have _1 suffix!!
    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <level-list
      xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/stat_sys_battery_0[COLOR="red"]_1[/COLOR]" android:maxLevel="4" />
        <item android:drawable="@drawable/stat_sys_battery_15[COLOR="red"]_1[/COLOR]" android:maxLevel="15" />
        <item android:drawable="@drawable/stat_sys_battery_28[COLOR="red"]_1[/COLOR]" android:maxLevel="35" />
        <item android:drawable="@drawable/stat_sys_battery_43[COLOR="red"]_1[/COLOR]" android:maxLevel="49" />
        <item android:drawable="@drawable/stat_sys_battery_57[COLOR="red"]_1[/COLOR]" android:maxLevel="60" />
        <item android:drawable="@drawable/stat_sys_battery_71[COLOR="red"]_1[/COLOR]" android:maxLevel="75" />
        <item android:drawable="@drawable/stat_sys_battery_85[COLOR="red"]_1[/COLOR]" android:maxLevel="90" />
        <item android:drawable="@drawable/stat_sys_battery_100[COLOR="red"]_1[/COLOR]" android:maxLevel="100" />
    </level-list>


    7. Done with new resources!!!
    Remember you can put as much as new ones you want, just change their suffix to next integer value!!!


    Java

    - New "clone" com.android.systemui.statusbar.policy package
    - New "clone" BatteryController.java class with two new methods and all related comments there too
    - Added into "clone" PhoneStatusBar.java the new handleStatusBarChangeBatteryIcons method and its "calls", take a look at:
    makeStatusBarView
    setupExternalSettingsObserver
    externalPreferencesObserverCallback
    handleStatusBarChangeBatteryIcons

    Get new Eclipse Project from attachments!!


    Smali

    1. Get the newly built ExternalPreferences.apk from Eclipse project ( \bin folder )


    2. Decompile it


    3. Go to ExternalPreferences.apk decompiled folder: ...\smali\com\android\systemui\statusbar\phone\


    4. Open PhoneStatusBar.smali

    Now let's copy our new method from ExternalPreferences.apk (PhoneStatusBar.smali) file to SystemUI.apk (PhoneStatusBar.smali file)
    By copying it you will get (in red):

    Under # direct methods
    Code:
    # direct methods
    [COLOR="red"].method private handleStatusBarChangeBatteryIcons()V
        .locals 9
    
        .prologue
        const/4 v8, 0x0
    
        .line 125
        iget-object v4, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        const/4 v5, 0x0
    
        new-instance v6, Landroid/content/IntentFilter;
    
        const-string v7, "android.intent.action.BATTERY_CHANGED"
    
        invoke-direct {v6, v7}, Landroid/content/IntentFilter;-><init>(Ljava/lang/String;)V
    
        invoke-virtual {v4, v5, v6}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;
    
        move-result-object v0
    
        .line 126
        .local v0, getIntent:Landroid/content/Intent;
        const-string v4, "level"
    
        invoke-virtual {v0, v4, v8}, Landroid/content/Intent;->getIntExtra(Ljava/lang/String;I)I
    
        move-result v2
    
        .line 127
        .local v2, level:I
        const-string v4, "plugged"
    
        invoke-virtual {v0, v4, v8}, Landroid/content/Intent;->getIntExtra(Ljava/lang/String;I)I
    
        move-result v3
    
        .line 131
        .local v3, plugged:I
        new-instance v1, Landroid/content/Intent;
    
        const-string v4, "android.intent.action.BATTERY_CHANGED"
    
        invoke-direct {v1, v4}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V
    
        .line 132
        .local v1, intent:Landroid/content/Intent;
        const-string v4, "level"
    
        invoke-virtual {v1, v4, v2}, Landroid/content/Intent;->putExtra(Ljava/lang/String;I)Landroid/content/Intent;
    
        .line 133
        const-string v4, "plugged"
    
        invoke-virtual {v1, v4, v3}, Landroid/content/Intent;->putExtra(Ljava/lang/String;I)Landroid/content/Intent;
    
        .line 134
        iget-object v4, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mContext:Landroid/content/Context;
    
        invoke-virtual {v4, v1}, Landroid/content/Context;->sendBroadcast(Landroid/content/Intent;)V
    
        .line 136
        return-void
    .end method[/COLOR]


    5. Also replace setupExternalSettingsObserver and externalPreferencesObserverCallback whole methods by the new ones


    6. While on SystemUI.apk look for our last implemented method (from original guide, but now in blue) inside makeStatusBarView method, and add red lines
    Code:
        .line 1005
        const-string v0, "com.sonymobile.notes.NEW_SKETCH"
    
        invoke-direct {p0, v0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->isAppInstalled(Ljava/lang/String;)Z
    
        move-result v0
    
        iput-boolean v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mRightVisible:Z
    	
        [COLOR="Blue"].line 34
        invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->setupExternalSettingsObserver()V
    
        .line 37
        invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->handleStatusBarChangeClockToRed()V[/COLOR]
    	
        [COLOR="Red"].line 40
        invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->handleStatusBarChangeBatteryIcons()V[/COLOR]
    
        .line 1007
        iget-object v0, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;
    
        return-object v0
    
        :cond_14
        move v1, v2
    
        .line 825
        goto/16 :goto_7


    7. Go to ExternalPreferences.apk decompiled folder: ...\smali\com\android\systemui\statusbar\policy\


    8. Open BatteryController.smali

    Now let's copy our new methods from ExternalPreferences.apk (BatteryController.smali) file to SystemUI.apk (BatteryController.smali file)
    By copying them you will get (in red):

    Under # direct methods
    Code:
    # direct methods
    [COLOR="Red"].method private getStatSysBatteryChargeResId()I
        .locals 6
    
        .prologue
        .line 62
        iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;
    
        invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;
    
        move-result-object v2
    
        const-string v3, "stat_sys_battery_charge"
    
        const-string v4, "drawable"
    
        iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;
    
        invoke-virtual {v5}, Landroid/content/Context;->getPackageName()Ljava/lang/String;
    
        move-result-object v5
    
        invoke-virtual {v2, v3, v4, v5}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
    
        move-result v0
    
        .line 65
        .local v0, resId:I
        iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;
    
        invoke-virtual {v2}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
    
        move-result-object v2
    
        const-string v3, "status_bar_change_battery_icons"
    
        const/4 v4, 0x0
    
        invoke-static {v2, v3, v4}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
    
        move-result v1
    
        .line 66
        .local v1, value:I
        packed-switch v1, :pswitch_data_0
    
        .line 77
        :goto_0
        return v0
    
        .line 71
        :pswitch_0
        iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;
    
        invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;
    
        move-result-object v2
    
        const-string v3, "stat_sys_battery_charge_1"
    
        const-string v4, "drawable"
    
        iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;
    
        invoke-virtual {v5}, Landroid/content/Context;->getPackageName()Ljava/lang/String;
    
        move-result-object v5
    
        invoke-virtual {v2, v3, v4, v5}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
    
        move-result v0
    
        goto :goto_0
    
        .line 66
        :pswitch_data_0
        .packed-switch 0x1
            :pswitch_0
        .end packed-switch
    .end method
    
    .method private getStatSysBatteryResId()I
        .locals 6
    
        .prologue
        .line 36
        iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;
    
        invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;
    
        move-result-object v2
    
        const-string v3, "stat_sys_battery"
    
        const-string v4, "drawable"
    
        iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;
    
        invoke-virtual {v5}, Landroid/content/Context;->getPackageName()Ljava/lang/String;
    
        move-result-object v5
    
        invoke-virtual {v2, v3, v4, v5}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
    
        move-result v0
    
        .line 39
        .local v0, resId:I
        iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;
    
        invoke-virtual {v2}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
    
        move-result-object v2
    
        const-string v3, "status_bar_change_battery_icons"
    
        const/4 v4, 0x0
    
        invoke-static {v2, v3, v4}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
    
        move-result v1
    
        .line 40
        .local v1, value:I
        packed-switch v1, :pswitch_data_0
    
        .line 51
        :goto_0
        return v0
    
        .line 45
        :pswitch_0
        iget-object v2, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;
    
        invoke-virtual {v2}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;
    
        move-result-object v2
    
        const-string v3, "stat_sys_battery_1"
    
        const-string v4, "drawable"
    
        iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BatteryController;->mContext:Landroid/content/Context;
    
        invoke-virtual {v5}, Landroid/content/Context;->getPackageName()Ljava/lang/String;
    
        move-result-object v5
    
        invoke-virtual {v2, v3, v4, v5}, Landroid/content/res/Resources;->getIdentifier(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
    
        move-result v0
    
        goto :goto_0
    
        .line 40
        :pswitch_data_0
        .packed-switch 0x1
            :pswitch_0
        .end packed-switch
    .end method[/COLOR]


    9. While on SystemUI.apk BatteryController.smali file look for this method:
    Code:
    .method public onReceive(Landroid/content/Context;Landroid/content/Intent;)V


    9. Found, now let's implement "calls" to our new "get" methods (in red)
    Pay attention on v6 (in green), method must return as v6 (or the v? from your decompiled code)
    Code:
    .
    .
    .
        .line 117
        .end local v8           #plugType:I
        :cond_1
        :goto_1
        if-eqz v9, :cond_3
    
        const [COLOR="SeaGreen"]v6[/COLOR], 0x7f020130
    
        [COLOR="red"]invoke-direct {p0}, Lcom/android/systemui/statusbar/policy/BatteryController;->getStatSysBatteryChargeResId()I
    
        move-result [COLOR="SeaGreen"]v6[/COLOR][/COLOR]
    
        .line 120
        .local [COLOR="SeaGreen"]v6[/COLOR], icon:I
        :goto_2
        move-object/from16 v0, p0
    
        iget-object v13, v0, Lcom/android/systemui/statusbar/policy/BatteryController;->mIconViews:Ljava/util/ArrayList;
    
        invoke-virtual {v13}, Ljava/util/ArrayList;->size()I
    
        move-result v1
    .
    .
    .
    
    
    .
    .
    .
        .line 117
        .end local v8           #plugType:I
        :cond_3
        const [COLOR="green"]v6[/COLOR], 0x7f020127
    	
        [COLOR="Red"]invoke-direct {p0}, Lcom/android/systemui/statusbar/policy/BatteryController;->getStatSysBatteryResId()I
    
        move-result [COLOR="SeaGreen"]v6[/COLOR][/COLOR]
    
        goto :goto_2
    
        .line 128
        .restart local v1       #N:I
        .restart local v4       #i:I
        .restart local v6       #icon:I
    .
    .
    .
    0x7f020130 is the hex value from original stat_sys_battery_charge resource (under SystemUI.apk public.xml)
    0x7f020127 is the hex value from original stat_sys_battery resource (under SystemUI.apk public.xml)
    Your values may differ!!!


    10. Double check your changes, save everything, compile your modified SystemUI.apk and... done!!



    Others soon...
    .
    .
    14
    Changelog

    v1.1 - 13/04/2014
    - New mods under 3th post


    v1 - 09/04/2014
    - Initial guide
    1
    Awesome my friend great guide :good: start learning again

    Thank you very much :)

    Sent from my LT25i using Tapatalk
    1
    Wow a new master piece, I will try this ASAP !

    Envoyé de mon C6603 en utilisant Tapatalk