在后台运行时显示弹出窗口?

我正在尝试从扩展服务的类中打开一个活动。当应用程序不在前台/未被使用时,我正在执行此任务。我可以在日志中看到我的服务类触发了具有Intent.FLAG_ACTIVITY_NEW_TASK标志的启动活动。但活动不会打开。但是,当服务在应用处于前台/正在使用时触发相同的活动时,活动将打开。

经过几次搜索,我发现我需要在应用程序设置的其他权限部分中手动授予“在后台Android中运行时显示弹出窗口”的权限。

显示其他应用程序权限SYSTEM_ALERT_WINDOW仅允许访问“显示弹出窗口”。

Other permissions

在上图中,SYSTEM_ALERT_WINDOW将仅授予您访问“显示弹出窗口”的权限,如果应用程序处于前台/正在使用中,这可以正常工作,但如果授予,则标记为红色的权限将允许您直接从扩展服务的类打开任何活动的权限。

如何检查或要求用户授予“在后台运行时显示弹出窗口”权限?或此权限是否受到限制?

我看到像Whatsapp这样的应用程序默认选中了这一点。


答案 1

这是开发人员的小米设备中的常见问题,

我们目前拥有的解决方案是将用户重定向到屏幕,并让用户手动授予权限:other permissions

if ("xiaomi" == Build.MANUFACTURER.toLowerCase(Locale.ROOT)) {
    val intent = Intent("miui.intent.action.APP_PERM_EDITOR")
    intent.setClassName("com.miui.securitycenter",
            "com.miui.permcenter.permissions.PermissionsEditorActivity")
    intent.putExtra("extra_pkgname", getPackageName())
    startActivity(intent)
}

仅当用户已提供“显示”弹出窗口(这意味着应用可以在系统 UI 上绘制)时,才能使用 来测试。Settings.canDrawOverlays(this)

其他两个权限无法验证用户是否已授予它们:

  1. 在后台运行时显示弹出窗口 :这意味着允许应用程序在后台运行时在系统UI上绘制,例如和servicesbroadcast
  2. 在锁定屏幕上显示 :这个使应用程序即使在屏幕像社交应用程序一样被锁定时也允许运行(whatsApp ,Viber ,Messnger ...)

答案 2

由于没有官方方法可以检查“在后台运行时显示弹出窗口”权限,因此我使用了一个小技巧来检查权限。

检查该应用程序是否可以绘制如下叠加层,然后如果设备是小米,则将用户导航到如下所示的特定设置屏幕。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (!Settings.canDrawOverlays(this)) {
                if ("xiaomi".equals(Build.MANUFACTURER.toLowerCase(Locale.ROOT))) {
                    final Intent intent =new Intent("miui.intent.action.APP_PERM_EDITOR");
                    intent.setClassName("com.miui.securitycenter",
                            "com.miui.permcenter.permissions.PermissionsEditorActivity");
                    intent.putExtra("extra_pkgname", getPackageName());
                    new AlertDialog.Builder(this)
                            .setTitle("Please Enable the additional permissions")
                            .setMessage("You will not receive notifications while the app is in background if you disable these permissions")
                            .setPositiveButton("Go to Settings", new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) {
                                    startActivity(intent);
                                }
                            })
                            .setIcon(android.R.drawable.ic_dialog_info)
                            .setCancelable(false)
                            .show();
                }else {
                    Intent overlaySettings = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
                    startActivityForResult(overlaySettings, OVERLAY_REQUEST_CODE);
                }
            }
        }

推荐