gpt4 book ai didi

android - 为什么 Android 8 中的 Settings.canDrawOverlays() 方法在用户授​​予绘制叠加层的权限并返回应用程序时返回 "false"?

转载 作者:IT老高 更新时间:2023-10-28 23:04:25 27 4
gpt4 key购买 nike

我正在为 parent 开发 MDM 应用程序来控制 child 的设备,如果执行了禁止的操作,它使用权限 SYSTEM_ALERT_WINDOW 在设备上显示警告。在具有 SDK 23+ (Android 6.0) 的设备上,应用程序在安装过程中使用此方法检查权限:

Settings.canDrawOverlays(getApplicationContext()) 

如果此方法返回 false,应用会打开系统对话框,用户可以在其中授予权限:

Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE);

但在 SDK 26 (Android 8.0) 的设备上,当用户成功授予权限并按返回按钮返回应用时,方法 canDrawOverlays() 仍然返回 false,直到用户没有关闭应用程序并再次启动它,或者只是在最近的应用程序对话框中选择它。我在 Android Studio 中使用 Android 8 在最新版本的虚拟设备上对其进行了测试,因为我没有真实设备。

我做了一些研究,另外检查了 AppOpsManager 的权限:

AppOpsManager appOpsMgr = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
int mode = appOpsMgr.checkOpNoThrow("android:system_alert_window", android.os.Process.myUid(), getPackageName());
Log.d(TAG, "android:system_alert_window: mode=" + mode);

所以:

  • 当应用没有此权限时,模式为“2”(MODE_ERRORED) (canDrawOverlays() 返回 false) 当用户
  • 授予权限并返回应用程序,模式为“1”(MODE_IGNORED) (canDrawOverlays() 返回 false)
  • 如果你现在重启应用,模式为“0”(MODE_ALLOWED)(canDrawOverlays()返回true)

请问,谁能向我解释这种行为?我可以依赖操作 "android:system_alert_window"mode == 1 并假设用户已授予权限吗?

最佳答案

我遇到了同样的问题。我使用一种尝试添加不可见覆盖的解决方法。如果抛出异常,则不会授予权限。它可能不是最好的解决方案,但它确实有效。我无法告诉您有关 AppOps 解决方案的任何信息,但它看起来很可靠。

2020 年 10 月编辑:如评论中所述,当抛出 SecurityException 时,WindowManager 内部可能存在内存泄漏,从而导致解决方法 View 不被删除(即使显式调用 removeView)。对于正常使用,这应该不是什么大问题,但要避免在同一个应用 session 中运行太多检查(如果不对其进行测试,我会假设任何低于 100 的东西都可以)。

/**
* Workaround for Android O
*/
public static boolean canDrawOverlays(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return true;
else if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
return Settings.canDrawOverlays(context);
} else {
if (Settings.canDrawOverlays(context)) return true;
try {
WindowManager mgr = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
if (mgr == null) return false; //getSystemService might return null
View viewToAdd = new View(context);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(0, 0, android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O ?
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
viewToAdd.setLayoutParams(params);
mgr.addView(viewToAdd, params);
mgr.removeView(viewToAdd);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}

关于android - 为什么 Android 8 中的 Settings.canDrawOverlays() 方法在用户授​​予绘制叠加层的权限并返回应用程序时返回 "false"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46173460/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com