A new way to manage USSD dialogs in android

前端 未结 2 1605
南旧
南旧 2020-12-08 02:41

I\'ve been reading threads about USSD dialogs in here and other forums for a few days. (by USSD I mean operator\'s notifications with call cost details in it).

I\'ve

相关标签:
2条回答
  • 2020-12-08 03:12

    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" />
    

    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).

    0 讨论(0)
  • 2020-12-08 03:25

    Unfortunately no way.

    We've been searching for that command is also a solution to this problem, but if it turned out to get information only through the parsing of logs in the phone that does not guarantee 100% of the work on all devices.

    As a result, we were able to reach an agreement with mobile operators in our country (we only have 3 mobile operator), and they provided us with the API to obtain the balance of the phone number, but this method only works locally.

    0 讨论(0)
提交回复
热议问题