123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- /*
- * Copyright (c) 2020. BoostTag E.I.R.L. Romell D.Z.
- * All rights reserved
- * porfile.romellfudi.com
- */
- package com.romellfudi.ussdlibrary;
- import android.accessibilityservice.AccessibilityService;
- import android.content.ClipData;
- import android.content.ClipboardManager;
- import android.content.Context;
- import android.os.Build;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.accessibility.AccessibilityEvent;
- import android.view.accessibility.AccessibilityNodeInfo;
- import java.util.ArrayList;
- import java.util.List;
- /**
- * AccessibilityService for ussd windows on Android mobile Telcom
- *
- * @author Romell Dominguez
- * @version 1.1.c 27/09/2018
- * @since 1.0.a
- */
- public class USSDService extends AccessibilityService {
- private static String TAG = "USSDServiceUSSD";
- public static AccessibilityEvent event;
- @Override
- public void onAccessibilityEvent(AccessibilityEvent event) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
- this.event = new AccessibilityEvent(event);
- } else {
- this.event = event;
- }
- if (USSDController.instance == null || !USSDController.instance.isRunning) {
- return;
- }
- String response = event.getText().toString();
- if (LoginView(event) && notInputText(event)) {
- // first view or logView, do nothing, pass / FIRST MESSAGE
- clickOnButton(event, 0);
- USSDController.instance.isRunning = false;
- if (USSDController.instance.send)
- USSDController.instance.callbackMessage.over(response);
- else
- USSDController.instance.callbackInvoke.over(response);
- } else if (problemView(event) || LoginView(event)) {
- // deal down
- clickOnButton(event, 1);
- if (USSDController.instance.send)
- USSDController.instance.callbackMessage.over(response);
- else
- USSDController.instance.callbackInvoke.over(response);
- } else if (isUSSDWidget(event)) {
- // ready for work
- // if (response.contains("\n")) {
- // response = response.substring(response.indexOf('\n') + 1);
- // }
- if (notInputText(event)) {
- // not more input panels / LAST MESSAGE
- // sent 'OK' button
- clickOnButton(event, 0);
- USSDController.instance.isRunning = false;
- if (USSDController.instance.send)
- USSDController.instance.callbackMessage.over(response);
- else
- USSDController.instance.callbackInvoke.over(response);
- } else {
- // sent option 1
- // USSDController.instance.callbackInvoke = null;
- // USSDController.instance.callbackMessage = null;
- if (USSDController.instance.send)
- USSDController.instance.callbackMessage.responseMessage(response);
- else
- USSDController.instance.callbackInvoke.responseInvoke(response);
- }
- }
- }
- /**
- * Send whatever you want via USSD
- *
- * @param text any string
- */
- public static void send(String text) {
- setTextIntoField(event, text);
- clickOnButton(event, 1);
- }
- /**
- * Cancel USSD
- */
- public static void cancel() {
- clickOnButton(event, 0);
- }
- /**
- * set text into input text at USSD widget
- *
- * @param event AccessibilityEvent
- * @param data Any String
- */
- private static void setTextIntoField(AccessibilityEvent event, String data) {
- USSDController ussdController = USSDController.instance;
- Bundle arguments = new Bundle();
- arguments.putCharSequence(
- AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, data);
- for (AccessibilityNodeInfo leaf : getLeaves(event)) {
- if (leaf.getClassName().equals("android.widget.EditText")
- && !leaf.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)) {
- ClipboardManager clipboardManager = ((ClipboardManager) ussdController.context
- .getSystemService(Context.CLIPBOARD_SERVICE));
- if (clipboardManager != null) {
- clipboardManager.setPrimaryClip(ClipData.newPlainText("text", data));
- }
- leaf.performAction(AccessibilityNodeInfo.ACTION_PASTE);
- }
- }
- }
- /**
- * Method evaluate if USSD widget has input text
- *
- * @param event AccessibilityEvent
- * @return boolean has or not input text
- */
- protected static boolean notInputText(AccessibilityEvent event) {
- boolean flag = true;
- for (AccessibilityNodeInfo leaf : getLeaves(event)) {
- if (leaf.getClassName().equals("android.widget.EditText")) flag = false;
- }
- return flag;
- }
- /**
- * The AccessibilityEvent is instance of USSD Widget class
- *
- * @param event AccessibilityEvent
- * @return boolean AccessibilityEvent is USSD
- */
- private boolean isUSSDWidget(AccessibilityEvent event) {
- return (event.getClassName().equals("amigo.app.AmigoAlertDialog")
- || event.getClassName().equals("android.app.AlertDialog")
- || event.getClassName().equals("com.android.phone.oppo.settings.LocalAlertDialog")
- || event.getClassName().equals("com.zte.mifavor.widget.AlertDialog")
- || event.getClassName().equals("color.support.v7.app.AlertDialog")
- || event.getClassName().equals("com.transsion.widgetslib.dialog.PromptDialog")
- || event.getClassName().equals("miuix.appcompat.app.AlertDialog"));
- }
- /**
- * The View has a login message into USSD Widget
- *
- * @param event AccessibilityEvent
- * @return boolean USSD Widget has login message
- */
- private boolean LoginView(AccessibilityEvent event) {
- return isUSSDWidget(event)
- && USSDController.instance.map.get(USSDController.KEY_LOGIN)
- .contains(event.getText().get(0).toString());
- }
- /**
- * The View has a problem message into USSD Widget
- *
- * @param event AccessibilityEvent
- * @return boolean USSD Widget has problem message
- */
- protected boolean problemView(AccessibilityEvent event) {
- return isUSSDWidget(event)
- && USSDController.instance.map.get(USSDController.KEY_ERROR)
- .contains(event.getText().get(0).toString());
- }
- /**
- * click a button using the index
- *
- * @param event AccessibilityEvent
- * @param index button's index
- */
- protected static void clickOnButton(AccessibilityEvent event, int index) {
- int count = -1;
- for (AccessibilityNodeInfo leaf : getLeaves(event)) {
- if (leaf.getClassName().toString().toLowerCase().contains("button")) {
- count++;
- if (count == index) {
- leaf.performAction(AccessibilityNodeInfo.ACTION_CLICK);
- }
- }
- }
- }
- private static List<AccessibilityNodeInfo> getLeaves(AccessibilityEvent event) {
- List<AccessibilityNodeInfo> leaves = new ArrayList<>();
- if (event.getSource() != null) {
- getLeaves(leaves, event.getSource());
- }
- return leaves;
- }
- private static void getLeaves(List<AccessibilityNodeInfo> leaves, AccessibilityNodeInfo node) {
- if (node.getChildCount() == 0) {
- leaves.add(node);
- return;
- }
- for (int i = 0; i < node.getChildCount(); i++) {
- getLeaves(leaves, node.getChild(i));
- }
- }
- /**
- * Active when SO interrupt the application
- */
- @Override
- public void onInterrupt() {
- Log.d(TAG, "onInterrupt");
- }
- /**
- * Configure accessibility server from Android Operative System
- */
- @Override
- protected void onServiceConnected() {
- super.onServiceConnected();
- Log.d(TAG, "onServiceConnected");
- }
- }
|