j'ai fait beaucoup de recherches sur ussd mais je ne peux pas lire la réponse USSD et comment puis-je empêcher le dialogue ussd comme cette application.
https://play.google.com/store/apps/details?id=com.iba.ussdchecker&hl=en
j'installe cela https://github.com/alaasalman/ussdinterceptor redémarrer mon téléphone (S2 Android 4.0.3), envoyer du code ussd mais rien ne se passe, quelqu'un dit moi que je dois lire le journal, mais comment puis-je le faire.
j'essaie ce code pour lire l'USSD depuis le journal
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() < stop) && (tostop == false)) {
if (line.length() > 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);
}
}
et la sortie est quelque chose comme ceci:
com.sec.Android.app.callsetting.allcalls:com.sec.Android.callsetting.allcalls.AllCallsProvider Terminated ALSA PLAYBACK device hifi
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 Android 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" />
</service>
Créez un fichier xml qui décrit 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ètres-> Paramètres d'accessibilité -> YourAppName).
Solution décrite ici et ici (russe) .
Cela fonctionne en Android 2.3, mais je ne suis pas sûr que cela puisse fonctionner dans une version supérieure, suivez les instructions:
adb devices
(votre téléphone doit être répertorié)adb Shell
logcat -v time -b main PhoneUtils:D > output.txt
output.txt
et trouver ce mot displayMMIComplete
Utilisez IExtendedNetworkService.aidl
Créez ce fichier dans le chemin com\Android\internal\telephony
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();
}
Ajoutez le filtre com.Android.ussd.IExtendedNetworkService dans le manifeste:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
>
<application
Android:icon="@drawable/icon"
Android:label="@string/app_name" >
<service
Android:name=".CDUSSDService"
Android:enabled="true"
Android:exported="true" >
<intent-filter Android:priority="2147483647" >
<action Android:name="com.Android.ussd.IExtendedNetworkService" />
</intent-filter>
</application>
</manifest>
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;
}
}
Une fois que l'appareil doit redémarrer pour fonctionner