SYSTEM_ALERT_WINDOW - 如何在Android 6.0和targetSdkVersion 23上自动获取此权限

99
Facebook、Evernote和Pocket都会自动获得 Android 6.0 上的此权限,即使它们的目标版本是23(targetSdkVersion=23)。
新版Marshmallow权限模型有很多文档,其中一个是将SYSTEM_ALERT_WINDOW提升为'above dangerous' 权限级别,因此需要特殊用户干预才能授予应用程序这些权限。如果应用程序具有targetSdkVersion 22或更低版本,则可以在清单中请求时自动获得此权限。
然而我注意到有些应用程序可以获得此权限,而不需要将用户发送到“绘制其他应用程序”的特殊页面。我发现 Facebook、Evernote 和 Pocket 可以,并且可能还有其他应用。
有人知道如何让应用程序在用户不经过 "设置-》应用程序-》绘制其他应用程序" 的步骤下获得此权限吗?
谢谢

这篇文章帮助了我:https://dev59.com/l1wY5IYBdhLWcg3wATpt - Bharath
这篇帖子帮助我展示了在Android 6.0 Marshmallow中写入SD卡的对话框权限。 - Bharath
1
更新2020年:https://dev59.com/7VoV5IYBdhLWcg3wnf7r#60005258 - Kzaf
5个回答

123

这是在Marshmallow6.0.1中引入的新行为。

每个通过Play商店安装(需要版本6.0.5或更高)并请求SYSTEM_ALERT_WINDOW权限的应用程序将自动被授予权限。

如果应用程序是通过侧载方式安装的,则不会自动授予该权限。您可以尝试从apkmirror.com下载并安装Evernote APK。正如您所看到的,您需要手动在“设置 -> 应用程序 -> 绘制其他应用程序上方”中授予该权限。

这些是允许Play商店自动授予SYSTEM_ALERT_WINDOW权限的提交[1] [2]


7
我想知道为什么一个“高危”权限突然变成了“低于正常水平”的权限。我的意思是,你甚至不能在弹出窗口中看到这个权限,而应用程序可以自动获得它。有什么想法吗? - oriharel
3
我想知道 Facebook Messenger 的大规模使用是否促使 Google 支持这一功能。可能是因为 Facebook 与 Google 达成协议,不强制用户授予权限,以便 chatheads 能够继续工作。请问需要翻译什么? - dennisdrew
3
当我询问自动授权权限的行为时(我认为原因是目标SDK),Google的回应是:“这是一种旨在允许流行应用程序继续工作的预期行为,直到我们在平台上为这些应用程序提供替代API迁移的解决方案。” 这里是相关的帖子链接:https://code.google.com/p/android/issues/detail?id=227123 和 https://code.google.com/p/android/issues/detail?id=222195。 - android developer
我刚刚侧载了9Apps和Vidmate,然后它们自动获得了在其他应用程序上绘制的权限。有什么线索吗? - Gautam
1
@MattiaMaestrini,你能看一下这个类似的问题吗?https://dev59.com/7bHma4cB1Zd3GeqPK2VE - ram
显示剩余5条评论

98
在 Marshmallow 之后,Android 加强了安全级别。但是对于 SYSTEM_ALERT_WINDOW ,您可以显示浮动操作和任何内容。您可以通过在 onCreate() 方法中遵循以下代码来强制用户授权:
将此代码放置在 setContentView 之后:
    // Check if Android M or higher
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        // Show alert dialog to the user saying a separate permission is needed
        // Launch the settings activity if the user prefers
        Intent myIntent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
        startActivity(myIntent);
    }

动作 ACTION_MANAGE_OVERLAY_PERMISSION 直接启动“绘制其他应用程序”权限屏幕。
编辑:
我的上面的代码完全正确
但是我发现很多人仍在搜索如何永久允许ACTION_MANAGE_OVERLAY_PERMISSION,比如如果用户一旦允许了权限,就不会每次打开应用程序时都询问他。所以这里有一个解决方案:
  1. 检查设备是否具有API 23+

  2. 如果是23+ API,则检查用户是否拥有许可证

  3. 如果已经允许,请不要将其驱动到Settings.ACTION_MANAGE_OVERLAY_PERMISSION,如果还没有允许,请进行运行时权限检查

将下面一行放入您的onCreate()方法中。 将此放置在setContentView之后:
checkPermission();

现在将以下代码放入onActivityResult中:
@TargetApi(Build.VERSION_CODES.M)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
        if (!Settings.canDrawOverlays(this)) {
            // You don't have permission
            checkPermission();
        } else {
            // Do as per your logic 
        }

    }

}

现在最后是checkPermission方法的代码:
public void checkPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!Settings.canDrawOverlays(this)) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
        }
    }
}

也不要忘记在你的类中声明这个公共变量:

public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE = 5469;

1
@JaymanJani 你好,这对我来说是有效的,但我想要一个开关按钮的开/关事件。 - PriyankaChauhan
权限已授权,接下来我该做什么?我想打开这个应用程序。 - Santanu Sur
好的解决方案。但是在onActivityResult方法中不需要再次检查canDrawOverlays权限,因为我们已经在checkPermission()方法中检查过了。 - VahidShir
它运行得非常好,但现在我无法点击工具栏菜单项。这可行吗? - Pablo R.
嘿,如果有人遇到问题,请告诉我,谢谢。 - Jayman Jani
有人能把这个做成 Cordova 插件吗? - Raz Buchnik

18

现在(2019),谷歌通过 Android Q 中的 Bubbles 提供了一种替代 SYSTEM_ALERT_WINDOW 的 API,因此谷歌决定在未来的 Android 版本中逐步停用 SYSTEM_ALERT_WINDOW

而 Android Go 设备将不再授予此权限,即 Settings.canDrawOverlays() == false


你怎么知道的?文档上说这还在预览阶段。https://developer.android.com/guide/topics/ui/bubbles - Noa Drach
1
没错,@NoaDrach,这就是为什么我说在将来Google最终会弃用SAW - 也就是当Bubble API稳定之后。 https://youtu.be/td3Kd7fOROw?t=136 - Dickson the developer
谢谢,我之所以问是因为我的应用程序(尚未针对Q进行定位)在从Play商店安装时自动接收此权限,现在我们不再自动获取它。我猜这是因为这个 - https://www.reddit.com/r/androiddev/comments/a69q0i/question_did_the_play_store_stop_auto_granting/ - Noa Drach
@Dicksonthedeveloper,请告诉我如何识别哪些设备没有 SYSTEM_ALERT_WINDOW 或屏幕叠加权限的功能,我需要解决方案 https://stackoverflow.com/questions/63938787/how-to-check-detect-or-identify-the-settings-component-screen-overlay-or-any-fe - Shaikh Mohib
Android 11 包含此 API。 - NothingtoSay
@Dicksonthedeveloper 你有什么内容来支持你的说法“谷歌最终会废弃SAW”吗?我正在开发一款打车应用程序,我想知道是否应该选择这条路线还是使用fullScreenIntent。 谢谢 - Mohsin Falak

17

对于那些希望在应用程序从Play商店下载时自动获取此权限的人,除了Manifest中的SYSTEM_ALERT_WINDOW外,您还应该前往此链接并向Google申请。

您需要提供一些额外的信息以解释为什么需要此权限,Google将审核并授予您自动授权。

请注意,在申请之前,您必须:

  • 在Manifest中拥有SYSTEM_ALERT_WINDOW权限

  • 在应用程序中未被授权时提示用户授予SYSTEM_ALERT_WINDOW权限。

如果我漏掉了什么,请随时更新答案。


现在这应该是正确答案了。谢谢。请简单说明一下我们如何通过编程方式请求用户的权限。 - Eren Tüfekçi
2
这个程序相关的内容翻译成中文如下:「在2021年还有效吗?你的应用使用了无障碍服务,你需要提供一份说明文档,记录应用程序如何使用所请求的系统功能。」这是你所谈论的情况吗?我们是否应该在发布应用到Play商店后发送请求电子邮件? - Samer Alkhatib

3
如果应用的目标API为22或更低版本,则即使设备运行Android 6.0,当用户点击安装(显示警报)时,Play商店也会授予SYSTEM_ALERT_WINDOW权限和其他权限。 否则,如果应用的目标API为23或更高版本,则需要在运行时请求授权。

根据更新的Play Store政策(自2018年8月起),您不应针对SDK低于26的版本进行开发。请参阅以下参考链接:1)https://developer.android.com/distribute/best-practices/develop/target-sdk2)https://medium.com/codespace69/google-play-warning-app-must-target-at-least-api-level-26-to-ensure-it-is-built-on-the-latest-7a8729d70679 - Jayman Jani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接