8

Some custom dialer apps (for example, Dialer from MotoBlur) are able to do USSD requests. Is it realy impossible to do this via SDK?

Nikhil
  • 16,194
  • 20
  • 64
  • 81
artem
  • 16,382
  • 34
  • 113
  • 189

5 Answers5

16

Ussd api was added in API26. So since Oreo working with ussd looks smt like this:

    TelephonyManager manager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
    manager.sendUssdRequest("*100#", new TelephonyManager.UssdResponseCallback() {
        @Override
        public void onReceiveUssdResponse(TelephonyManager telephonyManager, String request, CharSequence response) {
            super.onReceiveUssdResponse(telephonyManager, request, response);
        }

        @Override
        public void onReceiveUssdResponseFailed(TelephonyManager telephonyManager, String request, int failureCode) {
            super.onReceiveUssdResponseFailed(telephonyManager, request, failureCode);
        }
    }, new Handler());

    TelephonyManager manager2 = manager.createForSubscriptionId(subIdForSecondSlotFromSubscriptonManager);
    manager2.sendUssdRequest(...);

To get the simIDs, you can use the below:

    SubscriptionManager subscriptionManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);

    List<SubscriptionInfo> subscriptionInfoList = subscriptionManager.getActiveSubscriptionInfoList();

    for (SubscriptionInfo subscriptionInfo : subscriptionInfoList) {
        int subscriptionId = subscriptionInfo.getSubscriptionId();
        Log.d("Sims", "subscriptionId:" + subscriptionId);
    }

    if (subscriptionInfoList != null) {
        if (subscriptionInfoList.size() == 1) {
            sim1 = subscriptionInfoList.get(0).getDisplayName().toString();
            tvSim1.setText(sim1);
        } else {
            sim1 = subscriptionInfoList.get(0).getDisplayName().toString();
            sim2 = subscriptionInfoList.get(1).getDisplayName().toString();

            tvSim1.setText(sim1);
            tvSim2.setText(sim2);
        }

    }
Mikhail Sidorov
  • 699
  • 2
  • 9
  • 18
  • 1
    Hey Mikhail, you're the only one with the new API 27 code... COuld you elaborate a little bit ? I don't understand `manager2` code for `createForSubscriptionId`.... So for now my USSD is not sent yet – Jason Krs May 26 '18 at 21:37
  • manager2 code is for dual sim phones, when you what to send ussd from the second simcard. subIdForSecondSlotFromSubscriptonManager - is a second slot ID – Mikhail Sidorov Jun 04 '18 at 15:23
  • Awesome.... I was looking for that... But how do I set the value for `subIdForSecondSlotFromSubscriptonManager ` ? Also, is there a `subIdForFirstSlotFromSubscriptonManager` value for the first slot ? I'm saying that in case slot 2 is the primary slot in my dual sim phone – Jason Krs Jun 09 '18 at 17:25
  • 1
    You can get a list of subscriptions and find in it subscription for slot `List sims = SubscriptionManager.from(context).getActiveSubscriptionInfoList(); for(SubscriptionInfo subInfo : sims){ ... slotIndex = subInfo.getSimSlotIndex() ... subscriptionForSlot = subInfo.getSubscriptionId() }` – Mikhail Sidorov Jun 10 '18 at 18:02
10

You can intercept the USSD reponse , In order to do that you need to implement IExtendedNetworkService.aidl interface which binds the service with PhoneUtils. It then can intercept any USSD response and you can read that in your app easily . FYI https://github.com/alaasalman/ussdinterceptor

Mani
  • 176
  • 3
  • 11
10

You can dial ussd requests like any other number with an call-intent like this one:

String encodedHash = Uri.encode("#");
String ussd = "*" + encodedHash + "12345" + encodedHash;
startActivityForResult(new Intent("android.intent.action.CALL", Uri.parse("tel:" + ussd)), 1);

However, afaik, it's currently not possible to parse the result string in your app.

alexleutgoeb
  • 3,123
  • 3
  • 20
  • 31
  • 3
    You can send requests, but there is no means for an application to obtain a result. Some developers have requested that this be added to android, but there's been no indication that the feature request has been accepted. – Chris Stratton Aug 29 '11 at 01:04
  • 2
    But what is the reason behind appending # after *? – AndroGeek Jun 19 '13 at 06:12
  • 1
    This is just part of an actual USSD number and therefore an implementation detail of a local operator, nevermind – alexleutgoeb Mar 05 '15 at 16:14
  • 1
    Better way to construct Uri object: `Uri.fromParts("tel", "*#12345#", null)`. You don't need to encode/parse. – spatar Sep 19 '19 at 17:07
6

Starting from Android O it's possible to send USSD requests using the TelephonyManager.

greywolf82
  • 21,813
  • 18
  • 54
  • 108
0

hope it work for you:

String suffix = Uri.encode("#");
String ussd = suffix+"919"+"*"+number+suffix;

Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:"+ ussd));
startActivity(callIntent);