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!)
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;