[T-Mobile Samsung Galaxy Note 3] Morningstar:
Hello everyone...

I've always liked the concept of the Air Command window that pops up when the S Pen is removed, but I didn't like being limited to the 5 options it gave me, as I only ever use two of them. So after much trial and error, I finally came up with a way to replace the defaults with whatever apps you want.

NOTES

Do this at your own risk. I am not responsible for loss of data, bricked devices, or global thermonuclear war resulting from this guide.

***Before proceeding any further,

MAKE A BACKUP

.

***This should work on any stock or stock-based ROM, but it has only been tested on the T-Mobile Galaxy Note 3 (sm-n900t) running Tweaked 3.95

***This is one of my first real forays into smali modding, and I'm still just learning, so while fully-functional, the smali could probably be made 'cleaner' and more efficient. In fact, I'm sure of it. Any tips/suggestions/improvements are more than welcome.

***This guide assumes that you already know how to decompile/compile both .jar and .apk files.

***In order to use different apps, you must be able to find the package name and the main activity (or any other activity you'd like) of the app that you want to use. These can be found by decompiling the app and looking in the AndroidManifest. Some examples:

Sketchbook For Galaxy

Package name: com.adsk.sketchbookhd.galaxy.oem

Activity: com.adsk.sketchbook.SketchBook

Papyrus

Package name: com.steadfastinnovation.android.projectpapyrus

Activity: com.steadfastinnovation.android.projectpapyrus.application.HeadlessMainActivity

MyScript Calculator

Package name: com.visionobjects.calculator

Activity: com.visionobjects.calculator.activity.MainActivity

With all that out of the way, let's begin!

Pull your services.jar from /system/framework and decompile it. The file we are going to be working with is /com/android/server/smartclip/SpenGestureManagerService$6.smali.

TO REPLACE ACTION MEMO

-Either search or scoll all the way down and find this line:

nop

-Erase that line, and paste the following in it's place:

:pswitch_ms1
if-eqz v6, :cond_atd1

:cond_atd1
invoke-static {}, Lcom/android/server/smartclip/SpenGestureManagerService;->access$1300()Ljava/lang/String;

move-result-object v10

invoke-virtual {v10, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v10

const/4 v11, 0x1

if-ne v10, v11, :cond_atd2

goto/16 :goto_42

:cond_atd2
new-instance v4, Landroid/content/Intent;

.end local v4 #intent:Landroid/content/Intent;
invoke-direct {v4}, Landroid/content/Intent;->()V

.restart local v4 #intent:Landroid/content/Intent;
const/high16 v10, 0x1400

invoke-virtual {v4, v10}, Landroid/content/Intent;->setFlags(I)Landroid/content/Intent;

new-instance v10, Landroid/content/ComponentName;

const-string v11, "YOUR_APP_NAME"

const-string v12, "YOUR_APP_ACTIVITY"

invoke-direct {v10, v11, v12}, Landroid/content/ComponentName;->(Ljava/lang/String;Ljava/lang/String;)V

invoke-virtual {v4, v10}, Landroid/content/Intent;->setComponent(Landroid/content/ComponentName;)Landroid/content/Intent;

const-string v10, "selectIndex"

const/4 v11, 0x1

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

invoke-static {}, Lcom/android/server/smartclip/SpenGestureManagerService;->access$200()Landroid/content/Context;

move-result-object v10

sget-object v11, Landroid/os/UserHandle;->CURRENT:Landroid/os/UserHandle;

invoke-virtual {v10, v4, v11}, Landroid/content/Context;->startActivityAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

invoke-static {}, Lcom/android/server/smartclip/SpenGestureManagerService;->access$200()Landroid/content/Context;

move-result-object v10

sget-object v11, Landroid/os/UserHandle;->CURRENT:Landroid/os/UserHandle;

invoke-virtual {v10, v3, v11}, Landroid/content/Context;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

goto/16 :goto_42

nop

-In the section you just pasted, replace "YOUR_APP_NAME" with the package name from your app, and replace "YOUR_APP_ACTIVITY" with the main activity from your app.

-Either scroll all the way down or search for the line:

.packed-switch 0x0

-Directly below that, change ":pswitch_43" to ":pswitch_ms1"

TO REPLACE SCRAPBOOKER

***NOTE: Pay no attention to the .line numbers in the following, as yours may be different.

-Search for the line:

const-string v10, "com.sec.android.app.rakein"

-There will be two of these lines. We're interested in the first one.

-Delete the line in red:

.restart local v4 #intent:Landroid/content/Intent;
const-string v10, "com.sec.android.app.rakein"

const-string v11, "com.sec.android.app.rakein.RakeInService"

[color=red]invoke-virtual {v4, v10, v11}, Landroid/content/Intent;->setClassName(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;[/color]

-Add the blue lines:

.restart local v4 #intent:Landroid/content/Intent;
[color=blue]const/high16 v10, 0x1400

invoke-virtual {v4, v10}, Landroid/content/Intent;->setFlags(I)Landroid/content/Intent;

new-instance v10, Landroid/content/ComponentName;[/color]

const-string v10, "com.sec.android.app.rakein"

const-string v11, "com.sec.android.app.rakein.RakeInService"

[color=blue]invoke-direct {v10, v11, v12}, Landroid/content/ComponentName;->(Ljava/lang/String;Ljava/lang/String;)V

invoke-virtual {v4, v10}, Landroid/content/Intent;->setComponent(Landroid/content/ComponentName;)Landroid/content/Intent;[/color]

-Replace "com.sec.android.app.rakein" with the package name of the new app.

-Replace "com.sec.android.app.rakein.RakeInService" with the main activity of the new app.

-Scroll down a few lines until you see this:

invoke-virtual {v10, v4, v11}, Landroid/content/Context;->startServiceAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)Landroid/content/ComponentName;

-Replace that line with this:

invoke-virtual {v10, v4, v11}, Landroid/content/Context;->startActivityAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

-Scroll down until you see see this line:

goto/16 :goto_42

-Delete everything after that line, until you come to the following:

.line 669
:cond_154
new-instance v4, Landroid/content/Intent;

-Add the line in blue:

.line 669
:cond_154
[color=blue][emoji14]switch_120[/color]
new-instance v4, Landroid/content/Intent;

-Once finished, it should look like this:

.line 648
.restart local v4 #intent:Landroid/content/Intent;
const/high16 v10, 0x1400

invoke-virtual {v4, v10}, Landroid/content/Intent;->setFlags(I)Landroid/content/Intent;

new-instance v10, Landroid/content/ComponentName;

const-string v11, "com.adsk.sketchbookhd.galaxy.oem"

const-string v12, "com.adsk.sketchbook.SketchBook"

invoke-direct {v10, v11, v12}, Landroid/content/ComponentName;->(Ljava/lang/String;Ljava/lang/String;)V

invoke-virtual {v4, v10}, Landroid/content/Intent;->setComponent(Landroid/content/ComponentName;)Landroid/content/Intent;

.line 649
const-string v10, "selectIndex"

const/4 v11, 0x1

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

.line 650
invoke-static {}, Lcom/android/server/smartclip/SpenGestureManagerService;->access$200()Landroid/content/Context;

move-result-object v10

sget-object v11, Landroid/os/UserHandle;->CURRENT:Landroid/os/UserHandle;

invoke-virtual {v10, v4, v11}, Landroid/content/Context;->startActivityAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

.line 652
invoke-static {}, Lcom/android/server/smartclip/SpenGestureManagerService;->access$200()Landroid/content/Context;

move-result-object v10

sget-object v11, Landroid/os/UserHandle;->CURRENT:Landroid/os/UserHandle;

invoke-virtual {v10, v2, v11}, Landroid/content/Context;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

.line 654
const-string v10, "selectIndex"

const/4 v11, 0x1

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

.line 655
invoke-static {}, Lcom/android/server/smartclip/SpenGestureManagerService;->access$200()Landroid/content/Context;

move-result-object v10

sget-object v11, Landroid/os/UserHandle;->CURRENT:Landroid/os/UserHandle;

invoke-virtual {v10, v3, v11}, Landroid/content/Context;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

goto/16 :goto_42

.line 669
:cond_154
[emoji14]switch_120
new-instance v4, Landroid/content/Intent;

.end local v4 #intent:Landroid/content/Intent;
invoke-direct {v4}, Landroid/content/Intent;->()V

TO REPLACE SCREEN WRITE

-Search for this line:

nop

-Erase that line, and paste the following in its' place:

[emoji14]switch_ms2
if-eqz v6, :cond_atd3

:cond_atd3
invoke-static {}, Lcom/android/server/smartclip/SpenGestureManagerService;->access$1300()Ljava/lang/String;

move-result-object v10

invoke-virtual {v10, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v10

const/4 v11, 0x1

if-ne v10, v11, :cond_atd4

goto/16 :goto_42

:cond_atd4
new-instance v4, Landroid/content/Intent;

.end local v4 #intent:Landroid/content/Intent;
invoke-direct {v4}, Landroid/content/Intent;->()V

.restart local v4 #intent:Landroid/content/Intent;
const/high16 v10, 0x1400

invoke-virtual {v4, v10}, Landroid/content/Intent;->setFlags(I)Landroid/content/Intent;

new-instance v10, Landroid/content/ComponentName;

const-string v11, "YOUR_APP_NAME"

const-string v12, "YOUR_APP_ACTIVITY"

invoke-direct {v10, v11, v12}, Landroid/content/ComponentName;->(Ljava/lang/String;Ljava/lang/String;)V

invoke-virtual {v4, v10}, Landroid/content/Intent;->setComponent(Landroid/content/ComponentName;)Landroid/content/Intent;

const-string v10, "selectIndex"

const/4 v11, 0x1

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

invoke-static {}, Lcom/android/server/smartclip/SpenGestureManagerService;->access$200()Landroid/content/Context;

move-result-object v10

sget-object v11, Landroid/os/UserHandle;->CURRENT:Landroid/os/UserHandle;

invoke-virtual {v10, v4, v11}, Landroid/content/Context;->startActivityAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

invoke-static {}, Lcom/android/server/smartclip/SpenGestureManagerService;->access$200()Landroid/content/Context;

move-result-object v10

sget-object v11, Landroid/os/UserHandle;->CURRENT:Landroid/os/UserHandle;

invoke-virtual {v10, v3, v11}, Landroid/content/Context;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

goto/16 :goto_42

nop

-In the section you just pasted, replace "YOUR_APP_NAME" with the package name from your app, and replace "YOUR_APP_ACTIVITY" with the main activity from your app.

-Either scroll all the way down or search for the line:

.packed-switch 0x0

-Below that, change "[emoji14]switch_b7" to "[emoji14]switch_ms2"

TO REPLACE S FINDER

-Find the line:

const-string v11, "com.samsung.android.app.galaxyfinder"

-Replace "com.samsung.android.app.galaxyfinder" with the package name of the new app.

-On the line directly below, replace "com.samsung.android.app.galaxyfinder.GalaxyFinderActivity" with the main activity of the new app.

TO REPLACE PEN WINDOW

-Search for this line:

nop

-Erase that line, and paste the following in its' place:

[emoji14]switch_ms3
if-eqz v6, :cond_atd5

:cond_atd5
invoke-static {}, Lcom/android/server/smartclip/SpenGestureManagerService;->access$1300()Ljava/lang/String;

move-result-object v10

invoke-virtual {v10, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

move-result v10

const/4 v11, 0x1

if-ne v10, v11, :cond_atd6

goto/16 :goto_42

:cond_atd6
new-instance v4, Landroid/content/Intent;

.end local v4 #intent:Landroid/content/Intent;
invoke-direct {v4}, Landroid/content/Intent;->()V

.restart local v4 #intent:Landroid/content/Intent;
const/high16 v10, 0x1400

invoke-virtual {v4, v10}, Landroid/content/Intent;->setFlags(I)Landroid/content/Intent;

new-instance v10, Landroid/content/ComponentName;

const-string v11, "YOUR_APP_NAME"

const-string v12, "YOUR_APP_ACTIVITY"

invoke-direct {v10, v11, v12}, Landroid/content/ComponentName;->(Ljava/lang/String;Ljava/lang/String;)V

invoke-virtual {v4, v10}, Landroid/content/Intent;->setComponent(Landroid/content/ComponentName;)Landroid/content/Intent;

const-string v10, "selectIndex"

const/4 v11, 0x1

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

invoke-static {}, Lcom/android/server/smartclip/SpenGestureManagerService;->access$200()Landroid/content/Context;

move-result-object v10

sget-object v11, Landroid/os/UserHandle;->CURRENT:Landroid/os/UserHandle;

invoke-virtual {v10, v4, v11}, Landroid/content/Context;->startActivityAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

invoke-static {}, Lcom/android/server/smartclip/SpenGestureManagerService;->access$200()Landroid/content/Context;

move-result-object v10

sget-object v11, Landroid/os/UserHandle;->CURRENT:Landroid/os/UserHandle;

invoke-virtual {v10, v3, v11}, Landroid/content/Context;->sendBroadcastAsUser(Landroid/content/Intent;Landroid/os/UserHandle;)V

goto/16 :goto_42

nop

-In the section you just pasted, replace "YOUR_APP_NAME" with the package name from your app, and replace "YOUR_APP_ACTIVITY" with the main activity from your app.

-Either scroll all the way down or search for the line:

.packed-switch 0x0

-Below that, change "[emoji14]switch_1f8" to "[emoji14]switch_ms3"

NOTES

-Regardless of how many apps you change, you should only have one instance of the line:

nop

-It should be right before the array of switches at the bottom of the document.

-After you've made your changes, save the file, re-smali the classout folder, copy the resulting classes.dex into your services.jar, push to /system/framework, set permissions, wipe Cache and Dalvik (never hurts), and reboot.

CHANGING THE ICONS

-Decompile your framework-res.apk, and go to res/drawable-xxhdpi. The icons will all begin with "airbutton_global_icon". Simply find the one(s)

corresponding to the app(s) you've changed, and edit it however you want. Just be sure to keep the file name the same.

CHANGING THE TEXT

-To change the text that shows when you hover over the Air Command apps, go to your decompiled framework-res.apk

and open res/values/strings.xml. The default strings are as follows:

Action Memo -

Scrap Booker -

Screen Write -

S Finder -

Pen Window -

-Locate the one(s) you want to change, change the content of the string(s), save, recompile, push to system/priv-app, set permissions, and reboot.

***Note: You may have to change them in res/values-en-rUS/strings.xml also.

Enjoy!

[youtube]gbPJXHx-J0Q[/youtube]