Welcome to XDA

Search to go directly to your device's forum

Register an account

Unlock full posting privileges

Ask a question

No registration required
Post Reply

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

OP serajr

9th April 2014, 09:44 PM   |  #1  
serajr's Avatar
OP Recognized Developer / Recognized Themer
Flag Rafard - SP
Thanks Meter: 10,541
 
2,799 posts
Join Date:Joined: Apr 2011
Donate to Me
More
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.





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



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:




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


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


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


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


PHP Code:
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
PhoneStatusBar$MyExternalPreferencesObserver.smali
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;,
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyTicker;,
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$H;,
        Lcom/android/systemui/statusbar/phone/PhoneStatusBar$MyExternalPreferencesObserver;
    }
.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
.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

.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
.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

.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:Landroid/view/View;

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

    invoke-virtual {v3, v1}, Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;->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;

    return-object 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
	
    .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
	
    .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
- 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!!
.
.
Last edited by serajr; 13th April 2014 at 05:26 PM. Reason: v1.1
The Following 49 Users Say Thank You to serajr For This Useful Post: [ View ]
9th April 2014, 09:45 PM   |  #2  
serajr's Avatar
OP Recognized Developer / Recognized Themer
Flag Rafard - SP
Thanks Meter: 10,541
 
2,799 posts
Join Date:Joined: Apr 2011
Donate to Me
More
Post Changelog
v1.1 - 13/04/2014
- New mods under 3th post


v1 - 09/04/2014
- Initial guide
Last edited by serajr; 13th April 2014 at 05:43 PM.
The Following 9 Users Say Thank You to serajr For This Useful Post: [ View ]
9th April 2014, 09:46 PM   |  #3  
serajr's Avatar
OP Recognized Developer / Recognized Themer
Flag Rafard - SP
Thanks Meter: 10,541
 
2,799 posts
Join Date:Joined: Apr 2011
Donate to Me
More
Camera New mods...
Here I'm gonna try to show you other mods you can try!!


Change Battery Icons Guide



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
stat_sys_battery_1.xml
stat_sys_battery_charge.xml
stat_sys_battery_charge_1.xml
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_1" android:maxLevel="4" />
    <item android:drawable="@drawable/stat_sys_battery_15_1" android:maxLevel="15" />
    <item android:drawable="@drawable/stat_sys_battery_28_1" android:maxLevel="35" />
    <item android:drawable="@drawable/stat_sys_battery_43_1" android:maxLevel="49" />
    <item android:drawable="@drawable/stat_sys_battery_57_1" android:maxLevel="60" />
    <item android:drawable="@drawable/stat_sys_battery_71_1" android:maxLevel="75" />
    <item android:drawable="@drawable/stat_sys_battery_85_1" android:maxLevel="90" />
    <item android:drawable="@drawable/stat_sys_battery_100_1" 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:
Quote:

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
.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

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
	
    .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
	
    .line 40
    invoke-direct {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->handleStatusBarChangeBatteryIcons()V

    .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
.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

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 v6, 0x7f020130

    invoke-direct {p0}, Lcom/android/systemui/statusbar/policy/BatteryController;->getStatSysBatteryChargeResId()I

    move-result v6

    .line 120
    .local v6, 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 v6, 0x7f020127
	
    invoke-direct {p0}, Lcom/android/systemui/statusbar/policy/BatteryController;->getStatSysBatteryResId()I

    move-result v6

    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...
.
.
Attached Thumbnails
Click image for larger version

Name:	java_eclipse_01.png
Views:	9578
Size:	142.8 KB
ID:	2677494   Click image for larger version

Name:	red_clock_1.jpg
Views:	9604
Size:	37.6 KB
ID:	2677496   Click image for larger version

Name:	red_clock_2.jpg
Views:	9533
Size:	38.1 KB
ID:	2677497   Click image for larger version

Name:	java_eclipse_02.png
Views:	9245
Size:	162.4 KB
ID:	2678788   Click image for larger version

Name:	change_battery_icons.jpg
Views:	6003
Size:	54.3 KB
ID:	2684104  
Attached Files
File Type: zip ExternalPreferences_ChangeBatteryIcons_Eclipse_Project.zip - [Click for QR Code] (1.36 MB, 87 views)
Last edited by serajr; 13th April 2014 at 08:50 PM. Reason: v1.1
The Following 11 Users Say Thank You to serajr For This Useful Post: [ View ]
9th April 2014, 09:56 PM   |  #4  
poria1999's Avatar
Senior Member
Flag Tehran
Thanks Meter: 463
 
342 posts
Join Date:Joined: Feb 2013
More
Glad That Im the first person Who says Thank you!
Thanks button is not enough....

Sent from my LT18i using Tapatalk 2
The Following 2 Users Say Thank You to poria1999 For This Useful Post: [ View ]
10th April 2014, 04:02 PM   |  #5  
Rizal Lovins's Avatar
Recognized Developer / Recognized Themer / Recognized Contributor
Flag Bandung - The Girl Next Door
Thanks Meter: 14,990
 
1,469 posts
Join Date:Joined: May 2012
More
Awesome my friend great guide start learning again

Thank you very much

Sent from my LT25i using Tapatalk
The Following User Says Thank You to Rizal Lovins For This Useful Post: [ View ]
11th April 2014, 04:30 PM   |  #6  
niaboc79's Avatar
Recognized Developer / Themer
Flag Enghien
Thanks Meter: 35,835
 
6,953 posts
Join Date:Joined: Sep 2007
Donate to Me
More
Wow a new master piece, I will try this ASAP !

Envoyé de mon C6603 en utilisant Tapatalk
The Following User Says Thank You to niaboc79 For This Useful Post: [ View ]
12th April 2014, 02:10 AM   |  #7  
DsvCdsSoftware's Avatar
Senior Member
Flag Cornélio Procópio
Thanks Meter: 40
 
219 posts
Join Date:Joined: Jan 2014
More
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.
The Following User Says Thank You to DsvCdsSoftware For This Useful Post: [ View ]
12th April 2014, 02:32 AM   |  #8  
Thy Boss's Avatar
Member
Flag SOLAR SYSTEM/EARTH/ASIA/PHILIPPINES
Thanks Meter: 14
 
69 posts
Join Date:Joined: Apr 2014
More
Unhappy Good but hard!
ITS REALLY HARD TO UNDERSTAND XD ME NEWBZ -.-

BUT KEEP UP THE GOOD WORK!

---------- Post added at 08:32 AM ---------- Previous post was at 08:25 AM ----------

IT JUST HAPPENED TO BE BROKEN!! it just did SHUT DOWN AND CANT BE TURNED ON!!

HERES THE VIDEO LINK: https://www.youtube.com/watch?v=wBfMWMQ58Qc

HELP ME!
The Following User Says Thank You to Thy Boss For This Useful Post: [ View ]
12th April 2014, 03:21 AM   |  #9  
serajr's Avatar
OP Recognized Developer / Recognized Themer
Flag Rafard - SP
Thanks Meter: 10,541
 
2,799 posts
Join Date:Joined: Apr 2011
Donate to Me
More
Quote:
Originally Posted by DsvCdsSoftware

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 by serajr; 12th April 2014 at 03:33 AM.
The Following 2 Users Say Thank You to serajr For This Useful Post: [ View ]
12th April 2014, 03:37 AM   |  #10  
Ricky Divjakovski's Avatar
Recognized Contributor
Flag Sydney
Thanks Meter: 5,372
 
3,629 posts
Join Date:Joined: Feb 2013
Donate to Me
More
Im really impressed, great job!

The Following User Says Thank You to Ricky Divjakovski For This Useful Post: [ View ]
Post Reply Subscribe to Thread

Tags
guide, java, serajr, smali, systemui
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes