It was a challenge, and for several hours I was looking for a solution. But I'm afraid that I do not have good news.
1. First attemp, Intent.ACTION_DIAL
It is true that at first it was possible to directly call USSD codes from the application (using the intent Intent.ACTION_DIAL) and even from the website using the tel: scheme. This opens the dialer, and puts the right number. Since when you put the last #, the code receives an automatic transfer, it was almost transparent to a user whose interaction was not required. But in fact, this was considered a system vulnerability, because someone could write malicious software or even more, embed malicious code on a website that could even erase your phone or block a SIM card. You can read about it, for example, in this link. As of September 2012, it seems that Samsung has finally fixed this vulnerability , so, for example, your S3 is not capable of it. At this point, it will be difficult to find any device that is still vulnerable.
2. Second attempt, workaround
Well, everything in Android is an application, even the phone itself is an application. So why were we unable to reproduce his code? And actually, what happens when a user manually sends ussd? There were also possible answers:
- The phone sends the code to the provider and waits for a response, or
- The phone is doing something locally
Itโs easy to check: I put my phone in flight mode, so if he needs to send the code, we hope he canโt. It was exactly as I expected: I typed the code and the ServiceMode screen appeared! And it was empty, so we can say that the dialer opens the system application, and this application calls the provider. Its easy to find out what this app is. On Samsung devices, at least on S4, this is the name ServiceMode. You can find it in Settings > Application manager > All . Therefore, we can try to figure out how it starts more with one of them:
2.1. Reading phone application code
I tried, but it was rather confusing at the beginning, so I moved to option 2
2.2. Verify Maintenance Mode Application
I opened ES File Explorer> Application Manager. I connected the phone, and in the phone / backups / applications I had servicestatus apk. a few minutes later or after reverse engineering, I had a manifest file, as shown how it is used. There I could see many events, as well as several broadcast receivers. I did not know what I was more afraid of.
2.2.1 Try the steps.
Since we know that we can open a specific application from another, I will try to write a simple application that opens one of these actions. It is as simple as:
Intent i= new Intent(Intent.Action_MAIN); i.setClass( "package name", "class name"); startActivity(i);
Since this application is not intended to be opened from the launch icon, it has no activity with an intent filter that allows us to know that this is the main action. Therefore, I should try at least a few of them. But in any case, I saw something that I did not like. I will tell you later.
I tried, but, as expected, I can not open this activity. I get an exception not found in the job. So try with the receiver. At least it will be fun.
2.2.2 Try using receivers.
There are a few, but I especially liked this intent filter:
<intent-filter> <action android:name="android.provider.Telephony.SECRET_CODE" /> ...
Looks nice. I went to Telephony.java, and there I could see this:
public static final String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE";
It looks great, its specific intention, maybe we need a scheme not "tel:", but "android_secret_code: //", and probably the codes should be in a different internal format. I tried, more or less just for fun, because I knew that there is the same problem that I saw in the actions, and this is what:
<permission android:name="com.sec.android.app.servicemodeapp.permission.KEYSTRING" android:protectionLevel="signatureOrSystem" />
An application declares this permission, and each component uses it. So, either you know how to declare and establish a signature, or you are a system application. Otherwise, you cannot interact with this application at all.
Of course, you could not even think of creating your own servicemode application, since you could not carry out such communication with the provider without being a system application (since you need to go through some firmware applications that will say sad โwho do you think you are ")
conclusions
We can do nothing from his point of view, at least with a Samsung phone, and we can think that every other phone will be the same.
Alternatives
Well, really nothing good. But let's see:
Alternative 1. Find a different kind of ussd code
We know that there are 2 types of USSD. Those that, when you dial the last #, the action automatically starts, and another, for which you need to press the call button.
If you try a third-party dialer, you will see that
- if you type code of the first type, nothing starts at all (only they can be called only for firmware)
- You can use a different type (enter code + press call). I believe this means that such codes are less risky, since they do not change anything in the device, so they are allowed.
- Of course, if you type the code of the first type and press the call, you will receive an error message because this code does not work.
So, if a third party can send this type of code, every application can. So, if you can try to find an alternative ussd code , of the type that starts after usser presses the call button, you can achieve what you need. In this case, you must use the intent Intent.ACTION_CALL
// if you use the ACTION_DIAL intent, it opens the dialer and puts the given number into it. // Meanwhile, if we use ACTION_CALL, the application will call directly.
Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:"+ "*" + Uri.encode("#") + "0011" + Uri.encode("#")));
You also need to declare this permission in your manifest.
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
You could probably find an alternative code for this, since I saw several on the Internet, but at that moment no one worked for me. You can try try
Alternative 2. Wait for the official api to appear
On the project android project page in coogle code , a request appears to add support for the USSD API. He has a lot of subscribers, but he is quite old (more than 5 years), I am afraid that this is not very good. In any case, this can happen, probably, the android will consider preparing api so that the application can declare some permissions and make requests for some codes. But, I know, this can always wait.
So what to say. Good luck finding a solution or an alternative to your application. I wish my studies were more fruitful :(