We disassemble SystemUI.apk
Everything will happen in the resulting SystemUI folder, so all the paths are written relative to it.
To hide / show a battery, we need to know its id
Open up
res / layout /status_bar.xml and see the line
<ImageView android: id = "@ id / battery" android: paddingLeft = "4.0dip" android: layout_width = "wrap_content" android: layout_height = "wrap_content" />
then id it
battery Open up
res / values ​​/public.xml and look for a string with type
id and by name
battery <public type = "id" name = "battery" id = "0x7f0e002a" />
remember found id
7f0e002a (you may have a different id)
Now we need to write a method that will hide or show the battery depending on the setting.
Call it
zBatteryVis open up
smali / com / android / systemui / statusbar / phone /PhoneStatusBar.smali and at the very end of the file we write
Code
.method zBatteryVis () V
.locals 0
.prologue
return-void
.end method
This is our workpiece and we need to fill it.
The first thing we need to do is read the setting that stores the value that determines whether or not to show the element.
For this we need
setup name ,
default value (if there is no such setting) and
ContentResolver To get
ContentResolver we will need
Context The name of the setting
sb_batt , the value of this setting can be 1 (show) or 0 (hide)
The default value will be 1 (show)
But
Context You need to search in the same smali file, and at the beginning of the line should be iget-object, and at the end of the Context
Search by word
Context and find the string
iget-object v1, p0, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->mContext: Landroid / content / Context;
copy it and paste it into our method after the line .prologue and change v1 to v0
Code
.method zBatteryVis () V
.locals 0
.prologue
iget-object v0, p0, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->mContext: Landroid / content / Context;
return-void
.end method
This string means that we have received the context and written it to the register.
v0 now we can get
ContentResolver write further
invoke-virtual {v0}, Landroid / content / Context; ->getContentResolver () Landroid / content / ContentResolver;
move-result-object v0
Got
ContentResolver and write it to the register
v0 instead of
Context further setting name in register
v1 const-string v1, "sb_batt"
default value to register
v2 and actually getting the setting value and writing it to the register v0
invoke-static {v0, v1, v2}, Landroid / provider / Settings $ System; ->getInt (Landroid / content / ContentResolver; Ljava / lang / String; I) I
move-result v0
What happened
.method zBatteryVis () V
.locals 0
.prologue
iget-object v0, p0, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->mContext: Landroid / content / Context;
invoke-virtual {v0}, Landroid / content / Context; ->getContentResolver () Landroid / content / ContentResolver;
move-result-object v0
const-string v1, "sb_batt"
const / 4 v2, 0x1
invoke-static {v0, v1, v2}, Landroid / provider / Settings $ System; ->getInt (Landroid / content / ContentResolver; Ljava / lang / String; I) I
move-result v0
return-void
.end method
now we have in the register v0 setting value
Well, now we need to access the element by id
For example, take the clock reference, which is exactly in this smali file.
In the way described first we find the id of the clock, I have it
7f0e002b We are looking for the file smali word 0x7f0e002b and find such a code
Code
iget-object v1, p0, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->mStatusBarView: Lcom / android / systemui / statusbar / phone / PhoneStatusBarView;
const v2,0x7f0e002b
invoke-virtual {v1, v2}, Lcom / android / systemui / statusbar / phone / PhoneStatBarView; ->findViewById (I) Landroid / view / View;
move-result-object v0
Copy it and paste it into our method after move-result v0, but change 0x7f0e002b to the id of our battery, memorized at the beginning 0x7f0e002a
and in the last line of v0 on v1, so that the setting value that we have in register v0 does not get stuck
What happened
.method zBatteryVis () V
.locals 0
.prologue
iget-object v0, p0, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->mContext: Landroid / content / Context;
invoke-virtual {v0}, Landroid / content / Context; ->getContentResolver () Landroid / content / ContentResolver;
move-result-object v0
const-string v1, "sb_batt"
const / 4 v2, 0x1
invoke-static {v0, v1, v2}, Landroid / provider / Settings $ System; ->getInt (Landroid / content / ContentResolver; Ljava / lang / String; I) I
move-result v0
iget-object v1, p0, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->mStatusBarView: Lcom / android / systemui / statusbar / phone / PhoneStatusBarView;
const v2,0x7f0e002a
invoke-virtual {v1, v2}, Lcom / android / systemui / statusbar / phone / PhoneStatBarView; ->findViewById (I) Landroid / view / View;
move-result-object v1
return-void
.end method
And now we add the code to hide the element, we write after move-result-object v1
const v2,0x8
invoke-virtual {v1, v2}, Landroid / view / View; ->setVisibility (I) V
in the register v2 we have the number 8, which corresponds to android: visibility = "gone", that is, it hides the element
and it remains to make a choice based on the value of the parameter, which is in register v0, we write further
if the value in the register v0 does not equal 0 go to the label: cond_0
after the return-void line we write
Code
: cond_0
const v2,0x0
goto: goto_0
in the register v2 we have the digit 0, which corresponds to android: visibility = "visible", that is, it shows the element
and before the line invoke-virtual {v1, v2}, Landroid / view / View; ->setVisibility (I) V write
It turns out that, depending on the value of register v0, we register in register v2 0 or 8
Now we count the registers that we used: v0, v1, v2 - only 3
change .locals 0 to .locals 3
What happened
.method zBatteryVis () V
.locals 3
.prologue
iget-object v0, p0, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->mContext: Landroid / content / Context;
invoke-virtual {v0}, Landroid / content / Context; ->getContentResolver () Landroid / content / ContentResolver;
move-result-object v0
const-string v1, "sb_batt"
const / 4 v2, 0x1
invoke-static {v0, v1, v2}, Landroid / provider / Settings $ System; ->getInt (Landroid / content / ContentResolver; Ljava / lang / String; I) I
move-result v0
iget-object v1, p0, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->mStatusBarView: Lcom / android / systemui / statusbar / phone / PhoneStatusBarView;
const v2,0x7f0e002a
invoke-virtual {v1, v2}, Lcom / android / systemui / statusbar / phone / PhoneStatBarView; ->findViewById (I) Landroid / view / View;
move-result-object v1
if-nez v0,: cond_0
const v2,0x8
: goto_0
invoke-virtual {v1, v2}, Landroid / view / View; ->setVisibility (I) V
return-void
: cond_0
const v2,0x0
goto: goto_0
.end method
With method finished
Now it needs to be called at the initial loading of the statusbar and each time by the event
Initial loading of the statusbar occurs in the method
makeStatusBarView () Landroid / view / View To run our method, you need to see how a similar method is run from a method.
makeStatusBarView () Landroid / view / View for example method
updateRecentsPanel () V find it in the method
makeStatusBarView () Landroid / view / View invoke-virtual / range {p0 .. p0}, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->updateRecentsPanel () V
copy the string and paste it in front of the string
return object in the method
makeStatusBarView () Landroid / view / View and change
updateRecentsPanel on
zBatteryVis What happened
invoke-virtual / range {p0 .. p0}, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->zBatteryVis () V
.line 475
return object v8
When loading done, now you need an event
First register our event in BroadcastResiver
We look above in the same method lines starting with
android.intent.action it will be for example
Code
.line 450
const-string v13, "android.intent.action.CLOSE_SYSTEM_DIALOGS"
invoke-virtual {v4, v13}, Landroid / content / IntentFilter; ->addAction (Ljava / lang / String;) V
we copy these lines, we insert immediately after them and we change
android.intent.action.CLOSE_SYSTEM_DIALOGS on
aaa.our.settings.BATTERY_VIS Code
.line 450
const-string v13, "android.intent.action.CLOSE_SYSTEM_DIALOGS"
invoke-virtual {v4, v13}, Landroid / content / IntentFilter; ->addAction (Ljava / lang / String;) V
.line 450
const-string v13, "aaa.our.settings.BATTERY_VIS"
invoke-virtual {v4, v13}, Landroid / content / IntentFilter; ->addAction (Ljava / lang / String;) V
Event registered, now we need to find the file in which these events are processed
To do this, look for the string starting at
iput-object and ending on
mBroadcastReceiver : Landroid / content / BroadcastReceiver;
we find such code
invoke-direct {v0, p0}, Lcom / android / systemui / statusbar / phone / PhoneStatBar $ 7; -><init>(Lcom / android / systemui / statusbar / phone / PhoneStatusBar;) V
iput-object v0, p0, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->mBroadcastReceiver: Landroid / content / BroadcastReceiver;
In the top line you can see in which file the received event is processed -
PhoneStatusBar $ 7 open up
smali / com / android / systemui / statusbar / phone /PhoneStatusBar $ 7.smali and we are looking for a method
onReceive (Landroid / content / Context; Landroid / content / Intent;) V in this method, look for the string
return-void after it should be similar to this code
Code
: goto_0
return-void
.line 2423
: cond_3
const-string v6, "android.intent.action.SKIN_CHANGED"
invoke-virtual {v6, v0}, Ljava / lang / String; ->equals (Ljava / lang / Object;) Z
move-result v6
if-eqz v6,: cond_4
we copy these lines, we correct here
: cond_3 on
: cond_3a , paste in front of these lines the ones that are copied, change
android.intent.action.SKIN_CHANGED on our
aaa.our.settings.BATTERY_VIS change in inserted strings
: cond_4 on
: cond_3a and after
if-eqz v6,: cond_3a add row
goto: goto_0 (label: goto_0 is in front of the return-void line)
What happened
: goto_0
return-void
.line 2423
: cond_3
const-string v6, "aaa.our.settings.BATTERY_VIS" #Change
invoke-virtual {v6, v0}, Ljava / lang / String; ->equals (Ljava / lang / Object;) Z
move-result v6
if-eqz v6,: cond_3a # CHANGE
goto: goto_0 # CHANGE
.line 2423
: cond_3a #Change
const-string v6, "android.intent.action.SKIN_CHANGED"
invoke-virtual {v6, v0}, Ljava / lang / String; ->equals (Ljava / lang / Object;) Z
move-result v6
if-eqz v6,: cond_4
Now it remains only to spy as from this file run a method similar to ours, for example, take
updateResources () V .line 2429
iget-object v6, p0, Lcom / android / systemui / statusbar / phone / PhoneStatusBar $ 7; ->this $ 0: Lcom / android / systemui / statusbar / phone / PhoneStatusBar;
invoke-virtual {v6}, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->updateResources () V
Copy these lines, paste into our block before the line.
goto: goto_0 and change
updateResources on
zBatteryVis What happened
: goto_0
return-void
.line 2423
: cond_3
const-string v6, "aaa.our.settings.BATTERY_VIS"
invoke-virtual {v6, v0}, Ljava / lang / String; ->equals (Ljava / lang / Object;) Z
move-result v6
if-eqz v6,: cond_3a
.line 2429
iget-object v6, p0, Lcom / android / systemui / statusbar / phone / PhoneStatusBar $ 7; ->this $ 0: Lcom / android / systemui / statusbar / phone / PhoneStatusBar;
invoke-virtual {v6}, Lcom / android / systemui / statusbar / phone / PhoneStatusBar; ->zBatteryVis () V # CHANGE
goto: goto_0
.line 2423
: cond_3a
const-string v6, "android.intent.action.SKIN_CHANGED"
invoke-virtual {v6, v0}, Ljava / lang / String; ->equals (Ljava / lang / Object;) Z
move-result v6
if-eqz v6,: cond_4
On this with SystemUI finished
We collect apk and we change in the initial
classes.dex