¿Previene el diálogo de USSD y lee la respuesta de USSD?

Hice muchas investigaciones sobre ussd pero no puedo leer la respuesta de USSD y cómo puedo evitar el diálogo de ussd como esta aplicación.

https://play.google.com/store/apps/details?id=com.iba.ussdchecker&hl=es

Instalo este https://github.com/alaasalman/ussdinterceptor reinicio de mi teléfono (S2 android 4.0.3), envío el código ussd pero no pasa nada, alguien me dice que tengo que leer el registro, pero ¿cómo puedo hacer eso?

Intento estos códigos para leer USSD del registro

USSD.java

package com.example.ussd; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Calendar; import java.util.Date; import java.text.ParseException; import java.text.SimpleDateFormat; import android.util.Log; public class USSD { private static String startmsg = "displayMMIComplete"; // start msg to look // for private static String endmsg = "MMI code has finished running"; // stop msg private static String trimmsg = "- using text from MMI message: '"; // a msg // to // remove // from // the // text private long before = 3000; // delay (ms) before creation of the class // before a msg (USDD) is valid (use timestamp) private long after = 3000; // delay (ms) after creation of the class that a // msg (USDD) is valid (wait after ms) private String msg = ""; // the USSD message private boolean found = false; private long t = -1; // timestamp of the found log public USSD() { this(3000, 3000); } // USSD in log : example public USSD(long before_creation, long after_creation) { before = before_creation; after = after_creation; long timestamp = System.currentTimeMillis(); // creation of the class // --> look for the USSD // msg in the logs Log.d("USSDClass", "Class creation - timestamp: " + String.valueOf(timestamp)); try { // sample code taken from alogcat ... Process logcatProc = Runtime.getRuntime().exec( "logcat -v time -b main PhoneUtils:D"); // get PhoneUtils // debug log with // time information BufferedReader mReader = new BufferedReader(new InputStreamReader( logcatProc.getInputStream()), 1024); String line = ""; boolean tostop = false; long stop = timestamp + after; // to stop the while after "after" ms while (((line = mReader.readLine()) != null) && (System.currentTimeMillis()  19) // the line should be at least with a // length of a timestamp (19) ! { if (line.contains(startmsg)) // check if it is a USSD msg { // log example : // "12-10 20:36:39.321 D/PhoneUtils( 178): displayMMIComplete: state=COMPLETE" t = extracttimestamp(line); // extract the timestamp of // thie msg Log.d("USSDClass", "Found line at timestamp : " + String.valueOf(t)); if (t >= timestamp - before) found = true; // start of an USDD is found & is // recent ! } else if (found) { // log example : // "12-10 20:36:39.321 D/PhoneUtils( 178): displayMMIComplete: state=COMPLETE" if (line.contains(endmsg)) tostop = true; else { // log example : // "12-10 20:36:39.321 D/PhoneUtils( 178): - using text from MMI message: 'Your USSD message with one or several lines" Log.d("USSDClass", "Line content : " + line); String[] v = line.split("\\): "); // doesn't need // log // information // --> split // with "): " // separator if (v.length > 1) msg += v[1].replace(trimmsg, "").trim() + "\n"; } } } } } catch (IOException e) { Log.d("USSDClass", "Exception:" + e.toString()); } } public boolean IsFound() { return found; } public String getMsg() { return msg; } // extract timestamp from a log line with format // "MM-dd HH:mm:ss.ms Level/App:msg" Example : 12-10 20:36:39.321 // Note : known bug : happy new year check will not work !!! private long extracttimestamp(String line) { long timestamp = -1; // default value if no timestamp is found String[] v = line.split(" "); if (v.length > 1) // check if there is space { Calendar C = Calendar.getInstance(); int y = C.get(Calendar.YEAR); String txt = v[0] + "-" + y + " " + v[1]; // transform in format // "MM-dd-yyyy HH:mm:ss" SimpleDateFormat formatter = new SimpleDateFormat( "MM-dd-yyyy HH:mm:ss"); try { Date tmp = formatter.parse(txt); timestamp = tmp.getTime(); String[] ms = v[1].split("."); // get ms if (ms.length > 1) timestamp += Integer.getInteger(ms[1]); } catch (ParseException e) { Log.d("USSDClass", "USDD.extractimestamp exception:" + e.toString()); } } return timestamp; } } 

UssdActivity.java

 package com.example.ussd; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.TextView; public class UssdActivity extends Activity implements OnClickListener { /** Called when the activity is first created. */ private TextView view; private AutoCompleteTextView number; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button = (Button) findViewById(R.id.button1); button.setOnClickListener(this); this.view = (TextView) findViewById(R.id.Text2); this.number = (AutoCompleteTextView) findViewById(R.id.Text1); } @Override public void onClick(View arg0) { String encodedHash = Uri.encode("#"); call("*" + number.getText() + encodedHash); this.view.setText(""); } protected void call(String phoneNumber) { try { startActivityForResult( new Intent("android.intent.action.CALL", Uri.parse("tel:" + phoneNumber)), 1); } catch (Exception eExcept) { this.view.append("\n\n " + "\n" + eExcept.toString()); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { USSD ussd = new USSD(4000, 4000); if (ussd.IsFound()) this.view.append("\n test" + ussd.getMsg()); else this.view.append("" + R.string.error_ussd_msg); } } 

y la salida es algo como esto:

 com.sec.android.app.callsetting.allcalls:com.sec.android.callsetting.allcalls.AllCallsProvider Terminated ALSA PLAYBACK device hifi 

Es posible usar el servicio de accesibilidad. Primero crea una clase de servicio:

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

Declararlo en Android manifest

      

Cree un archivo xml que describa el servicio de accesibilidad llamado ussd_service

 < ?xml version="1.0" encoding="utf-8"?>  

Eso es. Una vez que la aplicación está instalada, debe habilitar el servicio en Configuración de accesibilidad (Configuración-> Configuración de accesibilidad -> Nombre de su aplicación).

Solución descrita aquí y aquí (en ruso) .

Funciona en Android 2.3, pero no estoy completamente seguro de si esto puede funcionar en una versión superior, siga las instrucciones:

  1. Conecte su teléfono USB a su computadora (Modo de depuración)
  2. Escriba adb devices (su teléfono debe estar en la lista)
  3. Escriba el adb shell
  4. Escriba logcat -v time -b main PhoneUtils:D > output.txt
  5. Ahora en su teléfono, envíe un ejemplo de código ussd: # 123 # espere un momento y luego en su consola presione Ctrl + C
  6. Lea el output.txt y encuentre esta palabra displayMMIComplete

Use IExtendedNetworkService.aidl

Cree este archivo en la ruta com \ android \ internal \ telefonía

 package com.android.internal.telephony; /** * Interface used to interact with extended MMI/USSD network service. */ interface IExtendedNetworkService { /** * Set a MMI/USSD command to ExtendedNetworkService for further process. * This should be called when a MMI command is placed from panel. * @param number the dialed MMI/USSD number. */ void setMmiString(String number); /** * return the specific string which is used to prompt MMI/USSD is running */ CharSequence getMmiRunningText(); /** * Get specific message which should be displayed on pop-up dialog. * @param text original MMI/USSD message response from framework * @return specific user message correspond to text. null stands for no pop-up dialog need to show. */ CharSequence getUserMessage(CharSequence text); /** * Clear pre-set MMI/USSD command. * This should be called when user cancel a pre-dialed MMI command. */ void clearMmiString(); } 

Agregue el filtro com.android.ussd.IExtendedNetworkService en manifast:

 < ?xml version="1.0" encoding="UTF-8"?>         

CDUSSDService.java

 import com.android.internal.telephony.IExtendedNetworkService; public class CDUSSDService extends Service { private boolean mActive = false; // we will only activate this // "USSD listener" when we want it private final IExtendedNetworkService.Stub mBinder = new IExtendedNetworkService.Stub() { public void clearMmiString() throws RemoteException { // Log.d(TAG, "called clear"); } public void setMmiString(String number) throws RemoteException { clearMmiString(); Log.d(TAG, "setMmiString:" + number); ussdcode = number; } public CharSequence getMmiRunningText() throws RemoteException { if (mActive == true) { return null; } Log.d(TAG, "USSD code running..."); return "USSD code running..."; } public CharSequence getUserMessage(CharSequence text) throws RemoteException { Intent iBroad = new Intent(getString(R.string.EXTRA_ACTION_USSD)); iBroad.putExtra(getString(R.string.EXTRA_USSD_MSG), text); iBroad.putExtra(getString(R.string.EXTRA_USSD_CODE), ussdcode); sendBroadcast(iBroad); if (mActive == false) { // listener is still inactive, so return whatever we got Log.d(TAG, " seven sky " + text); return text; } // listener is active, so broadcast data and suppress it from // default behavior // build data to send with intent for activity, format URI as per // RFC 2396 Uri ussdDataUri = new Uri.Builder() .scheme(getBaseContext().getString(R.string.uri_scheme)) .authority( getBaseContext().getString(R.string.uri_authority)) .path(getBaseContext().getString(R.string.uri_path)) .appendQueryParameter( getBaseContext().getString(R.string.uri_param_name), text.toString()).build(); // if (!hidden) sendBroadcast(new Intent(Intent.ACTION_GET_CONTENT, ussdDataUri)); Log.d(TAG, "" + ussdDataUri.toString()); mActive = false; return null; } }; @Override public IBinder onBind(Intent intent) { // Log.i(TAG, "called onbind"); // the insert/delete intents will be fired by activity to // activate/deactivate listener since service cannot be stopped return mBinder; } } 

Una vez que el dispositivo debe reiniciarse para funcionar