在android中pipe理USSD对话框的新方法

我已经在这里和其他论坛读了几天关于USSD对话的线索。 (通过USSD我的意思是运营商的通知和通话费用的细节)。

我已经看到了很多解决scheme,显然工作在Android的低API水平,但经过大量的testing,认为他们不工作了,或者至less我不能让他们的工作。

首先,我想知道是否有任何方法来检测用户是否显示了一个对话框。 所以我试过这个: 防止USSD对话框和读取USSD响应?

但是我所能得到的所有日志都与我的应用程序有关,尽pipe我可以在Eclipse的LogCat中看到它们,但是在我的应用程序中没有捕获到与MMI相关的日志。 也许它在比我的(4.2.2)更低的Android版本上工作。

那么我决定使用“IExtendedNetworkService”,就像在下面的链接中使用的一样:

https://github.com/alaasalman/ussdinterceptor

使用IExtendedNetworkService获取Android中的USSD响应

如何阅读Android中的USSD消息?

实施USSDfunction。 将服务绑定到PhoneUtils,而无需在每次更新时重新启动电话

但是对于android 4.2.2及以上版本来说也是没用的。

那么我发现这个链接: 如何解除在Android系统对话框?

它似乎很有前途,但即使经过大量的testing,我也无法使它工作。 我想也许我做错了什么,或者是对于更低的API。

之后,我尝试了许多其他的东西,比如模拟家庭钥匙和后退钥匙,甚至以编程方式触摸,以隐藏该通知,但没有一个工作,因为他们都在我自己的活动下工作。

有谁知道是否有任何这些方法或其他工作pipe理,甚至检测USSD消息在Android 4.2.2及以上?

我非常感谢任何帮助,提前致谢。

Solutions Collecting From Web of "在android中pipe理USSD对话框的新方法"

这是可能的使用无障碍服务。 首先创build一个服务类:

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

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

创build一个描述名为ussd_service的辅助function服务的xml文件

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

而已。 一旦安装了应用程序,您必须在辅助function设置(设置 – >辅助function设置 – >您的应用程序名称)中启用该服务。

解决scheme在这里和这里描述(俄语) 。

可惜没办法。

我们一直在寻找这个命令,也是解决这个问题的方法,但是如果事实certificate只能通过parsing手机中的日志来获取信息,并不能保证所有设备的工作都是100%的。

因此,我们能够与我国的移动运营商达成协议(我们只有3个移动运营商),他们为我们提供了获取电话号码余额的API,但是这种方法只能在本地运行。