Android 系统覆盖 window
Android System overlay window
我正在尝试创建系统覆盖。但我不断收到 "permission denied"。我使用的是 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>
我用来创建叠加层的代码:
//mView = new HUDView(this);
mButton = new Button(this);
mButton.setText("Overlay button");
mButton.setOnTouchListener(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.RIGHT | Gravity.TOP;
params.setTitle("Load Average");
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mButton, params);
首先,没有名为SYSTEM_OVERLAY_WINDOW
的权限。是SYSTEM_ALERT_WINDOW
.
其次,如果你的 targetSdkVersion
是 23 或更高,而你是 运行 在 Android 6.0+ 设备上,你的应用一开始不会获得此权限。调用 Settings.canDrawOverlays()
查看您是否有权限,如果没有,请使用 ACTION_MANAGE_OVERLAY_PERMISSION
将用户引导至设置。
在 AndroidManifest 中(版本 < 23)
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE= 5469;
//Random value
public void testPermission() {
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);
}
}
结果:
@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
}
}
}
您还可以将用户引导至特定应用的叠加页面。文档 states:
Input: Optionally, the Intent's data URI can specify the application package name to directly invoke the management GUI specific to the package name. For example "package:com.my.app".
所以像这样:
intent.setData(Uri.fromParts("package", getPackageName(), null));
作为替代解决方案,您可以尝试 WindowManager.LayoutParams.TYPE_TOAST 而不是 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT。
这不需要任何许可。
我用它来显示图像,也许按钮可以工作
以下用户和android8以上用户使用
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}
我在这里处理了我 library. Please see the gist 中每个 android 版本的所有覆盖权限。
要在其他应用程序上显示需要在清单中添加的权限是
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
检查您的应用是否有权限
Settings.canDrawOverlays(context)
检查权限checkOverlayPermission
private const val CODE_DRAW_OVER_OTHER_APP_PERMISSION = 2084
private fun checkOverlayPermission(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
//If the draw over permission is not available open the settings screen
//to grant the permission.
val intent = Intent(
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:$packageName")
)
startActivityForResult(
intent,
CODE_DRAW_OVER_OTHER_APP_PERMISSION
)
}
}
并且在 onActivityResult 中你可以检查权限是否被授予
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?
) {
if (requestCode == CODE_DRAW_OVER_OTHER_APP_PERMISSION) {
if (Settings.canDrawOverlays(this)) {
// Permission Granted
} else {
// Permission not Granted
// If you want then call again checkOverlayPermission until permission granted
}
}
}
我正在尝试创建系统覆盖。但我不断收到 "permission denied"。我使用的是 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>
我用来创建叠加层的代码:
//mView = new HUDView(this);
mButton = new Button(this);
mButton.setText("Overlay button");
mButton.setOnTouchListener(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.RIGHT | Gravity.TOP;
params.setTitle("Load Average");
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mButton, params);
首先,没有名为SYSTEM_OVERLAY_WINDOW
的权限。是SYSTEM_ALERT_WINDOW
.
其次,如果你的 targetSdkVersion
是 23 或更高,而你是 运行 在 Android 6.0+ 设备上,你的应用一开始不会获得此权限。调用 Settings.canDrawOverlays()
查看您是否有权限,如果没有,请使用 ACTION_MANAGE_OVERLAY_PERMISSION
将用户引导至设置。
在 AndroidManifest 中(版本 < 23)
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
public static int ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE= 5469;
//Random value
public void testPermission() {
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);
}
}
结果:
@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
}
}
}
您还可以将用户引导至特定应用的叠加页面。文档 states:
Input: Optionally, the Intent's data URI can specify the application package name to directly invoke the management GUI specific to the package name. For example "package:com.my.app".
所以像这样:
intent.setData(Uri.fromParts("package", getPackageName(), null));
作为替代解决方案,您可以尝试 WindowManager.LayoutParams.TYPE_TOAST 而不是 WindowManager.LayoutParams.TYPE_SYSTEM_ALERT。 这不需要任何许可。 我用它来显示图像,也许按钮可以工作
以下用户和android8以上用户使用
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}
我在这里处理了我 library. Please see the gist 中每个 android 版本的所有覆盖权限。
要在其他应用程序上显示需要在清单中添加的权限是
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
检查您的应用是否有权限
Settings.canDrawOverlays(context)
检查权限checkOverlayPermission
private const val CODE_DRAW_OVER_OTHER_APP_PERMISSION = 2084
private fun checkOverlayPermission(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(this)) {
//If the draw over permission is not available open the settings screen
//to grant the permission.
val intent = Intent(
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:$packageName")
)
startActivityForResult(
intent,
CODE_DRAW_OVER_OTHER_APP_PERMISSION
)
}
}
并且在 onActivityResult 中你可以检查权限是否被授予
override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?
) {
if (requestCode == CODE_DRAW_OVER_OTHER_APP_PERMISSION) {
if (Settings.canDrawOverlays(this)) {
// Permission Granted
} else {
// Permission not Granted
// If you want then call again checkOverlayPermission until permission granted
}
}
}