Java Android系统覆盖窗口

Java Android系统覆盖窗口,java,android,android-permissions,Java,Android,Android Permissions,我正在尝试创建一个系统覆盖。但我总是被“拒绝许可”。我使用的是SDK版本23 我的清单文件: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test" > <uses-permission android:name="android.permission.SYSTEM_O

我正在尝试创建一个系统覆盖。但我总是被“拒绝许可”。我使用的是SDK版本23

我的清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test" >

<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".activity.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

首先,没有名为
SYSTEM\u OVERLAY\u WINDOW
的权限。它是系统警报窗口

其次,如果您的
targetSdkVersion
为23或更高,并且您运行的是Android 6.0+设备,那么您的应用程序在一开始就不会获得此权限。调用
Settings.canDrawOverlays()
查看您是否有权限,如果您没有权限,则使用
操作\u管理\u覆盖\u权限
引导用户进行设置。

在AndroidManifest中(对于<23版)


您还可以引导用户进入特定应用的覆盖页面。文件:

输入:可选地,Intent的数据URI可以指定应用程序包名,以直接调用特定于包名的管理GUI。例如“package:com.my.app”

比如:

intent.setData(Uri.fromParts("package", getPackageName(), null));

作为替代解决方案,您可以尝试WindowManager.LayoutParams.TYPE_TOAST而不是WindowManager.LayoutParams.TYPE_SYSTEM_ALERT。 这不需要任何许可。
我用它来显示图像,也许这个按钮会对安卓8上下的用户起作用

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
   LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
    LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}

我处理了我数据库中每个android版本的所有覆盖权限。请看这里的图片。

我将权限更改为“系统警报”窗口,但这并没有解决问题。所以我正试图实施你的第二个建议。但是我如何使用“操作”\u“管理”\u“覆盖”\u权限引导用户进入设置?@VeryEvilBetty:这是一个
意图
操作
startActivity(新意图(设置。操作\u管理\u覆盖\u权限))
应启动一个活动,用户可以选择允许您的应用在屏幕上绘制。是否至少有一种方法可以仅为我的应用启用覆盖,而不要求用户在所有其他应用中搜索我的应用?理想情况下,一个小的弹出窗口,就像权限一样,是最好的选择。有办法吗?@Meymann:我不知道,对不起。即使有,如果他们觉得这是不合理的。@Meymann只需添加settingsinent.setData(Uri.parse(“package:+getPackageName());为了达到这个目的,这将在官方网站的设置列表中打开你的应用程序的详细页面。它说我们可以对API v23执行相同的操作,你在23上尝试过这个代码吗?是的,你可以。只是清单中的权限是针对版本i检查的运行时权限列表,系统警报窗口不在列表中。我想唯一的解决方案是指导用户如何授予权限@Anthone我已经尝试了你的代码和
设置。canDrawOverlays(this)
onActivityResult
方法中返回
false
。稍后调用时,返回
true
。看起来更改是异步完成的。当用户更改此设置时,是否有方法获得通知?注意:在Android 8.0和8.1上的某些设备上
设置。当用户刚刚启用权限并返回到您的应用程序时,canDrawOverlays(此)
可能始终返回
false
。此方法可能需要5-7秒才能返回实际值
true
。检查这个关于如何绕过这个已知错误的答案:可能重复的
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
        if (Settings.canDrawOverlays(this)) {
            // You have permission
        }
    }
}
intent.setData(Uri.fromParts("package", getPackageName(), null));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
   LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
    LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}