web-dev-qa-db-fra.com

Une nouvelle façon de gérer les dialogues USSD sous Android

Je lis des discussions sur les dialogues USSD ici et sur d'autres forums depuis quelques jours. (par USSD, je veux dire les notifications de l'opérateur avec le détail du coût des appels).

J'ai vu de nombreuses solutions qui fonctionnaient apparemment pour des niveaux d'API plus faibles dans Android, mais après de nombreux tests, elles ont déterminé qu'elles ne fonctionnaient plus ou du moins que je ne pouvais pas les faire fonctionner.

D'abord, je voulais savoir s'il y avait un moyen de détecter si un dialogue ussd a été montré à l'utilisateur. J'ai donc essayé ceci: Empêcher le dialogue USSD et lire la réponse USSD?

mais tout ce que je pouvais obtenir des journaux était en quelque sorte lié à mon application, même si je pouvais les voir dans LogCat d’Eclipse, mais aucun journal lié à MMI n’était capturé dans mon application! .2).

alors j'ai décidé d'utiliser "IExtendedNetworkService" comme il était utilisé dans les liens suivants et beaucoup d'autres:

https://github.com/alaasalman/ussdinterceptor

Utilisation de IExtendedNetworkService pour obtenir une réponse USSD sous Android

Comment lire les messages USSD sous Android?

Implémentation des fonctionnalités USSD. Liaison d’un service à PhoneUtils sans redémarrer le téléphone à chaque mise à jour

mais c'était aussi inutile pour Android 4.2.2 et supérieur.

alors j'ai trouvé ce lien: Comment fermer le dialogue système sous Android?

cela semblait prometteur mais je ne pouvais pas le faire fonctionner même après de nombreux tests. Je pensais que je faisais peut-être quelque chose de mal ou que c'était aussi pour des API plus faibles.

après cela, j'ai essayé beaucoup d'autres choses, comme simuler les touches home et back et même toucher par programmation pour masquer cette notification, mais aucune d'entre elles ne fonctionnait, car elles fonctionnaient toutes sous ma propre activité.

Est-ce que quelqu'un sait si l'une de ces méthodes ou d'autres fonctionnent pour gérer ou même détecter les messages USSD dans Android 4.2.2 et versions ultérieures?

J'apprécie vraiment toute aide, Merci d'avance.

31
Lord Sepid

Il est possible d’utiliser le service d’accessibilité. Créez d’abord une classe de service:

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

Déclarez-le dans le manifeste Android

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

Créez un fichier XML décrivant le service d'accessibilité appelé 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" />

C'est tout. Une fois l'application installée, vous devez activer le service dans les paramètres d'accessibilité (Paramètre -> Paramètre d'accessibilité -> VotreNomApp).

Solution décrite ici et ici (russe) .

8
HenBoy331

Malheureusement pas moyen.

Nous avons cherché cette commande est aussi une solution à ce problème, mais s'il s'avérait obtenir des informations uniquement via l'analyse des journaux du téléphone, cela ne garantit pas 100% du travail sur tous les appareils.

En conséquence, nous avons pu parvenir à un accord avec les opérateurs de téléphonie mobile de notre pays (nous n’avons que 3 opérateurs de téléphonie mobile), et ils nous ont fourni l’API pour obtenir le solde du numéro de téléphone, mais cette méthode ne fonctionne que localement.

0
Yaroslav Samardak