Hi again lads/gents,
Today i want to share to you how to enable 2G/3G Toggle feature that was commonly found on CyanogenMod and/or AOKP into your custom Android ROM. My code is based from Xperia Ray but shouldn't be too different between different phone version, because the concept in essence is to bring up the default toggle hidden in Settings menu to be switchable with external app or button.
The common problem when we try to implement this kind of mod is that Android system prevents system changes from outside system's apk, and added to the fact that the only apk allowed for Network Mode changes is the one with uid set as "phone" at its AndroidManifest.xml. When you thought it's a part of Settings.apk, actually Settings.apk only calls for Phone.apk Settings page.
So to do a workaround for that, you need to alter the phone.apk itself to be able to receive custom Broadcast from external apk and then switch the mode when required.
This is what you need:
1. Rooted phone
2. Phone.apk (or in my case SemcPhone.apk)
3. Basic Knowledge of Android Broadcast and Receiver concept
4. Custom toggle app/Status Bar Widget (in my case, i'll use lidroid's Power Button on Status Bar as a toggle utility)
5. Any APK Manager, preferably one that can be set to not decode resource file.
The steps are:
1. Place the Receiver files inside Phone.apk
2. Register the Receiver at runtime through Phone Application smali file
3. Compile Phone.apk
4. Implement Toggle mechanism for 2G/3G on Toggling app
1. Place the Receiver files inside Phone.apk
This is used as a Receiver of Broadcast Message from User App to start Toggling the Network Mode. There are 3 files you need to put on decompiled Phone.apk:
2. Register the Receiver at runtime through Phone Application smali file
Now you have the Receiver installed, you need to initiate and register the Receiver at phone app startup. There are 2 methods available:
This is how you alter the PhoneApp.smali:
3. Compile the Phone.apk
You need to compile the phone app back. As it was with Sony's code, it was clear that i need to decompile ONLY the source, but not the resource part of the apk because when compiled back it will be broken. So try to decompile it at the source only.
4. Implement the Toggle App to send a Broadcast Intent
Now this is the part where you have to determine what mode is supported by your phone. This is the value of Android supported value that will be sent as a Broadcast Intent:
So if your phone only supports WCDMA(3G) as max, you should use value 0,1, and 2 only.
The following is my 2G/3G simple toggle mode from Lidroid's Status Bar Widget code. You should adapt the code yourself if you're using something else. But as a guide, this is the logic:
The logic above can be observed in the method toggleState() on the following code:
Or you could download from attachment if you happen to use Lidroid's code too.
Compile back your apk and voila!
Hope this tutorial helps Any question, please reply and i'll help as best as i can.
Today i want to share to you how to enable 2G/3G Toggle feature that was commonly found on CyanogenMod and/or AOKP into your custom Android ROM. My code is based from Xperia Ray but shouldn't be too different between different phone version, because the concept in essence is to bring up the default toggle hidden in Settings menu to be switchable with external app or button.
The common problem when we try to implement this kind of mod is that Android system prevents system changes from outside system's apk, and added to the fact that the only apk allowed for Network Mode changes is the one with uid set as "phone" at its AndroidManifest.xml. When you thought it's a part of Settings.apk, actually Settings.apk only calls for Phone.apk Settings page.
So to do a workaround for that, you need to alter the phone.apk itself to be able to receive custom Broadcast from external apk and then switch the mode when required.
This is what you need:
1. Rooted phone
2. Phone.apk (or in my case SemcPhone.apk)
3. Basic Knowledge of Android Broadcast and Receiver concept
4. Custom toggle app/Status Bar Widget (in my case, i'll use lidroid's Power Button on Status Bar as a toggle utility)
5. Any APK Manager, preferably one that can be set to not decode resource file.
The steps are:
1. Place the Receiver files inside Phone.apk
2. Register the Receiver at runtime through Phone Application smali file
3. Compile Phone.apk
4. Implement Toggle mechanism for 2G/3G on Toggling app
1. Place the Receiver files inside Phone.apk
This is used as a Receiver of Broadcast Message from User App to start Toggling the Network Mode. There are 3 files you need to put on decompiled Phone.apk:
- smali\com\android\phone\NetworkModeReceiver.smali -> The Main Code
Code:.class public Lcom/android/phone/NetworkModeReceiver; .super Landroid/content/BroadcastReceiver; .source "NetworkModeReceiver.java" # annotations .annotation system Ldalvik/annotation/MemberClasses; value = { Lcom/android/phone/NetworkModeReceiver$1;, Lcom/android/phone/NetworkModeReceiver$MyHandler; } .end annotation # static fields .field private static final TAG:Ljava/lang/String; = "NetworkModeReceiver" # instance fields .field private mHandler:Lcom/android/phone/NetworkModeReceiver$MyHandler; # direct methods .method public constructor <init>()V .locals 2 .prologue .line 31 invoke-direct {p0}, Landroid/content/BroadcastReceiver;-><init>()V new-instance v0, Lcom/android/phone/NetworkModeReceiver$MyHandler; const/4 v1, 0x0 invoke-direct {v0, p0, v1}, Lcom/android/phone/NetworkModeReceiver$MyHandler;-><init>(Lcom/android/phone/NetworkModeReceiver;Lcom/android/phone/NetworkModeReceiver$1;)V iput-object v0, p0, Lcom/android/phone/NetworkModeReceiver;->mHandler:Lcom/android/phone/NetworkModeReceiver$MyHandler; return-void .end method # virtual methods .method public onReceive(Landroid/content/Context;Landroid/content/Intent;)V .locals 5 .parameter "context" .parameter "intent" const-string v0, "com.android.phone.CHANGE_NETWORK_MODE" .line 41 invoke-virtual {p2}, Landroid/content/Intent;->getAction()Ljava/lang/String; move-result-object v1 invoke-virtual {v1, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z move-result v1 if-eqz v1, :cond_0 .line 43 const-string v0, "com.android.phone.NEW_NETWORK_MODE" const v1, 0x0 invoke-virtual {p2, v0, v1}, Landroid/content/Intent;->getIntExtra(Ljava/lang/String;I)I move-result v1 .line 44 new-instance v0, Ljava/lang/StringBuilder; invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V const-string v3, "Receive Network Mode " invoke-virtual {v0, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v0 invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder; move-result-object v0 invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; move-result-object v0 sget-object v2, Lcom/android/phone/NetworkModeReceiver;->TAG:Ljava/lang/String; .line 45 invoke-static {v2, v0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I .line 46 invoke-virtual {p1}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver; move-result-object v3 const-string v2, "preferred_network_mode" invoke-static {v3, v2, v1}, Landroid/provider/Settings$Secure;->putInt(Landroid/content/ContentResolver;Ljava/lang/String;I)Z iget-object v4, p0, Lcom/android/phone/NetworkModeReceiver;->mHandler:Lcom/android/phone/NetworkModeReceiver$MyHandler; .line 48 const/4 v3, 0x1 invoke-virtual {v4, v3}, Lcom/android/phone/NetworkModeReceiver$MyHandler;->obtainMessage(I)Landroid/os/Message; move-result-object v4 .line 49 invoke-static {}, Lcom/android/internal/telephony/PhoneFactory;->getDefaultPhone()Lcom/android/internal/telephony/Phone; move-result-object v3 invoke-interface {v3, v1, v4}, Lcom/android/internal/telephony/Phone;->setPreferredNetworkType(ILandroid/os/Message;)V :cond_0 return-void .end method
As you can see, We will use Intent named as "com.android.phone.CHANGE_NETWORK_MODE" with the Extras(or attribute as a layman's term) named as "com.android.phone.NEW_NETWORK_MODE"
- smali\com\android\phone\NetworkModeReceiver$1.smali -> Helper Class for MyHandler inner class.
Code:.class synthetic Lcom/android/phone/NetworkModeReceiver$1; .super Ljava/lang/Object; .source "NetworkModeReceiver.java" # annotations .annotation system Ldalvik/annotation/EnclosingClass; value = Lcom/android/phone/NetworkModeReceiver; .end annotation .annotation system Ldalvik/annotation/InnerClass; accessFlags = 0x1008 name = null .end annotation
- smali\com\android\phone\NetworkModeReceiver$MyHandler.smali -> Does nothing, only used for Receiving a rollback message from system for UI element - which in this method is not quite usable. But it's there for compatibility reason.
Code:.class Lcom/android/phone/NetworkModeReceiver$MyHandler; .super Landroid/os/Handler; .source "NetworkModeReceiver.java" # annotations .annotation system Ldalvik/annotation/EnclosingClass; value = Lcom/android/phone/NetworkModeReceiver; .end annotation .annotation system Ldalvik/annotation/InnerClass; accessFlags = 0x2 name = "MyHandler" .end annotation # instance fields .field final synthetic this$0:Lcom/android/phone/NetworkModeReceiver; # direct methods .method private constructor <init>(Lcom/android/phone/NetworkModeReceiver;)V .locals 0 .parameter .prologue .line 628 iput-object p1, p0, Lcom/android/phone/NetworkModeReceiver$MyHandler;->this$0:Lcom/android/phone/NetworkModeReceiver; invoke-direct {p0}, Landroid/os/Handler;-><init>()V return-void .end method .method synthetic constructor <init>(Lcom/android/phone/NetworkModeReceiver;Lcom/android/phone/NetworkModeReceiver$1;)V .locals 0 .parameter "x0" .parameter "x1" .prologue .line 628 invoke-direct {p0, p1}, Lcom/android/phone/NetworkModeReceiver$MyHandler;-><init>(Lcom/android/phone/NetworkModeReceiver;)V return-void .end method .method private handleGetPreferredNetworkTypeResponse(Landroid/os/Message;)V .locals 9 .parameter "msg" return-void .end method .method private handleSetPreferredNetworkTypeResponse(Landroid/os/Message;)V .locals 2 .parameter "msg" return-void .end method .method private resetNetworkModeToDefault()V .locals 3 .prologue return-void .end method # virtual methods .method public handleMessage(Landroid/os/Message;)V .locals 1 .parameter "msg" .prologue .line 635 iget v0, p1, Landroid/os/Message;->what:I packed-switch v0, :pswitch_data_0 .line 643 :goto_0 return-void .line 637 :pswitch_0 invoke-direct {p0, p1}, Lcom/android/phone/NetworkModeReceiver$MyHandler;->handleGetPreferredNetworkTypeResponse(Landroid/os/Message;)V goto :goto_0 .line 640 :pswitch_1 invoke-direct {p0, p1}, Lcom/android/phone/NetworkModeReceiver$MyHandler;->handleSetPreferredNetworkTypeResponse(Landroid/os/Message;)V goto :goto_0 .line 635 :pswitch_data_0 .packed-switch 0x0 :pswitch_0 :pswitch_1 .end packed-switch .end method
2. Register the Receiver at runtime through Phone Application smali file
Now you have the Receiver installed, you need to initiate and register the Receiver at phone app startup. There are 2 methods available:
- Add another line to AndroidManifest.xml -> The simplest one but not practical for system app of stock ROM since the AndroidManifest.xml requires to be signed to be functional.
- Alter PhoneApp.smali (it can be named something else->The point is you need Phone's Application main code to be altered) to register the receiver when it's called -> This is the way to go.
This is how you alter the PhoneApp.smali:
- Give a space to store the Receiver inside the PhoneApp.smali, named as mModeReceiver (Insert the Bold Line)
Code:.field mLastPhoneState:Lcom/android/internal/telephony/Phone$State; .field private final mMediaButtonReceiver:Landroid/content/BroadcastReceiver; [B].field private final mModeReceiver:Landroid/content/BroadcastReceiver;[/B] .field private mNationalRoamingSettings:I .field private mNationalRoamingSupported:Z
- Initiate the Receiver Object and store it into the available space (Insert the Bold Line)
Code:.method public constructor <init>()V . . .line 233 new-instance v0, Lcom/android/phone/PhoneApp$PhoneAppBroadcastReceiver; const/4 v1, 0x0 invoke-direct {v0, p0, v1}, Lcom/android/phone/PhoneApp$PhoneAppBroadcastReceiver;-><init>(Lcom/android/phone/PhoneApp;Lcom/android/phone/PhoneApp$1;)V iput-object v0, p0, Lcom/android/phone/PhoneApp;->mReceiver:Landroid/content/BroadcastReceiver; [B] .line 236 new-instance v0, Lcom/android/phone/NetworkModeReceiver; invoke-direct {v0}, Lcom/android/phone/NetworkModeReceiver;-><init>()V iput-object v0, p0, Lcom/android/phone/PhoneApp;->mModeReceiver:Landroid/content/BroadcastReceiver;[/B] .line 238 new-instance v0, Lcom/android/phone/SemcMediaButtonBroadcastReceiver; invoke-direct {v0}, Lcom/android/phone/SemcMediaButtonBroadcastReceiver;-><init>()V iput-object v0, p0, Lcom/android/phone/PhoneApp;->mMediaButtonReceiver:Landroid/content/BroadcastReceiver; . . .end method
- Register the Receiver
The following is to register the Receiver when the Phone app is created (onCreate). When registered, It will start listening to the phone activity so later it can receive a toggle message from toggle app. And not just any message that this receiver can read, We limit this Receiver to only hear a filtered Intent with name of "com.android.phone.CHANGE_NETWORK_MODE" as explained above.
Code:.method public onCreate()V . . .line 630 const-string v1, "com.android.phone.intent.ACTION_DATA_TRAFFIC_SWITCH" invoke-virtual {v0, v1}, Landroid/content/IntentFilter;->addAction(Ljava/lang/String;)V .line 631 iget-object v1, p0, Lcom/android/phone/PhoneApp;->mReceiver:Landroid/content/BroadcastReceiver; invoke-virtual {p0, v1, v0}, Lcom/android/phone/PhoneApp;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent; [B] .line 633 new-instance v0, Landroid/content/IntentFilter; const-string v1, "com.android.phone.CHANGE_NETWORK_MODE" invoke-direct {v0, v1}, Landroid/content/IntentFilter;-><init>(Ljava/lang/String;)V iget-object v1, p0, Lcom/android/phone/PhoneApp;->mModeReceiver:Landroid/content/BroadcastReceiver; invoke-virtual {p0, v1, v0}, Lcom/android/phone/PhoneApp;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;[/B] .line 638 new-instance v0, Landroid/content/IntentFilter; const-string v1, "android.intent.action.MEDIA_BUTTON" invoke-direct {v0, v1}, Landroid/content/IntentFilter;-><init>(Ljava/lang/String;)V .line 642 const/16 v1, 0x3e0 invoke-virtual {v0, v1}, Landroid/content/IntentFilter;->setPriority(I)V .line 645 iget-object v1, p0, Lcom/android/phone/PhoneApp;->mMediaButtonReceiver:Landroid/content/BroadcastReceiver; invoke-virtual {p0, v1, v0}, Lcom/android/phone/PhoneApp;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent; . . .end method
3. Compile the Phone.apk
You need to compile the phone app back. As it was with Sony's code, it was clear that i need to decompile ONLY the source, but not the resource part of the apk because when compiled back it will be broken. So try to decompile it at the source only.
4. Implement the Toggle App to send a Broadcast Intent
Now this is the part where you have to determine what mode is supported by your phone. This is the value of Android supported value that will be sent as a Broadcast Intent:
Code:
int NETWORK_MODE_WCDMA_PREF = 0; /* GSM/WCDMA (WCDMA preferred) */
int NETWORK_MODE_GSM_ONLY = 1; /* GSM only */
int NETWORK_MODE_WCDMA_ONLY = 2; /* WCDMA only */
int NETWORK_MODE_GSM_UMTS = 3; /* GSM/WCDMA (auto mode, according to PRL) AVAILABLE Application Settings menu*/
int NETWORK_MODE_CDMA = 4; /* CDMA and EvDo (auto mode, according to PRL) AVAILABLE Application Settings menu*/
int NETWORK_MODE_CDMA_NO_EVDO = 5; /* CDMA only */
int NETWORK_MODE_EVDO_NO_CDMA = 6; /* EvDo only */
int NETWORK_MODE_GLOBAL = 7; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) AVAILABLE Application Settings menu*/
So if your phone only supports WCDMA(3G) as max, you should use value 0,1, and 2 only.
The following is my 2G/3G simple toggle mode from Lidroid's Status Bar Widget code. You should adapt the code yourself if you're using something else. But as a guide, this is the logic:
- create a new Intent with name "com.android.phone.CHANGE_NETWORK_MODE"
- take current mode
- Apply the next value into the newly created Intent as Extra named "com.android.phone.NEW_NETWORK_MODE"
- Broadcast the Intent to the System (which will be read by Phone.apk).
The logic above can be observed in the method toggleState() on the following code:
Code:
.class public Lcom/lidroid/systemui/quickpanel/NetworkModeButton;
.super Lcom/lidroid/systemui/quickpanel/PowerButton;
.source "NetworkModeButton.java"
# static fields
.field private static final CM_MODE_3GSM_ONLY:I = 0x1
.field private static final CM_MODE_3G_ONLY:I = 0x0
.field private static final CM_MODE_3G_PREFERRED:I = 0x2
.field private static final OBSERVED_URIS:Ljava/util/List; = null
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/util/List",
"<",
"Landroid/net/Uri;",
">;"
}
.end annotation
.end field
.field private static final TAG:Ljava/lang/String; = "NetworkModeButton"
# direct methods
.method static constructor <clinit>()V
.locals 3
.prologue
const/16 v2, 0x0
.line 21
new-instance v0, Ljava/util/ArrayList;
invoke-direct {v0}, Ljava/util/ArrayList;-><init>()V
sput-object v0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->OBSERVED_URIS:Ljava/util/List;
.line 23
sget-object v0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->OBSERVED_URIS:Ljava/util/List;
const-string v1, "preferred_network_mode"
invoke-static {v1}, Landroid/provider/Settings$Secure;->getUriFor(Ljava/lang/String;)Landroid/net/Uri;
move-result-object v1
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
return-void
.end method
.method public constructor <init>()V
.locals 2
.prologue
.line 43
invoke-direct {p0}, Lcom/lidroid/systemui/quickpanel/PowerButton;-><init>()V
const-string v0, "toggleNetworkMode"
iput-object v0, p0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->mType:Ljava/lang/String;
return-void
.end method
.method private static getCurrentNetworkMode(Landroid/content/Context;)I
.locals 3
.parameter "context"
.prologue
.line 167
const/16 v0, 0x0
.line 169
.local v0, state:I
:try_start_0
invoke-virtual {p0}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;
move-result-object v1
const-string v2, "preferred_network_mode"
invoke-static {v1, v2}, Landroid/provider/Settings$Secure;->getInt(Landroid/content/ContentResolver;Ljava/lang/String;)I
:try_end_0
.catch Landroid/provider/Settings$SettingNotFoundException; {:try_start_0 .. :try_end_0} :catch_0
move-result v0
.line 173
:goto_0
return v0
.line 171
:catch_0
move-exception v1
goto :goto_0
.end method
# virtual methods
.method protected getObservedUris()Ljava/util/List;
.locals 1
.annotation system Ldalvik/annotation/Signature;
value = {
"()",
"Ljava/util/List",
"<",
"Landroid/net/Uri;",
">;"
}
.end annotation
.prologue
.line 163
sget-object v0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->OBSERVED_URIS:Ljava/util/List;
return-object v0
.end method
.method protected getText()I
.locals 1
.prologue
.line 93
const v0, 0x7f08007d
return v0
.end method
.method protected handleLongClick()Z
.locals 3
.prologue
.line 126
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
.line 127
.local v0, intent:Landroid/content/Intent;
const-string v1, "com.android.phone"
const-string v2, "com.android.phone.Settings"
invoke-virtual {v0, v1, v2}, Landroid/content/Intent;->setClassName(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;
.line 128
const/high16 v1, 0x1000
invoke-virtual {v0, v1}, Landroid/content/Intent;->addFlags(I)Landroid/content/Intent;
.line 129
iget-object v1, p0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->mView:Landroid/view/View;
invoke-virtual {v1}, Landroid/view/View;->getContext()Landroid/content/Context;
move-result-object v1
invoke-virtual {v1, v0}, Landroid/content/Context;->startActivity(Landroid/content/Intent;)V
.line 130
const/4 v1, 0x1
return v1
.end method
[B].method protected toggleState()V
.locals 5
.prologue
const/4 v4, 0x2
const/4 v1, 0x1
const-string v2, "com.android.phone.CHANGE_NETWORK_MODE"
.line 83
iget-object v3, p0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->mView:Landroid/view/View;
invoke-virtual {v3}, Landroid/view/View;->getContext()Landroid/content/Context;
move-result-object v3
.line 84
.local v3, context:Landroid/content/Context;
invoke-static {v3}, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->getCurrentNetworkMode(Landroid/content/Context;)I
move-result v0
.line 85
add-int v0, v0, v1
if-le v0, v4, :cond_0
const/4 v0, 0x0
.line 86
:cond_0
new-instance v4, Landroid/content/Intent;
invoke-direct {v4, v2}, Landroid/content/Intent;-><init>(Ljava/lang/String;)V
const-string v2, "com.android.phone.NEW_NETWORK_MODE"
invoke-virtual {v4, v2, v0}, Landroid/content/Intent;->putExtra(Ljava/lang/String;I)Landroid/content/Intent;
invoke-virtual {v3, v4}, Landroid/content/Context;->sendBroadcast(Landroid/content/Intent;)V
return-void
.end method[/B]
.method protected updateState()V
.locals 3
.line 90
iget-object v1, p0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->mView:Landroid/view/View;
invoke-virtual {v1}, Landroid/view/View;->getContext()Landroid/content/Context;
move-result-object v1
invoke-static {v1}, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->getCurrentNetworkMode(Landroid/content/Context;)I
move-result v0
.line 92
const v1, 0x0
if-ne v0, v1, :cond_0
const v2, 0x7f0200d4
iput v2, p0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->mIcon:I
const/4 v2, 0x1
iput v2, p0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->mState:I
.line 93
:goto_0
return-void
.line 94
:cond_0
const v1, 0x1
if-ne v0, v1, :cond_1
const v2, 0x7f0200d3
iput v2, p0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->mIcon:I
const/4 v2, 0x2
iput v2, p0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->mState:I
goto :goto_0
.line 96
:cond_1
const v2, 0x7f0200d5
iput v2, p0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->mIcon:I
const/4 v2, 0x1
iput v2, p0, Lcom/lidroid/systemui/quickpanel/NetworkModeButton;->mState:I
goto :goto_0
.end method
Or you could download from attachment if you happen to use Lidroid's code too.
Compile back your apk and voila!
Hope this tutorial helps Any question, please reply and i'll help as best as i can.
Attachments
Last edited: