Related
Time for a big update to this post.
The andromeda roms have now a camera that not only uses the power button for taking stills, but also for video recording.
More interestingly, the power button in still images function now as the grey button on the display, i.e., one quick press takes a still as is, while a long press focuses until the key is released, and then takes the still.
The second mod required a change in android.policy.jar to prevent the power button long press to bring the power menu up. Thus, it will only work in the andromeda rom unless other rom developers decide to implement the change also.
You can find the diffs between the original armani camera app and this one attached here. For the actual app, please take a look at the andromeda page for the reason stated above.
I will explain the changes in posts below (20-23) so I don't clutter this one too much.
GlobalActions.smali is part of android.policy.jar, while the other three belong to the camera app.
BTW: This does not belong any more to Q&A. Dear Mods, would you please move the thread to a more suitable forum (apps or dev)?
+1, how do I do this?
subscribed...
Same here... Any rom removes this?
subscribed... really, that is annoying...
If this helps in the search:
I installed dropbox, and noticed that dropbox now shows as one of the upload options. This suggests (to me) that there is a configuration file or database entry somewhere where this was added.
If we can find out where, there is a possibility of just removing the lockbox entry.
I doubt that its built into the app, they would want to sell this to different providers, and each will have (or not) its own version of the AT&T lockbox.
I did spend an hour or so this morning perusing databases, but didn't find anything.
PhilipPeake said:
If this helps in the search:
I installed dropbox, and noticed that dropbox now shows as one of the upload options. This suggests (to me) that there is a configuration file or database entry somewhere where this was added.
If we can find out where, there is a possibility of just removing the lockbox entry.
I doubt that its built into the app, they would want to sell this to different providers, and each will have (or not) its own version of the AT&T lockbox.
I did spend an hour or so this morning perusing databases, but didn't find anything.
Click to expand...
Click to collapse
Lol! I almost forgot about this thread already! So many roms now and I always saw that button that I learned to be careful
I just decompiled it and this is what I found:
Code:
$:~/android/apk_manager/out$ grep -i -r -n 'locker' *
res/values/strings.xml:271: <string name="menu_qsend">Send to Online Locker</string>
smali/com/sec/android/app/camera/ReviewImage.smali:2346:.method public onSendToOnlineLocker()V
smali/com/sec/android/app/camera/ReviewImage$9.smali:57: invoke-virtual {v0}, Lcom/sec/android/app/camera/ReviewImage;->onSendToOnlineLocker()V
$:~/android/apk_manager/out$ grep -i -r -n 'menu_qsend' *
res/values-it/strings.xml:261: <string name="menu_qsend">Invia a Armadietto online</string>
res/values-de/strings.xml:261: <string name="menu_qsend">Senden an Online-Schließfach</string>
res/values/public.xml:1563: <public type="string" name="menu_qsend" id="0x7f07010c" />
res/values/strings.xml:271: <string name="menu_qsend">Send to Online Locker</string>
res/values-fr/strings.xml:261: <string name="menu_qsend">Envoyer à Casier en ligne</string>
res/values-es/strings.xml:261: <string name="menu_qsend">Enviar a Bloqueo en línea</string>
res/values-ko/strings.xml:261: <string name="menu_qsend">온라인 보관함으로 전송</string>
smali/com/sec/android/app/camera/R$string.smali:506:.field public static final menu_qsend:I = 0x7f07010c
I'll dig a little more into it
PhilipPeake said:
If this helps in the search:
I installed dropbox, and noticed that dropbox now shows as one of the upload options. This suggests (to me) that there is a configuration file or database entry somewhere where this was added.
If we can find out where, there is a possibility of just removing the lockbox entry.
I doubt that its built into the app, they would want to sell this to different providers, and each will have (or not) its own version of the AT&T lockbox.
I did spend an hour or so this morning perusing databases, but didn't find anything.
Click to expand...
Click to collapse
You made me look again into this
Check the first post
aleadam said:
You made me look again into this
Check the first post
Click to expand...
Click to collapse
On JPY, the Video says "Camera Failed" and exits the app. Pictures work fine.
EDIT: The stock camera app is doing that too... so it's not a problem with this.
MikeyMike01 said:
On JPY, the Video says "Camera Failed" and exits the app. Pictures work fine.
EDIT: The stock camera app is doing that too... so it's not a problem with this.
Click to expand...
Click to collapse
I don't think it's a jpy problem. I just tested on Doc's rom and the video works fine. On glitterballs kernel in case it's important.
So what makes this different from the other modded camera.apk?
moosefist said:
So what makes this different from the other modded camera.apk?
Click to expand...
Click to collapse
I thought it was quite clear from the title
When reviewing the images, you don't have to click on more->delete to delete a picture. It's just there. More important, you don't have the option for at&t online locker above delete. Too many times I clicked on that (fat thumbs, maybe?) instead of the delete button.
It is just a minimal mod, for the few of us that hate the online locker. Nothing more.
The Camera app in JPY is (in some stupid way) reliant on the Email.apk, which I had removed.
Got that squared away, and now it's working.
MikeyMike01 said:
The Camera app in JPY is (in some stupid way) reliant on the Email.apk, which I had removed.
Got that squared away, and now it's working.
Click to expand...
Click to collapse
Well, that should be obvious... how do you plan to take a picture without a proper email application?????
I'm getting FC's on the stock I-9000 froyo rom with Setiron's kernel after installing through cwm
vaiol123 said:
I'm getting FC's on the stock I-9000 froyo rom with Setiron's kernel after installing through cwm
Click to expand...
Click to collapse
If you're using an sgs i9000 then I would suggest you to use the original apk from fr4gg0r. This one is for captivates so you don't get FFC references and avoid at&t crap.
Oh yeah what I meant was I am using an i9000 rom on a cappy and wanted to get rid of ffc references but it would just fc haha. I can live with it though
vaiol123 said:
I'm getting FC's on the stock I-9000 froyo rom with Setiron's kernel after installing through cwm
Click to expand...
Click to collapse
Sorry I didn't check this thread in a while. With a stock i9000 rom I would try an i9000 camera.apk, like the one in the original thread from fr4gg0r
I can't say much without a logcat to know where is the error.
New Camera.apk that does respond to the home button after pressing the power button. It's a dirty trick so haptic feedback won't work on it.
EDIT: Now video recording should also keep working with a low battery.
Diff explanations
Let's start with the camera:
Code:
diff -ru armani_Camera/Camera/smali/com/sec/android/app/camera/Camera.smali new_Camera/Camera/smali/com/sec/android/app/camera/Camera.smali
--- armani_Camera/Camera/smali/com/sec/android/app/camera/Camera.smali 2011-02-09 23:53:00.459447001 -0500
+++ new_Camera/Camera/smali/com/sec/android/app/camera/Camera.smali 2011-02-09 23:52:27.407447002 -0500
Nothing new in this part, just to make it keep working when the battery is very low
Code:
@@ -588,9 +588,6 @@
if-eq v3, v8, :cond_0
- .line 1665
- invoke-virtual {p0}, Lcom/sec/android/app/camera/Camera;->handleLowBattery()V
-
.line 1668
:cond_0
if-eq v1, v8, :cond_1
This is at the very beginning of the onKeyDown method and is the hack to fix the issue with the home button not responding after pressing the power button. As I said in the other thread, I don't think this is the real solution but it works well enough for now.
Code:
@@ -7641,6 +7638,42 @@
.prologue
const/4 v4, 0x1
+ const/16 v1, 0x3
+
+ if-ne p1, v1, :cond_0
+
+ new-instance v0, Landroid/content/Intent;
+
+ const-string v1, "android.intent.action.MAIN"
+
+ invoke-direct {v0, v1}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V
+
+ .local v0, startMain:Landroid/content/Intent;
+ const-string v1, "android.intent.category.HOME"
+
+ invoke-virtual {v0, v1}, Landroid/content/Intent;->addCategory(Ljava/lang/String;)Landroid/content/Intent;
+
+ const/high16 v1, 0x1000
+
+ invoke-virtual {v0, v1}, Landroid/content/Intent;->setFlags(I)Landroid/content/Intent;
+
+ invoke-virtual {p0, v0}, Lcom/sec/android/app/camera/Camera;->startActivity(Landroid/content/Intent;)V
+
Now we're talking! This little piece here adds a new global setting, named "camera_in_use" that I made it be either 0 (not in use) or 1 (in use). As soon as the power key is pressed, this setting becomes 1. This is the int that will be read by android.policy.jar. We could use this idea to prevent android.policy.jar to respond to the power key altogether to solve the issue above, but I did not look into it yet.
Code:
+ .line 593
+ :cond_0
+ invoke-virtual {p0}, Lcom/sec/android/app/camera/Camera;->getApplicationContext()Landroid/content/Context;
+
+ move-result-object v0
+
+ invoke-virtual {v0}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
+
+ move-result-object v0
+
+ .line 594
+ const-string v2, "camera_in_use"
+
+ invoke-static {v0, v2, v4}, Landroid/provider/Settings$System;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
+
const-string v3, "Camera"
.line 595
I removed all the garbage here, to focus on the switch part. By making it jump to :sswitch_2 instead of _sswitch_0 i force it to evaluate it as a camera button.
Code:
@@ -7930,32 +7963,34 @@
:sswitch_data_0
.sparse-switch
0x4 -> :sswitch_0
0x17 -> :sswitch_2
0x18 -> :sswitch_3
0x19 -> :sswitch_3
- 0x1a -> :sswitch_0
+ 0x1a -> :sswitch_2
0x1b -> :sswitch_2
0x42 -> :sswitch_2
0x50 -> :sswitch_1
Beginning of onKeyUp method. Now the power menu cannot longer be called by the power button, so I changed camera_in_use back to 0. I thought it was the safest location to allow android.policy.jar to respond to the button in any other circumstance.
Code:
@@ -7971,6 +8057,20 @@
.prologue
const/4 v4, 0x0
+ .line 687
+ invoke-virtual {p0}, Lcom/sec/android/app/camera/Camera;->getApplicationContext()Landroid/content/Context;
+
+ move-result-object v0
+
+ invoke-virtual {v0}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
+
+ move-result-object v0
+
+ .line 688
+ const-string v2, "camera_in_use"
+
+ invoke-static {v0, v2, v4}, Landroid/provider/Settings$System;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z
+
const/4 v2, 0x1
const-string v3, "Camera"
Actual code to make the power button to take the shot. To be honest, I don't really know how much of all this is required. I will trim it if I have the time.
Code:
@@ -8030,72 +8130,92 @@
:cond_0
const/16 v0, 0x1a
- if-ne p1, v0, :cond_1
+ if-ne p1, v0, :cond_2
.line 700
- invoke-direct {p0}, Lcom/sec/android/app/camera/Camera;->resetFocusDueToZoom()V
+ iget-object v1, p0, Lcom/sec/android/app/camera/Camera;->mCameraEngine:Lcom/sec/android/app/camera/CameraEngine;
- .line 701
- iget-object v0, p0, Lcom/sec/android/app/camera/Camera;->mCameraBaseIndicators:Lcom/sec/android/app/camera/CameraBaseIndicators;
+ invoke-virtual {v1}, Lcom/sec/android/app/camera/CameraEngine;->isTouchAutoFocusing()Z
- invoke-virtual {v0}, Lcom/sec/android/app/camera/CameraBaseIndicators;->showFocusIndicator()V
+ move-result v1
- .line 702
- invoke-virtual {p0}, Lcom/sec/android/app/camera/Camera;->getCameraSettings()Lcom/sec/android/app/camera/CameraSettings;
+ if-eqz v1, :cond_1
- move-result-object v0
+ iget-object v1, p0, Lcom/sec/android/app/camera/Camera;->mCameraEngine:Lcom/sec/android/app/camera/CameraEngine;
- invoke-virtual {v0}, Lcom/sec/android/app/camera/CameraSettings;->getLock()Z
+ invoke-virtual {v1}, Lcom/sec/android/app/camera/CameraEngine;->stopTouchAutoFocus()V
- move-result v0
+ :cond_1
+ iget-object v1, p0, Lcom/sec/android/app/camera/Camera;->mCameraEngine:Lcom/sec/android/app/camera/CameraEngine;
- if-eqz v0, :cond_2
+ const/16 v3, 0x190
- .line 703
- invoke-virtual {p0}, Lcom/sec/android/app/camera/Camera;->getCameraSettings()Lcom/sec/android/app/camera/CameraSettings;
+ const/16 v4, 0xf0
- move-result-object v0
+ const/16 v0, 0x320
- invoke-virtual {v0, v4}, Lcom/sec/android/app/camera/CameraSettings;->setLock(Z)V
+ const/16 v2, 0x1e0
- .line 712
- :cond_1
- invoke-virtual {p0}, Lcom/sec/android/app/camera/Camera;->getCameraSettings()Lcom/sec/android/app/camera/CameraSettings;
+ invoke-virtual {v1, v3, v4}, Lcom/sec/android/app/camera/CameraEngine;->setTouchFocusPosition(II)V
- move-result-object v0
+ iget-object v1, p0, Lcom/sec/android/app/camera/Camera;->mCameraEngine:Lcom/sec/android/app/camera/CameraEngine;
- invoke-virtual {v0}, Lcom/sec/android/app/camera/CameraSettings;->getLock()Z
+ invoke-virtual {v1}, Lcom/sec/android/app/camera/CameraEngine;->startTouchAutoFocus()V
- move-result v0
+ iget-object v1, p0, Lcom/sec/android/app/camera/Camera;->mCameraBaseIndicators:Lcom/sec/android/app/camera/CameraBaseIndicators;
- if-eqz v0, :cond_3
+ invoke-virtual {v1}, Lcom/sec/android/app/camera/CameraBaseIndicators;->hideFocusIndicator()V
- move v0, v2
+ iget-object v1, p0, Lcom/sec/android/app/camera/Camera;->mCameraBaseIndicators:Lcom/sec/android/app/camera/CameraBaseIndicators;
+
+ invoke-virtual {v1}, Lcom/sec/android/app/camera/CameraBaseIndicators;->resetTouchFocusRectView()V
+
+ iget-object v1, p0, Lcom/sec/android/app/camera/Camera;->mCameraBaseIndicators:Lcom/sec/android/app/camera/CameraBaseIndicators;
+
+ invoke-virtual {v1, v3, v4, v0, v2}, Lcom/sec/android/app/camera/CameraBaseIndicators;->setTouchFocusRectCenter(IIII)V
+
+ const/4 v1, 0x1
+
+ iput-boolean v1, p0, Lcom/sec/android/app/camera/Camera;->mChkAllowFocusTouch:Z
+
+ iget-object v1, p0, Lcom/sec/android/app/camera/Camera;->mCameraEngine:Lcom/sec/android/app/camera/CameraEngine;
+
+ invoke-direct {p0}, Lcom/sec/android/app/camera/Camera;->handleShutterKey()Z
+
+ invoke-virtual {v1}, Lcom/sec/android/app/camera/CameraEngine;->handleShutterEvent()V
+
+ invoke-virtual {v1}, Lcom/sec/android/app/camera/CameraEngine;->scheduleAutoFocus()V
+
+ invoke-direct {p0}, Lcom/sec/android/app/camera/Camera;->handleShutterKeyReleased()Z
+
+ invoke-virtual {v1}, Lcom/sec/android/app/camera/CameraEngine;->handleShutterReleaseEvent()V
+
+ const/4 v0, 0x1
- .line 713
goto :goto_0
- .line 705
+ .line 702
+ .line 703
+ .line 712
:cond_2
invoke-virtual {p0}, Lcom/sec/android/app/camera/Camera;->getCameraSettings()Lcom/sec/android/app/camera/CameraSettings;
move-result-object v0
- invoke-virtual {v0, v2}, Lcom/sec/android/app/camera/CameraSettings;->setLock(Z)V
-
- .line 706
- :goto_1
- invoke-virtual {p0}, Lcom/sec/android/app/camera/Camera;->isCaptureEnabled()Z
+ invoke-virtual {v0}, Lcom/sec/android/app/camera/CameraSettings;->getLock()Z
move-result v0
- if-nez v0, :cond_1
+ if-eqz v0, :cond_3
- .line 707
- invoke-virtual {p0}, Lcom/sec/android/app/camera/Camera;->processBack()V
+ move v0, v2
- goto :goto_1
+ .line 713
+ goto :goto_0
+ .line 705
+ .line 706
+ .line 707
.line 716
:cond_3
const-string v0, "Camera"
Hello Everyone,
Here, being on XDA, is like learning new things in a school and getting project homework on daily basis. And Speaking for this, I really like it.
So here is the project that I cleared today morning at around 4.30 AM IST (Indian Standard Time).
But before beginning for project let me THANK few IDOLS of XDA.
@tdunham - You are the master of Power menu Sir. Compared files with your guide. @Adi Aisiteru Reborn - The GOD of MOD & Guides for CM / AOSP / AOKP @ankurbata- For the files I used for comparing.
@Dzol Cp- You are the One brother who taught me these things.
@bombaybadboy-Awesome Thread by You Sir. Got everything working whenever I take help from your thread.
@Goldieking- For helping me in rectifying error.
@Ticklefish- Awesome and Simplest tool for Themers and noobs like me.
@My Wife - My Life's Companion, Dearest Friend, My Love & Encouragement. I love you Sweet-Heart. @Xda Forum- The School for New born Techie child like me.
Before beginning to this guide, please make sure that you followed this guide by tdunham line by line and you failed doing so.
I tried this on my Stock ROMs and Other ported ROMs of My Device forum and got this working.
PART-1
1st Step:-
Decompile Your framework-res.apk and go to - res/value/strings.xml
add this line at the end.
Code:
<string name="global_action_screenshot_txt">Screenshot</string>
<string name="global_action_recovery_txt">BOND Recovery</string>
And add the png attached in this thread to - res/value/drawable-hdpi/mdpi/xhdpi (any one folder you can choose to add the images as according to your device resolution).
Step-2
Now recompile the framework-res.apk and then again decompile the newly compiled framework-res.apk
Then go to - res/values/public.xml and leave it open.
PART-2
Step-1
Now Decompile your stock "android.policy.jar" and add the attached "android.policy" files to - "android.policy.jar\smali\com\android\internal\policy\impl"
Now open GlobalActions.smali.
and find this lines.
Code:
.field private mRingerModeReceiverRegistered:Z
Just below this line make space for a line just like as its there (One space above the line & One space below)
Then Add these lines
Code:
.field mScreenshotConnection:Landroid/content/ServiceConnection;
.field final mScreenshotLock:Ljava/lang/Object;
.field final mScreenshotTimeout:Ljava/lang/Runnable;
Now find this line
Code:
iput-object v4, p0, Lcom/android/internal/policy/impl/GlobalActions;->mAirplaneState:Lcom/android/internal/policy/impl/GlobalActions$ToggleAction$State;
Add these line below that.
Code:
.line 315
new-instance v4, Ljava/lang/Object;
invoke-direct {v4}, Ljava/lang/Object;-><init>()V
iput-object v4, p0, Lcom/android/internal/policy/impl/GlobalActions;->mScreenshotLock:Ljava/lang/Object;
.line 317
const/4 v4, 0x0
iput-object v4, p0, Lcom/android/internal/policy/impl/GlobalActions;->mScreenshotConnection:Landroid/content/ServiceConnection;
.line 318
new-instance v4, Lcom/android/internal/policy/impl/GlobalActions$12;
invoke-direct {v4, p0}, Lcom/android/internal/policy/impl/GlobalActions$12;-><init>(Lcom/android/internal/policy/impl/GlobalActions;)V
iput-object v4, p0, Lcom/android/internal/policy/impl/GlobalActions;->mScreenshotTimeout:Ljava/lang/Runnable;
Now Find This line -
Code:
.method static synthetic access$1800(Lcom/android/internal/policy/impl/GlobalActions;)V
.locals 0
.parameter "x0"
.prologue
.line 68
invoke-direct {p0}, Lcom/android/internal/policy/impl/GlobalActions;->handleShow()V
return-void
.end method
And Add the line below end method.
Code:
.method static synthetic access$1900(Lcom/android/internal/policy/impl/GlobalActions;)V
.locals 0
.parameter "x0"
.prologue
.line 64
invoke-direct {p0}, Lcom/android/internal/policy/impl/GlobalActions;->takeScreenshot()V
return-void
.end method
Now find this line
Code:
invoke-direct {v2, v0, v3, v4}, Lcom/android/internal/policy/impl/GlobalActions$3;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V
And add this line below this method and above the line starting with-".line XXX"
Code:
.line 232
move-object/from16 v0, p0
iget-object v1, v0, Lcom/android/internal/policy/impl/GlobalActions;->mItems:Ljava/util/ArrayList;
new-instance v2, Lcom/android/internal/policy/impl/GlobalActions$11;
const v3, 0x1080691 [COLOR=Lime]<-------- This is the ID of "bond_screenshot"[/COLOR]
const v4, 0x1040516 [COLOR=Red] <-------- This is the ID of "global_action_screenshot_txt"[/COLOR]
move-object/from16 v0, p0
invoke-direct {v2, v0, v3, v4}, Lcom/android/internal/policy/impl/GlobalActions$11;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V
invoke-virtual {v1, v2}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z
move-object/from16 v0, p0
iget-object v1, v0, Lcom/android/internal/policy/impl/GlobalActions;->mItems:Ljava/util/ArrayList;
new-instance v2, Lcom/android/internal/policy/impl/GlobalActions$14;
const v3, 0x1080692[COLOR=Lime] <-------- This is the ID of "bond_recovery"[/COLOR]
const v4, 0x1040517 [COLOR=Red]<-------- This is the ID of "global_action_recovery_txt"[/COLOR]
move-object/from16 v0, p0
invoke-direct {v2, v0, v3, v4}, Lcom/android/internal/policy/impl/GlobalActions$14;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V
invoke-virtual {v1, v2}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z
Now Find this line--
Code:
# virtual methods
And add this lines just above it with gap of 2(two) Space between "end method" & "Virtual methods"
Code:
.method private takeScreenshot()V
.locals 8
.prologue
.line 330
iget-object v4, p0, Lcom/android/internal/policy/impl/GlobalActions;->mScreenshotLock:Ljava/lang/Object;
monitor-enter v4
.line 331
:try_start_0
iget-object v3, p0, Lcom/android/internal/policy/impl/GlobalActions;->mScreenshotConnection:Landroid/content/ServiceConnection;
if-eqz v3, :cond_0
.line 332
monitor-exit v4
.line 391
:goto_0
return-void
.line 334
:cond_0
new-instance v0, Landroid/content/ComponentName;
const-string v3, "com.android.systemui"
const-string v5, "com.android.systemui.screenshot.TakeScreenshotService"
invoke-direct {v0, v3, v5}, Landroid/content/ComponentName;-><init>(Ljava/lang/String;Ljava/lang/String;)V
.line 336
.local v0, cn:Landroid/content/ComponentName;
new-instance v2, Landroid/content/Intent;
invoke-direct {v2}, Landroid/content/Intent;-><init>()V
.line 337
.local v2, intent:Landroid/content/Intent;
invoke-virtual {v2, v0}, Landroid/content/Intent;->setComponent(Landroid/content/ComponentName;)Landroid/content/Intent;
.line 338
new-instance v1, Lcom/android/internal/policy/impl/GlobalActions$BondB;
invoke-direct {v1, p0}, Lcom/android/internal/policy/impl/GlobalActions$BondB;-><init>(Lcom/android/internal/policy/impl/GlobalActions;)V
.line 386
.local v1, conn:Landroid/content/ServiceConnection;
iget-object v3, p0, Lcom/android/internal/policy/impl/GlobalActions;->mContext:Landroid/content/Context;
const/4 v5, 0x1
invoke-virtual {v3, v2, v1, v5}, Landroid/content/Context;->bindService(Landroid/content/Intent;Landroid/content/ServiceConnection;I)Z
move-result v3
if-eqz v3, :cond_1
.line 387
iput-object v1, p0, Lcom/android/internal/policy/impl/GlobalActions;->mScreenshotConnection:Landroid/content/ServiceConnection;
.line 388
iget-object v3, p0, Lcom/android/internal/policy/impl/GlobalActions;->mHandler:Landroid/os/Handler;
iget-object v5, p0, Lcom/android/internal/policy/impl/GlobalActions;->mScreenshotTimeout:Ljava/lang/Runnable;
const-wide/16 v6, 0x2710
invoke-virtual {v3, v5, v6, v7}, Landroid/os/Handler;->postDelayed(Ljava/lang/Runnable;J)Z
.line 390
:cond_1
monitor-exit v4
goto :goto_0
.end local v0 #cn:Landroid/content/ComponentName;
.end local v1 #conn:Landroid/content/ServiceConnection;
.end local v2 #intent:Landroid/content/Intent;
:catchall_0
move-exception v3
monitor-exit v4
:try_end_0
.catchall {:try_start_0 .. :try_end_0} :catchall_0
throw v3
.end method
Few Things to remeber:-
1) The ID's Need to be Same as in public.xml or else boot loop will shake your hands.
2) The register values like - v0,v1,v2.... need to be managed like what it is in your GlobalActions.smali. For the Comparison I have attached My-GlobalActions.smali for comparison.
Just change the extention from zip to smali.
3) I am also human and will be here after my daily life. So please have patience. I will try to get you out of your problem, if and only if you have a adb logcat.
4) If you find any difficulties then post it in the thread.
The Results after successful completion of this will be same as screenshot.
http://dl.xda-developers.com/attach.../7/6/5/2/2/Screenshot_2013-08-09-02-00-21.jpg
Last But Not Least - Don't get bothered to hit thanks. It will not cost you anything but will surely increase my courage to work and try new things.
Awesome Guide My Brother!!
Happy Eid Mubarak to You and rest of your family
Dzol Cp said:
Awesome Guide My Brother!!
Happy Eid Mubarak to You and rest of your family
Click to expand...
Click to collapse
Thanks a lot brother...
Happy EID to you and The whole XDA family of ours brother...
"""Hitting Thanks Don't Cost You Anything So Why Don't You Try Hitting It......."""
Sent From Mind Blowing Canvas Using SUVI-Heart Rom.....<3<3<3
"Happy EID to you all and the whole XDA Family "
Hey, i want to ask something. What is the meaning of line 315 on this ".line315 new-instance v4, Ljava/lang/Object;"? Sorry, just want to know a bit java programming Thanks for your help
i manage to make it bro..sadly after pressing screenshot my phone reboots..but recovery is working just fine..great tut..
BOND1987 said:
Thanks a lot brother...
Happy EID to you and The whole XDA family of ours brother...
"""Hitting Thanks Don't Cost You Anything So Why Don't You Try Hitting It......."""
Sent From Mind Blowing Canvas Using SUVI-Heart Rom.....<3<3<3
Click to expand...
Click to collapse
I did as your followers. click on the menu button to display the power source immediately my phone reboot
Looking forward to your help
vuong95vjpboy said:
I did as your followers. click on the menu button to display the power source immediately my phone reboot
Looking forward to your help
Click to expand...
Click to collapse
Upload you global actions.smali and public.xml of framework....
"" Hitting Thanks Will Not Cost You Anything, So, Why Don't You Try Hitting It Once.....""
Sent While Checking The "AMOI 4.2.2 Beast".....
BOND1987 said:
Upload you global actions.smali and public.xml of framework....
"" Hitting Thanks Will Not Cost You Anything, So, Why Don't You Try Hitting It Once.....""
Sent While Checking The "AMOI 4.2.2 Beast".....
Click to expand...
Click to collapse
Hi sir, my GlobalActions.smali has different with your file, so i dont know put the code in what line
Can you help me? I attach my original GlobalActions.smali, can you mod the code help me? Thanks!
The id in my framework is:
Code:
<public type="drawable" name="bond_recovery" id="0x010805ef" />
<public type="drawable" name="bond_screenshot" id="0x010805f0" />
<public type="string" name="global_action_screenshot_txt" id="0x010404d5" />
<public type="string" name="global_action_recovery_txt" id="0x010404d6" />
My phone was use MTK chipset, ICS 4.0.4. Here is my power menu screenshot
Thanks!
^
^
@BOND1987 Can you help me sir? Thanks!
sieuan said:
^
^
@BOND1987 Can you help me sir? Thanks!
Click to expand...
Click to collapse
Yes brother,
Of course I'll help you. Yesterday night I corrupted my windows so brother you have to wait for today and tomorrow I'll do this for you.
BOND1987 said:
Yes brother,
Of course I'll help you. Yesterday night I corrupted my windows so brother you have to wait for today and tomorrow I'll do this for you.
Click to expand...
Click to collapse
Thanks sir!
After follow the guide in this thread: http://forum.xda-developers.com/showthread.php?t=2225970, I succes add 3-Way boot to Power Menu, and it work good
Before:
After:
Now, can you help me add screenshot option into Power Menu, sir? Here is my GlobalActions.smali. Thanks!
sieuan said:
Thanks sir!
After follow the guide in this thread: http://forum.xda-developers.com/showthread.php?t=2225970, I succes add 3-Way boot to Power Menu, and it work good
Before:
After:
Now, can you help me add screenshot option into Power Menu, sir? Here is my GlobalActions.smali. Thanks!
Click to expand...
Click to collapse
I absolutely love your set up. What ROM / Theme is that?
babalonius508 said:
I absolutely love your set up. What ROM / Theme is that?
Click to expand...
Click to collapse
A Vietnamese ROM, for a Chinese phone, modify by me with light holo theme, apex launcher and miui v5 icon pack.
That's a very cool setup! Thanks!
I can't seem to open the GlobalActions.smali in the OP for comparison because it says its corrupt? Any one else have this problem?
babalonius508 said:
That's a very cool setup! Thanks!
I can't seem to open the GlobalActions.smali in the OP for comparison because it says its corrupt? Any one else have this problem?
Click to expand...
Click to collapse
Brother,
Change the extension of zip to .Smali.
Or try opening with notepad++ and you will be able to coordinate with the guide as well.
If you get any problems further to this, just let me know by post it in this thread.
BOND1987 said:
Brother,
Change the extension of zip to .Smali.
Or try opening with notepad++ and you will be able to coordinate with the guide as well.
If you get any problems further to this, just let me know by post it in this thread.
Click to expand...
Click to collapse
Thanks a lot man! I missed that part of the instructions. Does this modification work for all devices?
babalonius508 said:
Thanks a lot man! I missed that part of the instructions. Does this modification work for all devices?
Click to expand...
Click to collapse
I think brother,
Other than TouchWiz, it will work on all AOSP based devices. Though I'm not sure for this but you can try. If you are in trouble, just let me know.
BOND1987 said:
I think brother,
Other than TouchWiz, it will work on all AOSP based devices. Though I'm not sure for this but you can try. If you are in trouble, just let me know.
Click to expand...
Click to collapse
Thank you for all your help!
For some reason, after I finish the modification, I hold the power button and my phone just reboots. I'm not sure what I'm doing wrong.
Here is my framework-res.apk: https://db.tt/xy0QGFiH
And my androidpolicy.jar: https://db.tt/IOe6JAkn
And a logcat: https://db.tt/EiN6Qcot
Thank you again!
babalonius508 said:
Thank you for all your help!
For some reason, after I finish the modification, I hold the post menu and my phone just reboots. I'm not sure what I'm doing wrong.
Here is my framework-res.apk: https://db.tt/xy0QGFiH
And my androidpolicy.jar: https://db.tt/IOe6JAkn
And a logcat: https://db.tt/EiN6Qcot
Thank you again!
Click to expand...
Click to collapse
Brother,
Give me 24 hours only to take look on your files. And I will revert you back as soon as possible. Thanks for posting it here. I appreciate your support brothers.
That sounds great! Thank you! I really hope I can get it working.
Sent from my Nexus 4
After searching months for a way to allow Unknown Sources by default on the HTC One, I've finally discovered where to mod it so I thought I would share for the benefit of the community. Its one of the more convenient mods to have and I thought it would be a great for lazy people like me who want to quickly restore their setup while trying other roms and not have to deal with Blocked install messages lol.
You will need to have apktool or similar tools and decompiling knowledge before attempting this.
Previously you would need to mod SettingsProvider.apk but on Sense 5 that is no longer the case. There are two APK's to look at here. PureC_PackageInstaller and Settings.apk. PureC is the main one you want to look at.
Decompile PureC_PackageInstaller and find this directory in smali folder:
\smali\com\android\packageinstaller\PackageInstallerActivity.smali
open up PackageInstallerActivity.smali and look for this method:
Code:
.method private isInstallingUnknownAppsAllowed()Z
.locals 3
.prologue
const/4 v0, 0x0
.line 261
invoke-virtual {p0}, Lcom/android/packageinstaller/PackageInstallerActivity;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v1
const-string v2, "install_non_market_apps"
invoke-static {v1, v2, v0}, Landroid/provider/Settings$Secure;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v1
if-lez v1, :cond_0
const/4 v0, 0x1
:cond_0
return v0
.end method
change
Code:
.locals 3
.prologue
const/4 v0, 0x0
.line 261
to this
Code:
.locals 3
.prologue
const/4 v0, 0x1
.line 261
recompile and you are done
next decompile Settings.apk(optional!)
the only reason to edit this is to give the mod the appearance that Unknown Sources is visibly checked in Settings menu, otherwise the mod still works fine even if it isn't checked.
find this directory:
\smali\com\android\settings\SecuritySettings.smali
locate this method:
Code:
.method private isNonMarketAppsAllowed()Z
.locals 3
const/4 v0, 0x0
invoke-virtual {p0}, Lcom/android/settings/SecuritySettings;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v1
const-string v2, "install_non_market_apps"
invoke-static {v1, v2, v0}, Landroid/provider/Settings$Secure;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v1
if-lez v1, :cond_0
const/4 v0, 0x1
:cond_0
return v0
.end method
change the 0x0 to 0x1, and change the 0x1 to 0x0.
recompile and your done.
tested this and working on Sprint HTC One variant, but i'm almost certain this should work on any carrier with version of Sense 5.
also of note: there is a small glitch to this mod while toggling the checkbox on and off. it'll recheck itself if you turn it off and come back to the options screen again. Plus, I turned off the disabled function completely as a temporary solution because there was another glitch where you couldn't install apps while it was checked on if you messed around trying to turn it off, but why would you want to? lol
You can also just edit the default.xml in customize
<item name="def_install_non_market_apps">1</item>
Sent from my HTCONE using Tapatalk 2
is there any way to do this in android10 ?
hi guys,
anyone an idea to disable (hack, apk, ...) the wifi popup notification whenever wifi is connected.
This drives me crazy ...
This notification is absolutely senseless, when connection is on i see it in the notification bar ...
I found a description but only for S III Verizon.
JackoMJ
JackoMJ said:
hi guys,
anyone an idea to disable (hack, apk, ...) the wifi popup notification whenever wifi is connected.
This drives me crazy ...
This notification is absolutely senseless, when connection is on i see it in the notification bar ...
I found a description but only for S III Verizon.
JackoMJ
Click to expand...
Click to collapse
Hi! Try this:
- decompile secsettings.apk
- go to file "smali\com\android\settings\wifi\WifiStatusReceiver.smali"
- open in notepad++ and find this code:
Code:
.line 194
invoke-virtual {v3}, Landroid/widget/Toast;->getView()Landroid/view/View;
move-result-object v1
const v4, 0x102000b
invoke-virtual {v1, v4}, Landroid/view/View;->findViewById(I)Landroid/view/View;
move-result-object v1
check-cast v1, Landroid/widget/TextView;
.line 195
const/16 v4, 0x11
invoke-virtual {v1, v4}, Landroid/widget/TextView;->setGravity(I)V
.line 196
[COLOR="Red"]invoke-virtual {v3}, Landroid/widget/Toast;->show()V[/COLOR]
goto :goto_1a3
And change it to (just add # before it):
Code:
[COLOR="Red"]#invoke-virtual {v3}, Landroid/widget/Toast;->show()V[/COLOR]
Thats all - save, recompile, copy to phone, restart and hope
somin.n said:
Hi! Try this:
- decompile secsettings.apk
- go to file "smali\com\android\settings\wifi\WifiStatusReceiver.smali"
- open in notepad++ and find this code:
Code:
.line 194
invoke-virtual {v3}, Landroid/widget/Toast;->getView()Landroid/view/View;
move-result-object v1
const v4, 0x102000b
invoke-virtual {v1, v4}, Landroid/view/View;->findViewById(I)Landroid/view/View;
move-result-object v1
check-cast v1, Landroid/widget/TextView;
.line 195
const/16 v4, 0x11
invoke-virtual {v1, v4}, Landroid/widget/TextView;->setGravity(I)V
.line 196
[COLOR="Red"]invoke-virtual {v3}, Landroid/widget/Toast;->show()V[/COLOR]
goto :goto_1a3
And change it to (just add # before it):
Code:
[COLOR="Red"]#invoke-virtual {v3}, Landroid/widget/Toast;->show()V[/COLOR]
Thats all - save, recompile, copy to phone, restart and hope
Click to expand...
Click to collapse
Hi somin mf,
WHAT THE HELL IS GOING ON?
you are the best. Works perfect. No f****** popup any more.
How do you know or find this out because i think it´s not easy to make it.
JackoMJ
JackoMJ said:
How do you know or find this out because i think it´s not easy to make it.
Click to expand...
Click to collapse
Hehe, you are true, it is not so easy, maybe it was luck that I find it. How I find it?
- i was looking for wifi is connected to bla,bla,bla string in system apk's
- then I find its public id in public.xml file
- then I was looking for this id in *.smali files
- and then it was luck that I find proper line "invoke-virtual {XX}, Landroid/widget/Toast;->show()V", I just know that this line is making toast messages
There was some bad tests, but one of my try was working. And here is result
somin.n said:
Hehe, you are true, it is not so easy, maybe it was luck that I find it. How I find it?
- i was looking for wifi is connected to bla,bla,bla string in system apk's
- then I find its public id in public.xml file
- then I was looking for this id in *.smali files
- and then it was luck that I find proper line "invoke-virtual {XX}, Landroid/widget/Toast;->show()V", I just know that this line is making toast messages
There was some bad tests, but one of my try was working. And here is result
Click to expand...
Click to collapse
Thanks for your time and patience you spent on it.
Do you make every test like me (decompile, change, compile, copy to phone, reboot)?
Hope your Powerbutton won´t break
Or is there a program you can simulate it on your pc without using your phone really?
That´s a very interesting question i think....
JackoMJ
JackoMJ said:
Thanks for your time and patience you spent on it.
Do you make every test like me (decompile, change, compile, copy to phone, reboot)?
Hope your Powerbutton won´t break
Or is there a program you can simulate it on your pc without using your phone really?
That´s a very interesting question i think....
JackoMJ
Click to expand...
Click to collapse
Yes one change and whole process with de/compile,restart,... in round. Don't know about pc sw to simulate it, but yes it would be great. And don't worry about my power button, sometimes I have to pull out my battery because of bootloop :laugh::victory:
I posted this in S2 section a while ago but after talking with a senior mod I'm posting here as its useful on this device
Firstly I am by no means an expert and am just trying to share what i have learnt about smali as its hard to find much info about general smali. Contributions to the thread are always welcome
For the last year or so I have been developing AllianceROM on the i9100. During this time I have learnt lots about smali through a combination of trial and error and guides I have found here on XDA. The guides are great but one thing that stands out is that they all follow the same pattern of “Find a certain line in a certain file and copy/paste" to replace methods or chunks of code for the desired outcome. Whilst this is a great means to an end it is only a means to that particular end. Most people wont actually understand what they are doing or how it works and will blindly do as instructed.
So I thought that I would try to write some general guides. The aim is to give you the means to dream up your own mods and know how to go about implementing them from scratch by yourself. As I say, I am by no means an expert but hopefully there should be enough here to set you on your way. These are the methods I used to create many of the mods in alliance, lots of which didn’t exist on Touchwiz devices before.
You will need certain tools to do this but I am not going into how to decompile etc. Before attempting this you should have a good knowledge of decompiling apks and modding in general and have the following tools available:
ADB
Notepad ++
A good image editor like Photoshop or GIMP
The guides are in 3 sections:
Coloring stuff with color pickers
Toggling stuff to show or hide
List choices for things like toggles in view etc
For the purposes of these guides I am using an apk from our legendary alliance developer ficeto. He has made this app to enable us to easily add color pickers, checkboxes and lists by adding a single line to an xml. Huge huge thanks to him as he made this a lot easier!! You can use this to test your mods but please dont rename everything from ficeto to "ubermodders" or something and try to pass it off as your own. If you do it will be reported It is to be used as is, not changed or renamed (this causes problems for people installing alliamceMOD) and dont forget to credit ficeto!!
Please feel free to ask general smali questions here too!
So lets get started!!
Coloring Stuff:
Text Colors
There is a ton of stuff in alliance that can be colored, from text to images or backgrounds. Text works by using the setTextColor method and images and backgrounds use setColorFilter to lay a color over the top of an image ot setBackgroundColor to fill the entire background. I will cover one of each in this section starting with text color. The 3 methods use similar code and text color is the easiest to start with.
So….you decide you want to change the color of some text using a picker. For this example I will use the dropdown date. Where do you start? As you probably know dropdown stuff is dealt with by SystemUI.apk. When you decompile that you are faced with a ton of smali files. The best way to start is to use a handy function in Notepad++ called “Find in Files” which will search for certain text within files. Funnily enough its under the Search menu at the top!!
In this case the first port of call would be to search for the obvious word “date”. This returns a ton of results and you should see an obvious file called DateView.smali. If your search doesn’t return much for your specific choice of text then you have a couple of options:
1) look in the layout xml and find the id for the view you want to change. Look the id up in public.xml and then search that using “Find in Files” again. If you are unsure of the text view id then use hierarchy viewer from the tools folder of the sdk which will show you all the views on your screen
2) look through the smali files manually for anything that sounds like it might contain your target
So you think you found the right smali. Open it and search for “setText(Ljava/lang/CharSequenceV”. This will hopefully return a line something like this:
invoke-virtual {p0, v5}, Lcom/android/systemui/statusbar/policy/DateView;->setText(Ljava/lang/CharSequenceV
Scroll up until you see the name of the method. This should give you a good idea if you have the right text. In this case that line was in .method private final updateClock()V which sounds about right!
What this line is doing is calling settext with the parameter Ljava/lang/CharSequence which is the date string. Invoke virtual calls the method and the bit in the brackets {p0, v5} is the date view (p0 means “this file”) and the string (v5). The v is a register. Registers are used to store things. A few lines up in the method you will see something similar to this:
invoke-virtual {v0, v9, v5}, Landroid/content/Context;->getString(I[Ljava/lang/ObjectLjava/lang/String;
move-result-object v5
What that is doing is using getString to get the date and moving it into the register v5. This v5 is then used in our setText call.
So now we have identified our text view in the smali we can use setTextColor to change its color.
A bit of background is useful here. Color pickers do not act directly on any smali. Your phone has a database where it stores its settings. It is located in data/data/com.android.providers.settings/databases/settings.db. You can open it with Root Explorer and take a look. You will see a standard database with entries and values. What color picker code does is put an entry in this database with a “key” and a hex code. The smali then uses this key to look up the hex color it needs to set.
Now we need to add some code to look up that entry and return the color to the smali. There are 3 elements to this:
The ContentResolver
This is used to resolve the entry in the database. In order to use the content resolver we must put it into a register as we mentioned earlier. At the top of the method you will see .locals X where X is a number. This is the number of registers used in the method. So if it says .locals 5 there will be v0,v1,v2,v3 and v4. We need to add 3 to this value as we will be using 3 new registers. One for the resolver, one for the default color (in case there is no entry in the database it needs to have a color to set) and one for the key.
Now we need context in order to get the content resolver. There are a few ways to do this. A lot of files have a field called mContext. This can be used directly like this:
iget-object v5, p0, Lcom/android/systemui/statusbar/policy/BrightnessController;->mContext:Landroid/content/Context;
This is using iget-object to put mContext into v5. As mentioned earlier the p0 mean “this”.
The v5 should be the first of the new registers you added. So if previously .locals was 5 and you changed it to 8 then this would be v5 as v0 to v4 already exist. You can reuse registers but you can run into problems if it is needed further through the code so it is advisable to add new.
Alternatively, smali files whose .super is a view (look at the top of the smali for .super) like the date view we are working with here can use getcontext to get context like this:
invoke-virtual {p0}, Lcom/android/systemui/statusbar/policy/DateView;->getContext()Landroid/content/Context;
move-result-object v5
Now we have context we can use it to get the content resolver and put it into the register using this line:
invoke-virtual {v5}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v5
The Key
Next we need the key that we want to look up in the database. This is as simple as :
const-string v6, "date_color"
This just puts the constant string “date_color” into v6. The text inside the “” can be anything you like but cannot have spaces and the key must match the picker key we will add later.
The Default Value
Next we need a default color for in case there is no entry in the database. For example on a fresh install or after a wipe. The value is hex but in reverse preceded with -0x so ICS blue 33b5e5 becomes -0xcc4a1a because 0 = F, 1 = E, 2 = D etc
0 = F
1 = E
2 = D
3 = C
4 = B
5 = A
6 = 9
7 = 8
8 = 7
9 = 6
A = 5
B = 4
C = 3
D = 2
E = 1
F = 0
We put that into our 3rd new register v7 using:
const v7, -0xcc4a1a
Now we have all the needed elements we can use them to return the color to the smali from the database using:
invoke-static {v5, v6, v7}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v5
This uses the getInt method with our parameters. I have colored them so you can see how the registers relate to the getInt method. V5 is the content resolver, v6 is the string and v7 is the integer of the color.
The resultant color from the database is then moved into v5. We can use v5 register again as we no longer need the content resolver.
The color from the database is now stored in v5. From the settext line we found earlier we can see that the text view is referred to as p0:
invoke-virtual {p0, v5}, Lcom/android/systemui/statusbar/policy/DateView;->setText(Ljava/lang/CharSequenceV
The first item in the brackets is the text view. This wont be p0 in all cases. Its only p0 here because we are working with a smali that has a view as its super so the smali is effectively the text view. If working with something like ToggleSlider for example we may have something like:
invoke-virtual {v2, v3}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequenceV
So in this case the text view is in v2.
We can now use setTextColor on our date which is p0 with the color which we put in v5:
invoke-virtual {p0, v5}, Lcom/android/systemui/statusbar/policy/DateView;->setTextColor(I)V
The full code looks like this:
invoke-virtual {p0, v3}, Lcom/android/systemui/statusbar/policy/DateView;->setText(Ljava/lang/CharSequenceV
invoke-virtual {p0}, Lcom/android/systemui/statusbar/policy/DateView;->getContext()Landroid/content/Context;
move-result-object v5
invoke-virtual {v5}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v5
const-string v6, "date_color"
const v7, -0xcc4a1a
invoke-static {v5, v6, v7}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v5
invoke-virtual {p0, v5}, Lcom/android/systemui/statusbar/policy/DateView;->setTextColor(I)V
Oh and just so you know the big V at the end of lines like ;->setText(Ljava/lang/CharSequenceV and ;->setTextColor(I)V means the method returns void or nothing.
Hopefully the apk will now compile and you can test the result. In order for something to change immediately you need observers but I wont go into that here. This will only change when the updateClock method runs. A reboot will also trigger it to update the color.
I know I have written a lot to take in here. But hopefully this will give you a good basic understanding of how methods are called with parameters in smali.
Next stop…..choosing the color!
Thanks to ficeto this part is REALLY easy!
Decompile the attached apk. You will find a file called preferences.xml in the xml folder. Open it with Notepad++. Each instance of this line will add another picker…
<com.ficeto.colorpicker.ColorPickerPreference android:title="Dropdown Date Color" android:key="date_color" android:summary="Select Color" android:dialogTitle="Select Color" />
Change the android:title to what you want your picker to be called and change android:key=“date_color” to whatever the key you used earlier was. So if your smali was....
const-string v6, "clock_color"
Then the android:key would be “clock_color”.
That’s it. Compile and push the apk or install as a system app and it will show in your app drawer as custom settings. Now go test your new mod!!
Any questions or problems please ask (with logs and files if possible) as its impossible to cover all eventualities in a guide.
OK....time for part 2
COLORING IMAGES
This part will cover two things. Coloring images in a similar way to setting text colors from part 1 and also how to create a method and pass it context. Sometimes you wont be able to use mContext or getcontext but most smali files have context already in their init so you can use that and pass it to a new method. Using your own method is more efficient as you can run your code to get the color from the database just once and use it on multiple items and in multiple places.
There are three main ways to color an image. Using the method setColorFilter(I)V which is in android/widget/ImageView smali in framework2.jar, using method public final setColorFilter(ILandroid/graphics/PorterDuff$ModeV in the same file and using method public setColorFilter(ILandroid/graphics/PorterDuff$ModeV in android/graphics/drawable/Drawable smali in framework.jar. It depends what and where the image is as to which you use. All three methods overlay a color on an existing image and the two with porterduffmode have a means of choosing what effect the overlay has. There is more about this at the bottom of the post.
Lets start....
Things are stored in fields in a smali. At the top of the file you will see them like this:
Code:
.field protected mType:Ljava/lang/String;
.field protected mView:Landroid/view/View;
.field protected mIcon:I
These fields can be used to store things of their type. So in the ones shown above you would put a string, a view and an integer respectively. You can see the type a field should hold after the :
In order to use your own method to get the color from the database we need to add a new field to store the value in so we can use it in another method. For this example i am going to use the toggle icons in lidroids toggle mod but this can be done on pretty much any image you want.
At the top of the smali with the other instance fields add your new field. You can call it whatever you want and it is going to store an integer so you will need an I after the colon. Im calling this one mToggleColor for obvious reasons:
Code:
.field private mToggleColor:I
We now have somewhere to put our value so now we can write the new method. At this point you should refer to the text color guide for explanations about the content resolver, context and registers as I will assume you have an idea about these now.
You can call your method anything you want. It will need 3 registers to store the resolver, default value and integer. This method has no context parameter (in the brackets after the method name) so you would need to use getcontext or mContext....
Code:
.method color_toggles()V
.locals 3
If you are going to use existing context and pass it to your method it would look like this. As you can see the method is expecting context as its parameter when called...
Code:
.method color_toggles(Landroid/content/Context;)V
.locals 3
Now we get the content resolver so we need context. If using the first method then you would need to call your view and invoke getcontext like this in stock toggles:
Code:
iget-object v1, p0, Lcom/android/systemui/statusbar/policy/quicksetting/QuickSettingButton;->mBtnImage:Landroid/widget/ImageView;
invoke-virtual {v1}, Landroid/widget/ImageView;->getContext()Landroid/content/Context;
move-result-object v1
invoke-virtual {v1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v1
As metioned in the text color guide your contentresolver is now in v1.
If you are passing context to your method then the context is the parameter of the method. Each item in brackets after methods name is stored in a p. So in this case the context would be in p1. All you need to do is use it to get the resolver:
Code:
invoke-virtual {p1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v1
Again...resolver now in v1.
The next part is identical to the text color guide so i wont repeat it. But you should have now something that looks like this:
Code:
.method color_toggles()V
.locals 3
iget-object v1, p0, Lcom/android/systemui/statusbar/policy/quicksetting/QuickSettingButton;->mBtnImage:Landroid/widget/ImageView;
invoke-virtual {v1}, Landroid/widget/ImageView;->getContext()Landroid/content/Context;
move-result-object v1
const-string v2, "theme_color"
const v3, -0x4d06ff
invoke-static {v1, v2, v3}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v1
or if passing context:
Code:
.method color_toggles(Landroid/content/Context;)V
.locals 3
invoke-virtual {p1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v1
const-string v2, "theme_color"
const v3, -0xcc4a1a
invoke-static {v1, v2, v3}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v1
Both of the above now have your color stored in v1. We can now put it into your new field that you created earlier using iput:
Code:
iput v1, p0, Lcom/alliance/systemui/quickpanel/PowerButton;->mToggleColor:I
This puts the integer in v1 into the field in p0 (this file) and stores it as mToggleColor
Your method is not expected to return anything meaning something doesnt call it and ask for a value in reply so after this we need:
Code:
return-void
....and then to finish the method....
Code:
.end method
The final methods look like this:
Code:
.method color_toggles()V
.locals 3
iget-object v1, p0, Lcom/android/systemui/statusbar/policy/quicksetting/QuickSettingButton;->mBtnImage:Landroid/widget/ImageView;
invoke-virtual {v1}, Landroid/widget/ImageView;->getContext()Landroid/content/Context;
move-result-object v1
const-string v2, "theme_color"
const v3, -0x4d06ff
invoke-static {v1, v2, v3}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v1
iput v1, p0, Lcom/android/systemui/statusbar/policy/quicksetting/QuickSettingButton;->mToggleColor:I
return-void
.end method
Code:
.method color_toggles(Landroid/content/Context;)V
.locals 3
invoke-virtual {p1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v1
const-string v2, "theme_color"
const v3, -0xcc4a1a
invoke-static {v1, v2, v3}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v1
iput v1, p0, Lcom/alliance/systemui/quickpanel/PowerButton;->mColor:I
return-void
.end method
Now your color can be put into your new field we need to invoke your new method. Otherwise it will just be an empty field. You can do this in a number of places. Either directly before you use it or in the methods init. We will come back to this.
In order to color an image you need to find it first. There are ways of calling the image by its id but looking for it this way will familiarise you more with smali. Images can be set using setImageResource and setImageDrawable. If you search firstly for the images id in the smalis to find the correct file and if that doesnt find anything then have a look at file names and see what you can find that looks like it might be right. In this case PowerButton smali has a method called :
Code:
.method private updateImageView(II)V
...which uses setImageResource(I)V. Sounds like a good place to start!
Code:
.method private updateImageView(II)V
.locals 2
iget-object v1, p0, Lcom/alliance/systemui/quickpanel/PowerButton;->mView:Landroid/view/View;
invoke-virtual {v1, p1}, Landroid/view/View;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, Landroid/widget/ImageView;
invoke-virtual {v0, p2}, Landroid/widget/ImageView;->setImageResource(I)V
return-void
.end method
We need to invoke your new method. If you are not passing context you can just do this:
Code:
invoke-virtual {p0}, Lcom/android/systemui/statusbar/policy/quicksetting/QuickSettingButton;->color_toggles()V
...which will invoke your new method and put your color in your field.
Or to pass context you would do:
Code:
invoke-virtual {v1}, Landroid/view/View;->getContext()Landroid/content/Context;
move-result-object v1
invoke-virtual {p0, v1}, Lcom/alliance/systemui/quickpanel/PowerButton;->color_toggles(Landroid/content/Context;)V
In the above code the method you are in has a Landroid/view/View; stored in v1. You can use getContext on this and then invoke your method. The invoke says to call your method color_toggles(Landroid/content/ContextV which is in this file (p0) with the parameter v1 (the context). Now your method has run we can use iget to get the color from the field:
Code:
iget v1, p0, Lcom/alliance/systemui/quickpanel/PowerButton;->mColor:I
You can see in the original updateImage method that the imageView is in v0. We can now apply the color (in v1) to the image (v0).
Code:
invoke-virtual {v0, v1}, Landroid/widget/ImageView;->setColorFilter(I)V
Final methods would look like this:
Code:
.method private updateImageView(II)V
.locals 2
invoke-virtual {p0}, Lcom/android/systemui/statusbar/policy/quicksetting/QuickSettingButton;->color_toggles()V
iget-object v1, p0, Lcom/alliance/systemui/quickpanel/PowerButton;->mView:Landroid/view/View;
invoke-virtual {v1, p1}, Landroid/view/View;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, Landroid/widget/ImageView;
invoke-virtual {v0, p2}, Landroid/widget/ImageView;->setImageResource(I)V
iget v1, p0, Lcom/alliance/systemui/quickpanel/PowerButton;->mColor:I
invoke-virtual {v0, v1}, Landroid/widget/ImageView;->setColorFilter(I)V
return-void
.end method
or
Code:
.method private updateImageView(II)V
.locals 2
iget-object v1, p0, Lcom/alliance/systemui/quickpanel/PowerButton;->mView:Landroid/view/View;
invoke-virtual {v1, p1}, Landroid/view/View;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, Landroid/widget/ImageView;
invoke-virtual {v0, p2}, Landroid/widget/ImageView;->setImageResource(I)V
invoke-virtual {v1}, Landroid/view/View;->getContext()Landroid/content/Context;
move-result-object v1
invoke-virtual {p0, v1}, Lcom/alliance/systemui/quickpanel/PowerButton;->color_toggles(Landroid/content/Context;)V
iget v1, p0, Lcom/alliance/systemui/quickpanel/PowerButton;->mColor:I
invoke-virtual {v0, v1}, Landroid/widget/ImageView;->setColorFilter(I)V
return-void
.end method
Your source image should be white. You can make them semi transparent so the color is not as bright. For example the off toggles could be 50% transparent so they will only appear dim compared to the on ones.
You will notice in PowerButton smali there is another method....
Code:
.method private updateImageView(ILandroid/graphics/drawable/Drawable;)V
.locals 2
iget-object v1, p0, Lcom/alliance/systemui/quickpanel/PowerButton;->mView:Landroid/view/View;
invoke-virtual {v1, p1}, Landroid/view/View;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, Landroid/widget/ImageView;
invoke-virtual {v0, p2}, Landroid/widget/ImageView;->setImageDrawable(Landroid/graphics/drawable/Drawable;)V
return-void
.end method
This is the same except it uses 2 parameters (in the brackets after the name) of and (I)nteger and Landroid/graphics/drawable/Drawable rather than two (I)ntegers.
You don't HAVE to use your own method. You could just use identical code to the textColor code straight after the setImageResource and invoke setColorFilter on the ImageView rather than setTextColor on a TextView. But I think it is good practice to use a new method
PorterDuffMode
Sometimes when you implement a color picker you will get an outcome you dont want like a battery that had a a white centre and the fill in a color wouldnt show the level as it would all have the same color overlay. Instead of using setColorFilter(I)V you can use setColorFilter(ILandroid/graphics/PorterDuff$ModeV.
If you are familiar with Photoshop you may be better than me at this but basically it changes the way the color is laid over. Using different modes will give different results. As Im not great with Photoshop for me its more trial and error!
There are lots of different modes:
PorterDuff.Mode ADD Saturate(S + D)
PorterDuff.Mode CLEAR [0, 0]
PorterDuff.Mode DARKEN [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)]
PorterDuff.Mode DST [Da, Dc]
PorterDuff.Mode DST_ATOP [Sa, Sa * Dc + Sc * (1 - Da)]
PorterDuff.Mode DST_IN [Sa * Da, Sa * Dc]
PorterDuff.Mode DST_OUT [Da * (1 - Sa), Dc * (1 - Sa)]
PorterDuff.Mode DST_OVER [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc]
PorterDuff.Mode LIGHTEN [Sa + Da - Sa*Da, Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)]
PorterDuff.Mode MULTIPLY [Sa * Da, Sc * Dc]
PorterDuff.Mode OVERLAY
PorterDuff.Mode SCREEN [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]
PorterDuff.Mode SRC [Sa, Sc]
PorterDuff.Mode SRC_ATOP [Da, Sc * Da + (1 - Sa) * Dc]
PorterDuff.Mode SRC_IN [Sa * Da, Sc * Da]
PorterDuff.Mode SRC_OUT [Sa * (1 - Da), Sc * (1 - Da)]
PorterDuff.Mode SRC_OVER [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc]
PorterDuff.Mode XOR [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
The letters in CAPITALS are the what you put as the parameter.
I have found that MULTIPLY is the most useful. SRC_ATOP is used as default in setColorFilter(I)V
To use one you need to put the mode into a register. You do that using sget:
Code:
sget-object v1, Landroid/graphics/PorterDuff$Mode;->MULTIPLY:Landroid/graphics/PorterDuff$Mode;
Then you call the porterduff setcolorfilter method instead of the normal one. Like this:
invoke-virtual {v6, v12, v1}, Landroid/widget/ImageView;->setColorFilter(ILandroid/graphics/PorterDuff$ModeV
...instead of this:
invoke-virtual {v6, v12}, Landroid/widget/ImageView;->setColorFilter(I)V
There is a good article here
Please ask if anything is unclear.
Toggles
You have learnt how to get a value from the database creating a toggle is pretty straightforward. For this example I will use toggling the text on lidroid toggles but you can use this on anything from settings button in statusbar to things stopping auto scroll on toggles etc.
Again we start by finiding the method we need to mod. Look at the top of smali files for the field names. This may help you to find the item you wish to toggle. Method names will also help you find your place. In this example we can see in PowerButton smali there is a method called:
Code:
.method protected updateText()V
Obvious huh! It wont always be that easy to find so i will cover how to call something by it's ID later in this post.
In this method you can see that the text is set by calling the setText method. There are two ways to do this. The obvious thing to do is not to run this line so the text will not be set. This is the first way i will cover and it is the way that things are toggled such as ink effect or crt etc rather than showing/hiding things. I will get to that later.
TURNING THINGS ON/OFF
We need to read that value into our smali. This is done in exactly the same way as a color so if you are not sure please go back and read those posts.
This would be added the line before the setText call....
Code:
iget-object v3, p0, Lcom/alliance/systemui/quickpanel/PowerButton;->mView:Landroid/view/View;
invoke-virtual {v3}, Landroid/view/View;->getContext()Landroid/content/Context;
move-result-object v3
...dont forget to add to .locals if you are using a new register!! That gets us context so now we can...
Code:
const-string v4, "toggle_text"
const v5, 0x1
invoke-static {v3, v4, v5}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v3
...which gets the value from the database which will be 1 or 0 for on/off and puts it into v3.
To toggle something we then act on that value. The if-nez checks if a value is non-zero. So the next line would be:
Code:
if-nez v3, :cond_skip_text
....as you can see, if v3 is non-zero then it goes to the condition skip_text.
All we need to do now is make a new cond called skip_text after the setText line so it effectively does just that.....skips the setText. Right before return-void put:
Code:
:cond_skip_text
That's it. All you have to do with a toggle to turn something on or off is skip the chunk of text that does what you want to stop. So as long as your new cond comes after it then it should work
SHOWING/HIDING
This works in exactly the same way as above but instead of skipping code you are going to use setVisibility(I)V method.
We have got the value from the database as we did before:
Code:
iget-object v3, p0, Lcom/alliance/systemui/quickpanel/PowerButton;->mView:Landroid/view/View;
invoke-virtual {v3}, Landroid/view/View;->getContext()Landroid/content/Context;
move-result-object v3
const-string v4, "toggle_text"
const v5, 0x1
invoke-static {v3, v4, v5}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v3
if-nez v3, :cond_show_text
To hide something we must set visibility of the item to "gone". The value for this is 0x8. Visible is 0x1. If the database value returns 0 then the item is unchecked and so should be hidden. If it returns 1 then the item should be visible.
If the value from the database was 1 and the checkbox was ticked then you can use the value in v3 as the value for setVisibility. If it was 0 then the value needs to be set to 0x8 for "gone". We can put 0x8 into v4 here because the line will be skipped if the checkbox was checked:
Code:
const v3, 0x8
....now we add the new cond:
Code:
:cond_show_text
and invoke the set visibility which now has either 0x1 or 0x8 in it.
Code:
invoke-virtual {v1, v3}, Landroid/widget/TextView;->setVisibility(I)V
This tells the code to find the place labelled :goto_new so we add that straight after the code that sets visibility to shown. The full code would look like this....
Code:
iget-object v3, p0, Lcom/alliance/systemui/quickpanel/PowerButton;->mView:Landroid/view/View;
invoke-virtual {v3}, Landroid/view/View;->getContext()Landroid/content/Context;
move-result-object v3
const-string v4, "toggle_text"
const v5, 0x1
invoke-static {v3, v4, v5}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v3
if-nez v3, :cond_show_text
const v4, 0x8
:cond_show_text
invoke-virtual {v1, v4}, Landroid/widget/TextView;->setVisibility(I)V
Thats it!
CALLING THINGS BY ID
Say you wanted to make a show/hide for the recents button that can be added to dropdown header. You can call it by it's public ID and then use setvisibility. Create a new method like you did for coloring images (refer to that guide if unsure), get a value from the database, test for non-zero and skip to cond. You can use mCcontext here from in Phonestatusbar:
Code:
.method Update_recents()V
.locals 6
iget-object v1, p0, Lcom/android/systemui/SystemUI;->mContext:Landroid/content/Context;
invoke-virtual {v1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v1
const-string v2, "recents_button"
const/4 v3, 0x1
invoke-static {v1, v2, v3}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v3
if-nez v3, :cond_1
const v3, 0x8
Now to get the image we can use findViewById method. In order to use it we need the parent view that contains the image. In Phonestatusbar you can get to most stuff by using the field mStatusBarWindow.
Code:
iget-object v4, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarWindow:Lcom/android/systemui/statusbar/phone/StatusBarWindowView;
Now we get the id of the image from public.xml and put it into a register:
Code:
const v5, 0x7f0d0014
....and then findViewById. This method expects an integer as a parameter which we have in v5...
Code:
invoke-virtual {v4, v5}, Lcom/android/systemui/statusbar/phone/StatusBarWindowView;->findViewById(I)Landroid/view/View;
move-result-object v4
Now we have the item we can setVisibility with the value in v3:
Code:
:cond_1
invoke-virtual {v4, v3}, Landroid/widget/LinearLayout;->setVisibility(I)V
In this case I used LinearLayout but you can use imageView or whatever depending what you are doing. The full method would look like this:
Code:
.method Update_recents()V
.locals 6
iget-object v1, p0, Lcom/android/systemui/SystemUI;->mContext:Landroid/content/Context;
invoke-virtual {v1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v1
const-string v2, "recents_button"
const/4 v3, 0x1
invoke-static {v1, v2, v3}, Landroid/provider/Settings$System;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;I)I
move-result v3
if-nez v3, :cond_1
const/4 v3, 0x8
:cond_1
iget-object v5, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarWindow:Lcom/android/systemui/statusbar/phone/StatusBarWindowView;
const v6, 0x7f0d0014
invoke-virtual {v5, v6}, Lcom/android/systemui/statusbar/phone/StatusBarWindowView;->findViewById(I)Landroid/view/View;
move-result-object v4
invoke-virtual {v4, v3}, Landroid/widget/LinearLayout;->setVisibility(I)V
return-void
.end method
All we need to do now is to call the method. The best place for this is during makestatusbarview. I put it right after the settings button is set but you can put it in loads of places. It just invokes update_recents_button in p0 (this file):
Code:
iget-object v9, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mSettingsButton:Landroid/widget/ImageView;
iget-object v10, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mSettingsButtonListener:Landroid/view/View$OnClickListener;
invoke-virtual {v9, v10}, Landroid/widget/ImageView;->setOnClickListener(Landroid/view/View$OnClickListener;)V
[COLOR="Red"] invoke-virtual {p0}, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->update_recents_button()V[/COLOR]
Thats all for now
USEFUL POSTS:
NOTEPAD++ SMALI HIGHLIGHTING - Thanks to @majdinj
LIST OF DALVIK OPCODES - Thanks to @majdinj
good work Goldie, 5st
Goldie said:
USEFUL POSTS:
NOTEPAD++ SMALI HIGHLIGHTING - Thanks to @majdinj
LIST OF DALVIK OPCODES - Thanks to @majdinj
Click to expand...
Click to collapse
this is great! im good with xml, scripting, binary etc etc, Im starting to learm smali and honestly this guide is perfect to the T! thanks!
Thank you very much, sir!
Keep that great work up.