Reputation: 472
I'm trying to create a system overlay. But I keep getting "permission denied". I'm using SDK version 23.
My manifest file:
<?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>
The code I use to create the overlay:
//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);
Upvotes: 20
Views: 33685
Reputation: 2301
For Display over the other apps permissions is required to add in the manifest is
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
To check your app has permission
Settings.canDrawOverlays(context)
To check permission 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
)
}
}
And in onActivityResult you can check permission is granted or not
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
}
}
}
Upvotes: 0
Reputation: 6936
I handled all of the overlay permissions for every android version in my library. Please see the gist here.
Upvotes: 0
Reputation: 109
for users below and above android 8 use
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}
Upvotes: 0
Reputation: 664
As an alternative solution, you can try WindowManager.LayoutParams.TYPE_TOAST instead of WindowManager.LayoutParams.TYPE_SYSTEM_ALERT. This not requires any permission. I'm using it to show image, maybe button will work to
Upvotes: 0
Reputation: 2518
You can also lead the user over to the specific app's overlaying page. The documentation 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".
So something like:
intent.setData(Uri.fromParts("package", getPackageName(), null));
Upvotes: 0
Reputation: 2290
In AndroidManifest (for version < 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);
}
}
Result :
@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
}
}
}
Upvotes: 27
Reputation: 1006944
First, there is no permission named SYSTEM_OVERLAY_WINDOW
. It is SYSTEM_ALERT_WINDOW
.
Second, if your targetSdkVersion
is 23 or higher, and you are running on Android 6.0+ devices, your app will not get this permission at the outset. Call Settings.canDrawOverlays()
to see if you have the permission, and use ACTION_MANAGE_OVERLAY_PERMISSION
to lead the user over to Settings if you do not.
Upvotes: 35