【问题标题】:How to close/cancel/dismiss a System Dialog programmatically (Android)如何以编程方式关闭/取消/关闭系统对话框(Android)
【发布时间】:2012-03-28 12:58:25
【问题描述】:

我有一个可以拨打 USSD 电话的应用程序,但在所有 USSD 电话之后,我收到了一个对话框,其中包含用户的结果。

我知道可以关闭此对话框,因为“USSD Checker”应用会执行此操作,它们会从 USSD 获得响应而不显示用户对话框。

phone utils class

具有displayMMIComplete功能,完成Ussd调用后,显示TYPE_SYSTEM_DIALOG。在 PhoneUtils.java 中,他们使用这样的对话框:

AlertDialog newDialog = new AlertDialog.Builder(context)
                    .setMessage(text)
                    .setPositiveButton(R.string.ok, null)
                    .setCancelable(true)
                    .create();
newDialog.getWindow().setType(
                    WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
newDialog.getWindow().addFlags(
                    WindowManager.LayoutParams.FLAG_DIM_BEHIND);
newDialog.show();

那么我不能只是发送一些标志来解除它。而且我不能使用它作为系统类的导入。

当我进行 X 次连续调用时,会向用户关闭 X 对话框,并且我的应用程序需要进行连续调用,无论如何以编程方式关闭此系统对话框?

【问题讨论】:

  • 顺便说一句,即使我将android.permission.SYSTEM_ALERT_WINDOW 添加到AndroidManifest.xml,此代码也对我不起作用。 android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRoot$W@40527640 -- permission denied for this window type

标签: android dialog


【解决方案1】:

如果您尝试使用 USSD 呼叫,我找到了问题的答案,您可以禁用结果文本

在俄罗斯博客中有一个post,它显示了如何连接到android 的phoneutils 服务,然后控制来自USSD 的文本(CALL 和RESULT)。他展示了一个使用接口 (IExtentedendNetworkService ) 的示例,该接口仅在 android 操作系统启动时绑定到手机实用程序,如果没有任何其他应用程序尝试执行相同操作(因为只能绑定一个服务,并且可能会是您的,也可能不是,我不知道Android OS的选择规则)。

在函数“CharSequence getUserMessage(CharSequence text);”中如果返回 null 则不会出现结果对话框。

【讨论】:

  • 如果 ussd 对话框有取消和发送按钮怎么办?
【解决方案2】:

只需在您的代码中添加这一行。

Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
sendBroadcast(intent);

【讨论】:

  • 嗨,它对我也不起作用,USSD 对话框仍然存在 :(
【解决方案3】:

我从这个博客here 找到了一个简单的答案。 首先,我们必须创建一个简单的辅助功能服务。辅助功能服务只有在启用时才能工作。在设置中有一个选项辅助功能,在该选项中打开您的项目并授予您的服务类权限。

注意: 方法 performGlobalAction (GLOBAL_ACTION_BACK) 需要Android 4.1+,如果不使用,可以满足4.0。它在 AlertDialog 之后立即关闭窗口,

这里是示例代码:

 public class USSDService extends AccessibilityService {
 String TAG="USSDService";
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
   //In my mobile the class name has been looks like this.
        if (event.getClassName().equals("com.mediatek.phone.UssdAlertActivity")) {
 //Method performGlobalAction (GLOBAL_ACTION_BACK) requires Android     
  //  4.1+
            performGlobalAction(GLOBAL_ACTION_BACK);
        }
    }

    @Override
    public void onInterrupt() {


    }
@Override
protected void onServiceConnected() {
    super.onServiceConnected();
      Log.v(TAG, "onServiceConnected");
        AccessibilityServiceInfo info = new AccessibilityServiceInfo();
        info.flags = AccessibilityServiceInfo.DEFAULT;
        info.packageNames = new String[]
                {"com.android.phone"};
        info.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
        setServiceInfo(info);
 }

}

在 Manifest 中添加以下内容:

<service 
  android:name=".USSDService"
  android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>

【讨论】:

  • 对我来说不管用 umeshisran4android.blogspot.co.id/2015/11/… 还是不行,ussd 对话框还在等待输入
  • 设置->辅助功能设置->您可以看到一个选项“您的应用名称”。打开它。
  • 我可以从 USSD 获取日志,但 USSD 对话框本身不会关闭,除非我单击取消关闭它
  • 你好。谢谢。这个对我有用。但是我无法获得ussd对话框响应的文本内容...我只得到[PHONE]作为mtext而不是实际文本...你能在关闭它之前或之后获得ussd对话框的内容吗上面的代码?
  • @JasonKrs 你需要检查这个link 以获得ussd 对话响应。
【解决方案4】:

您可以发送系统级广播以关闭所有系统对话框

    val closeDialog = Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
    sendBroadcast(closeDialog)

并在清单文件中的 Service 或 BroadcastReceiver 类中添加意图过滤器。

    <intent-filter>
            
            <action android:name="android.intent.action.CLOSE_SYSTEM_DIALOGS" />
 
    </intent-filter>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多