Using IExtendedNetworkService to get USSD response in Android
Asked Answered
T

1

7

I'm trying to find the way to make USSD requests in Android. I found this - http://commandus.com/blog/?p=58 . I added all needed files to my project.

USSDDumbExtendedNetworkService.java:

package com.android.ussdcodes;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.IBinder;
import android.os.PatternMatcher;
import android.os.RemoteException;
import android.util.Log;

import com.android.internal.telephony.IExtendedNetworkService;
import com.android.ussdcodes.R;

/**
 * Service implements IExtendedNetworkService interface. 
 * USSDDumbExtendedNetworkService
 * Service must have name "com.android.ussd.IExtendedNetworkService" of the intent declared
 * in the Android manifest file so com.android.phone.PhoneUtils class bind
 * to this service after system rebooted.
 * Please note service is loaded after system reboot! 
 * Your application must check is system rebooted. 
 * @see Util#syslogHasLine(String, String, String, boolean)   
 */
public class USSDDumbExtendedNetworkService extends Service {
    public static final String TAG = "CommandusUSSDExtNetSvc";
    public static final String LOG_STAMP = "*USSDTestExtendedNetworkService bind successfully*";
    public static final String URI_SCHEME = "ussdcodes";
    public static final String URI_AUTHORITY = "android.com";
    public static final String URI_PATH = "/";
    public static final String URI_PAR = "return";
    public static final String URI_PARON = "on";
    public static final String URI_PAROFF = "off";
    public static final String MAGIC_ON = ":ON;)";
    public static final String MAGIC_OFF = ":OFF;(";
    public static final String MAGIC_RETVAL = ":RETVAL;(";

    private static boolean mActive = false;
    private static CharSequence mRetVal = null;
    private Context mContext = null;
    private String msgUssdRunning = "USSD running..."; 

    final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_INSERT.equals(intent.getAction())) {
                mContext = context;
                if (mContext != null) {
                    msgUssdRunning = mContext.getString(R.string.USSD_run);
                    mActive = true;
                    Log.d(TAG, "activate");
                }
            } else if (Intent.ACTION_DELETE.equals(intent.getAction())) {
                mContext = null;
                mActive = false;
                Log.d(TAG, "deactivate");
            }
        }
    };

    private final IExtendedNetworkService.Stub mBinder = new IExtendedNetworkService.Stub() {
        @Override
        public void setMmiString(String number) throws RemoteException {
            Log.d(TAG, "setMmiString: " + number);
        }

        @Override
        public CharSequence getMmiRunningText() throws RemoteException {
            Log.d(TAG, "getMmiRunningText: " + msgUssdRunning);
            return msgUssdRunning;
        }

        @Override
        public CharSequence getUserMessage(CharSequence text)
                throws RemoteException {
            if (MAGIC_ON.contentEquals(text)) {
                mActive = true;
                Log.d(TAG, "control: ON");
                return text;
            } else {
                if (MAGIC_OFF.contentEquals(text)) {
                    mActive = false;
                    Log.d(TAG, "control: OFF");
                    return text;
                } else {
                    if (MAGIC_RETVAL.contentEquals(text)) {
                        mActive = false;
                        Log.d(TAG, "control: return");
                        return mRetVal;
                    }
                }
            }

            if (!mActive) {
                Log.d(TAG, "getUserMessage deactivated: " + text);
                return text;
            }
            String s = text.toString();
            // store s to the !
            Uri uri = new Uri.Builder()
                .scheme(URI_SCHEME)
                .authority(URI_AUTHORITY)
                .path(URI_PATH)
                .appendQueryParameter(URI_PAR, text.toString())
                .build();
            sendBroadcast(new Intent(Intent.ACTION_GET_CONTENT, uri));
            mActive = false;
            mRetVal = text;
            Log.d(TAG, "getUserMessage: " + text + "=" + s);
            return null;
        }

        @Override
        public void clearMmiString() throws RemoteException {
            Log.d(TAG, "clearMmiString");
        }
    };


    /**
     * Put stamp to the system log when PhoneUtils bind to the service
     * after Android has rebooted. Application must call {@link Util#syslogHasLine(String, String, String, boolean)} to 
     * check is phone rebooted or no. Without reboot phone application does not bind tom this service! 
     */
    @Override
    public IBinder onBind(Intent intent) {
        // Do not localize!
        Log.i(TAG, LOG_STAMP);
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_INSERT);
        filter.addAction(Intent.ACTION_DELETE);
        filter.addDataScheme(URI_SCHEME);
        filter.addDataAuthority(URI_AUTHORITY, null);
        filter.addDataPath(URI_PATH, PatternMatcher.PATTERN_LITERAL);
        registerReceiver(mReceiver, filter);

        return mBinder; 
    }

    public IBinder asBinder() {
        Log.d(TAG, "asBinder");
        return mBinder;
    }

}

Manifest:

<receiver android:name="com.android.ussdcodes.BootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <service
            android:name=".USSDDumbExtendedNetworkService" >
            <intent-filter android:icon="@drawable/ic_launcher">
                <action android:name="com.android.ussd.IExtendedNetworkService" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </service>

BootReceiver.java:

package com.android.ussdcodes;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class BootReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        Log.d("USSDService", context.getString(R.string.service_started));
        context.startService(new Intent(context,USSDDumbExtendedNetworkService.class));
    }

}

So now the service starts after boot complete.

And my question is how I have to send USSD request and get responce with service? Thanks!)

Tighten answered 3/1, 2013 at 23:25 Comment(4)
Can you find out how to do that?I am looking for same thing :(Polyethylene
com.android.internal.telephony.IExtendedNetworkService; cannot be resolved. Can you just tell me what is your minimum sdk version?Effectuate
Have you added com.android.internal.telephony package with IExtendedNetworkService.aidl as it's said in tutorial at the beginning of the question.(gist.github.com/victorkifer/9384471)Tighten
Ok I solved it... .aidl wasnt in the directory i specified. Now how do i call USSD from the activity? Thanks in advance.Effectuate
T
2

Well, I have found the answer.

I just put the link on my gist.

Deactivate messages

USSDDumbExtendedNetworkService.mActive = false;

Send USSD:

Intent launchCall = new Intent(Intent.ACTION_CALL,
                        Uri.parse("tel:" + Uri.encode(ussdcode)));
launchCall.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
launchCall.addFlags(Intent.FLAG_FROM_BACKGROUND);
startActivity(launchCall);

Activate messages again

USSDDumbExtendedNetworkService.mActive = true;
USSDDumbExtendedNetworkService.mRetVal = null;
Tighten answered 14/10, 2013 at 20:43 Comment(8)
What version of android have you tested it on?Malady
I've been struggling to make this example work, but without any result. Then I found thisMalady
I've tested it on 4.1.1Malady
@Arhimed: how you solved this issue? Please provide a correct code here as I'm looking for it solutionLiftoff
@arhimed pls provide working solution or code else steps to createMetzgar
@arhimed is there any way to read USSD message ?if yes then please please ping meFoothill
@ViktorK I don't understand your answer... I too have added the file of the tutorial... But the way you caught the ussd response text, I don't see that nor understand that...Incommode
@VaishaliSutariya Did you find a way to do that ? Ping me if you didIncommode

© 2022 - 2024 — McMap. All rights reserved.