How to open the Android ServiceMode menu programmatically on Samsung Phones ?
Manually, I can do it by dialing the ussd code *#0011#.
This was a challenge and I've been a few hours looking for a solution. But i am afraid i don't have good news.
1. First attemp, Intent.ACTION_DIAL
Is true that in the beginning, it was possible to directly call USSD codes from an app (using the intent Intent.ACTION_DIAL), and even from a website, just using the "tel:" schema. That opens the dialer, an puts the desired number. As when you put the last #, the code get send automatically, it was almost transparent to the user, whose interaction wasn't required. But that was actually considered a vulnerability of the system, since somebody could write malicious software, or even more, insert malicious code in a website that could even wipe your phone or block the sim card. You can read about this, for example in this link As of September 2012, it seems that Samsung finally fixed that vulnerability so for instance your S3 is not capable of that. At this point it will be hard to find any device still vulnerable.
2. Second Attempt, the workaround
Ok everything in Android is an app, even the phone itself is an app. So, why couldn't we try to replicate its code? And actually, what happens when the user manually sends a ussd? There was too possible answers:
Easy to test: I put my phone in flight mode, so if it has to send a code, hopefully it wont be able to. It was as i expected: i dialed the code, and the ServiceMode screen appeared! And it was empty, so we can say that the dialer opens a system application, and this application calls the provider.
Its easy to find out which is this application. In Samsung devices, at least in S4, its name is ServiceMode. You can find it at Settings > Application manager > All
. So we can try to find out how it is launched more by means of one of this:
2.1. Reading the phone application code
I tried, but it was pretty confusing at the beginning, so i went to option 2
2.2. Checking the Service mode app
I opened ES file explorer > app manager. connected the phone, and in phone/backups/apps i had the servicestatus apk. a few minutes or inverse engineering after, i had the manifest file, as revealing as it uses to be. There i could see a bunch of activities, and also a few broadcast receivers. I didn't know what i was more afraid of.
2.2.1 Lets try with the activities.
Since we know we can open an specific application from another, i will try to write a simple app, that open one of this activities. This is as simple as:
Intent i= new Intent(Intent.Action_MAIN);
i.setClass( "package name", "class name");
startActivity(i);
Since this app is not meant to be open from a launcher icon, it has not an activity with an intent filter that let us know that it is the main activity. So i have to try at least a few of them. But anyways, i saw something i didn't like. I will tell you later.
I tried, but, as i expected, i cannot open that activities. I get an activity not found exception. So, lets try with a receiver. At least this will be fun.
2.2.2 Lets try with the receivers.
There is a few, but specially i liked one with this intent-filter:
<intent-filter>
<action android:name="android.provider.Telephony.SECRET_CODE" />
...
Looks good. I went yo Telephony.java, and there i could see this:
/**
* Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are
* of the form *#*#<code>#*#*. The intent will have the data URI:</p>
*
* <p><code>android_secret_code://<code></code></p>
*/
public static final String SECRET_CODE_ACTION =
"android.provider.Telephony.SECRET_CODE";
Looks great, its an specific intent, probably the schema we need is not "tel:" but "android_secret_code://" and probably the codes has to be in a different internal format. I tried, more or less just for fun, since i knew that there is the same problem i saw in the activities, and is this:
<permission android:name="com.sec.android.app.servicemodeapp.permission.KEYSTRING" android:protectionLevel="signatureOrSystem" />
The app declares this permission, and every component uses it. so, or you know how to declare and set a signature, or you are a system app. Otherwise you cannot interact with this app at all.
Of course you couldn't even think about creating your own servicemode app, since you wouldn't perform that kind of communication with the provider without being a system app (since you have to pass through some firmware apps that will say a sad "who do you think you are")
There is nothing we can do at his point, at least with a Samsung phone, and we can think every other phone will be the same.
Well, actually none really good. But lets see:
Alternative 1. Find another kind of ussd code
We know that there is 2 kind of USSD. The ones that when you dial the last #, the action is automatically triggered, and the other, which require that you press the call button.
If you try with a third-party dialer, you can see that
So, if a third-party can send that type of codes, every app could. So If you could try to find an alternative ussd code, of that type that are triggered after the usser press the call button, you could achieve your what you need. In that case, you should use an Intent.ACTION_CALL intent
//if you use the ACTION_DIAL intent, it open the dialer and put the given number in it. //meanwhile, if we use the ACTION_CALL, the app will directly call.
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:"+ "*" + Uri.encode("#") + "0011" + Uri.encode("#"))); //here you woud put your alternative code
startActivity(intent);
Also you would need to declare this permission in your manifest
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
Probably you could find an alternative code to do this, since i ve seen a few in the internet, but at this point no one worked for me. You can give it a try
Alternative 2. Wait for an official api to come up
In the android project page at coogle code, there is a request to Add USSD API support. It has many subscribers, but it is quite old (more than 5 years), i'm afraid that's not really good. Anyways, that could happen, probably the android tem will consider to prepare an api so an app could declare some permissions, and make requests of some kind of codes. But, I know, this can be waiting forever.
So, what to say. Would luck looking for a solution, or for an alternative to your app. I'm sorry my research wasn't more fruitful :(
I think that I got a solution.
By running the bellow code on a rooted phone you should open the Samsung ServiceModeApp (the service mode shown in this post). Programmatically, I think that one can run anything if logged as root. However, there are issues to face such as:
Repare that 0011 is the argument that you must pass to the activity. Code follows:
PackageManager packageManager = this.getPackageManager();
if (packageManager != null) {
measure_intent = new Intent(Intent.ACTION_MAIN).
addCategory(Intent.CATEGORY_LAUNCHER).setComponent(new ComponentName(
"com.sec.android.app.servicemodeapp",
"com.sec.android.app.servicemodeapp.ServiceModeApp"));
measure_intent.putExtra("keyString", "0011");
ResolveInfo resolved = packageManager.resolveActivity(
measure_intent, PackageManager.MATCH_DEFAULT_ONLY);
if (resolved != null) {
startActivity(measure_intent);
return;
} else {
Toast.makeText(this, "version not implemented", Toast.LENGTH_LONG).show();
}
}
I've reached to it by pulling ServiceModeApp from Android's /system/app directory, then decompiling the .apk file, and then analyzing its code. Hope it helps! :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With