Prevent Ussd Dialog and Read Ussd Response

Prevent USSD dialog and read USSD response?

It is possible using accessibility service.
First create a service class:

public class USSDService extends AccessibilityService {

public static String TAG = USSDService.class.getSimpleName();

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.d(TAG, "onAccessibilityEvent");

AccessibilityNodeInfo source = event.getSource();
/* if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && !event.getClassName().equals("android.app.AlertDialog")) { // android.app.AlertDialog is the standard but not for all phones */
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED && !String.valueOf(event.getClassName()).contains("AlertDialog")) {
return;
}
if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED && (source == null || !source.getClassName().equals("android.widget.TextView"))) {
return;
}
if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED && TextUtils.isEmpty(source.getText())) {
return;
}

List<CharSequence> eventText;

if(event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
eventText = event.getText();
} else {
eventText = Collections.singletonList(source.getText());
}

String text = processUSSDText(eventText);

if( TextUtils.isEmpty(text) ) return;

// Close dialog
performGlobalAction(GLOBAL_ACTION_BACK); // This works on 4.1+ only

Log.d(TAG, text);
// Handle USSD response here

}

private String processUSSDText(List<CharSequence> eventText) {
for (CharSequence s : eventText) {
String text = String.valueOf(s);
// Return text if text is the expected ussd response
if( true ) {
return text;
}
}
return null;
}

@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 | AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
setServiceInfo(info);
}
}

Declare it in Android manifest

<service android:name=".USSDService"
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/ussd_service" />
</service>

Create a xml file that describes the accessibility service called ussd_service

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeWindowStateChanged|typeWindowContentChanged"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagDefault"
android:canRetrieveWindowContent="true"
android:description="@string/accessibility_service_description"
android:notificationTimeout="0"
android:packageNames="com.android.phone" />

That's it. Once app is installed, you have to enable the service in Accessibility Settings (Setting->Accessibility Setting -> YourAppName).

Solution described here and here (russian).

How to read USSD Message response in android

You need to build an AccessibilityService in order to do that you need to read the documentation of AccessibilityService in below link
https://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html

and also this question helped me

Prevent USSD dialog and read USSD response?

How to read USSD messages in android?

There is no API for USSD request yet. The ticket to create this API is not closed. But the community has found several hacks how to add this feature to their applications.

  1. The first approach is to parse a log. Here is where you can find a class that do this. And here is a test application that uses this class.
  2. Also there is a second approach.

Good luck!

Fetch and parse USSD response data

Finally able to get response, Basically a background "Accessibility Service" is running which receives callback by the system whenever system accessible events are fired and app filter out the event when alert dialogue after calling USSD which in our case "android.app.AlertDialog" is shown and at this instance we can retrieve the data sent by the operator.
"Accessibility Service" for particular app needs to be enabled manually by the end user not programmatically by code because of security purpose mentioned by android.

How to interact with USSD dialog programmatically in android

For interacting with USSD dialog, I used below code.

I used the below code for click event:

List<AccessibilityNodeInfo> list = nodeInfo.findAccessibilityNodeInfosByText("Send");
for (AccessibilityNodeInfo node : list) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}

I used the below code for setText in EditText. This is setText where the current focus is.

AccessibilityNodeInfo nodeInput = nodeInfo.findFocus(AccessibilityNodeInfo.FOCUS_INPUT);
Bundle bundle = new Bundle();
bundle.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,pMPIN);
nodeInput.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT,bundle);
nodeInput.refresh();

Stuck in developing an interactive USSD app

I noticed that this is NOT supported for Android below API 5, but runs fine in API 6 and above.



Related Topics



Leave a reply



Submit