Friday 27 November 2015

How to read/parse USSD messages in Android .?



What is USSD.?

USSD is a communication technology that is used to send text between a mobile phone and an application program(network operator) in the network.


What are USSD codes.?

USSD codes are used by network users to get usage infromation from the current operator. USSD codes start with *, preceeding with numbers and end up with #. Ex : *123#
Different network operators have different USSD codes. Ex :
*123# is used to get usage information for Airtel
*111# is used to get usage information for Vadafone


How do we get this USSD information in android application.?

The below code will display a USSD popup, showing the balance information for the current sim

// Get vadafone balance(*111*2for vadafone)

private void dailNumber(String code) {
    String ussdCode = "*" + code + Uri.encode("#");
    startActivity(new Intent("android.intent.action.CALL", Uri.parse("tel:" + ussdCode)));
}

Add the following permission (to make a call) in the manifest

<uses-permission android:name="android.permission.CALL_PHONE" />


How to handle/read/parse USSD messages from popup.?

An accessibility service runs in the background and receives callbacks by the system when AccessibilityEvents are fired. Such events denote some state transition in the user interface, for example, the focus has changed, a button has been clicked, a popup dialog etc.

So the trick is, this service will deliver us an event, from which we can get the USSD message.


Steps to implement


1. Write a class named "XXXX"


public class XXXX extends AccessibilityService {


    public static String TAG = "XXXX";


    @Override

    public void onAccessibilityEvent(AccessibilityEvent event) {
        Log.d(TAG, "onAccessibilityEvent");
        String text = event.getText().toString();

        if (event.getClassName().equals("android.app.AlertDialog")) {

            performGlobalAction(GLOBAL_ACTION_BACK);
            Log.d(TAG, text);
            Intent intent = new Intent("com.times.ussd.action.REFRESH");
            intent.putExtra("message", text);
       // write a broad cast receiver and call sendbroadcast() from here, if you want to parse the message for balance, date
        }

    }


    @Override

    public void onInterrupt() {
    }

    @Override

    protected void onServiceConnected() {
        super.onServiceConnected();
        Log.d(TAG, "onServiceConnected");
        AccessibilityServiceInfo info = new AccessibilityServiceInfo();
        info.flags = AccessibilityServiceInfo.DEFAULT;
        info.packageNames = new String[]{"com.android.phone"};
        info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
        setServiceInfo(info);
    }

}



2. Add an entry for the above service in the manifest


<service android:name=".XXXX"

    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data android:name="android.accessibilityservice"
        android:resource="@xml/config_service" /> // created below
</service>


3. Create a folder 'xml' under res, and then create file named "config_service.xml" in xml folder.


<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"

    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:accessibilityFlags="flagDefault"
    android:canRetrieveWindowContent="true"
    android:description="This service records pop ups sent by your mobile operator, and saves them in XXXX App. It is absolutely safe to use." //declare this in string.xml
    android:notificationTimeout="100"
    android:packageNames="com.times.ussd"
    android:settingsActivity="com.example.android.accessibility.ServiceSettingsActivity" />

To run a accessibility service, user permissions are needed. The above xml is used to provide the necessary description to the user .



4. Now in your activity, invoke this


    startService(new Intent(this, XXXX.class));
    dailNumber("*111*2");


5. Launch your application.


6. After the launch, change the settings manually


Setting->Accessibility Setting -> You can see a option 'your app name'. Turn it on. (This has to be done from as a part of application flow(not manual))


7. Restart your application, and check the logs, that I wrote in Service class



Happy to see the USSD logs.. CHEERS :)


Feel free to ask if you face any difficulties with the above explanation..


Please give your feedback on this post as a like, comment, share..