How to Give Screen Overlay Permission On My Activity
Here is a sample code to disable pull notifications by using custom overlay. It works fine on Android versions below and 6+.
Permissions Required in Manifest:
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Disabling the pull notifications
private void disablePullNotificationTouch() {
try {
Log.v("App", "Disable Pull Notification");
private HUDView mView = new HUDView(this);
int statusBarHeight = (int) Math.ceil(25 * getResources().getDisplayMetrics().density);
Log.v("App", "" + statusBarHeight);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
statusBarHeight,
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, //Disables status bar
PixelFormat.TRANSPARENT); //Transparent
params.gravity = Gravity.CENTER | Gravity.TOP;
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mView, params);
} catch (Exception e) {
Log.v("App", "Exception: " + e.getMessage());
}
}
// code to post/handler request for permission
public final static int REQUEST_CODE = -1010101;
@RequiresApi(api = Build.VERSION_CODES.M)
public void checkDrawOverlayPermission() {
Log.v("App", "Package Name: " + getApplicationContext().getPackageName());
// check if we already have permission to draw over other apps
if (!Settings.canDrawOverlays(context)) {
Log.v("App", "Requesting Permission" + Settings.canDrawOverlays(context));
// if not construct intent to request permission
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getApplicationContext().getPackageName()));
/ request permission via start activity for result
startActivityForResult(intent, REQUEST_CODE);
} else {
Log.v("App", "We already have permission for it.");
disablePullNotificationTouch();
}
}
@TargetApi(Build.VERSION_CODES.M)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.v("App", "OnActivity Result.");
//check if received result code
// is equal our requested code for draw permission
if (requestCode == REQUEST_CODE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.canDrawOverlays(this)) {
disablePullNotificationTouch();
}
}
}
}
Your code after modifications
public class MainActivity extends Activity {
public static final int REQUEST_PERMISSION = 123;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.data);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Log.v("App", "Build Version Greater than or equal to M: " + Build.VERSION_CODES.M);
checkDrawOverlayPermission();
} else {
Log.v("App", "OS Version Less than M");
//No need for Permission as less then M OS.
}
if ((CheckPermission(this, Manifest.permission.CAMERA)) &&
(CheckPermission(this, Manifest.permission.READ_PHONE_STATE)) &&
(CheckPermission(this, Manifest.permission.NFC))) {
PermHandling();
} else {
RequestPermission(MainActivity.this, Manifest.permission.CAMERA, REQUEST_PERMISSION);
RequestPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE, REQUEST_PERMISSION);
RequestPermission(MainActivity.this, Manifest.permission.NFC, REQUEST_PERMISSION);
//NewPermHandling();
}
}
private void PermHandling() {
//My app internal parts....
//Here my stuff works...
}
//private void NewPermHandling(){
//}
@Override
public void onRequestPermissionsResult(int permissionRequestCode, String[] permissions, int[] grantResults) {
if (permissionRequestCode != REQUEST_PERMISSION) {
return;
}
if (grantResults.length && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
PermHandling();
} else {
// Ask the user to grant the permission
}
}
public void RequestPermission(Activity thisActivity, String Permission, int Code) {
if (ContextCompat.checkSelfPermission(thisActivity,
Permission) !=
PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Permission)) {} else {
ActivityCompat.requestPermissions(thisActivity,
new String[] {
Permission
},
Code);
}
}
}
public final static int REQUEST_CODE = -1010101;
@RequiresApi(api = Build.VERSION_CODES.M)
public void checkDrawOverlayPermission() {
Log.v("App", "Package Name: " + getApplicationContext().getPackageName());
// Check if we already have permission to draw over other apps
if (!Settings.canDrawOverlays(context)) {
Log.v("App", "Requesting Permission" + Settings.canDrawOverlays(context));
// if not construct intent to request permission
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getApplicationContext().getPackageName()));
// request permission via start activity for result
startActivityForResult(intent, REQUEST_CODE); //It will call onActivityResult Function After you press Yes/No and go Back after giving permission
} else {
Log.v("App", "We already have permission for it.");
// disablePullNotificationTouch();
// Do your stuff, we got permission captain
}
}
@TargetApi(Build.VERSION_CODES.M)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.v("App", "OnActivity Result.");
//check if received result code
// is equal our requested code for draw permission
if (requestCode == REQUEST_CODE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.canDrawOverlays(this)) {
// Permission Granted by Overlay
// Do your Stuff
}
}
}
}
public boolean CheckPermission(Context context, String Permission) {
if (ContextCompat.checkSelfPermission(context,
Permission) == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
}
startActivityForResult will call onActivityResult if you call this from an activity and not from service. Read more about it here
Screen overlay detected blocks Android permissions
This popup is caused by the manifest.PERMISSION.SYSTEM_ALERT_WINDOW permission declared by the manifest.
The are 3 categories of permissions, that developer must be aware of.:
- Normal permission - do nothing with them, just declare in the Manifest
- Vulnerable permissions - declare in Manifest and ask for permission at first time. They can be changed through system settings
- Above dangerous permissions: SYSTEM_ALERT_WINDOW and WRITE_SETTINGS belong to this category. They must be granted, but are not visible in system settings. To request for it you don't use a standard way (
int checkSelfPermission (String permission)
) but you have to checkSettings.canDrawOverlays()
orSettings.System.canWrite()
appropriately
If you don't have SYSTEM_ALERT_WINDOW permission:
- check if you have a
Toast
visible when interacting with the permissions popup. Though the Overlay Detected popup doesn't mention it, aToast
also counts as an overlay - check if any of your dependencies require it.
If you're not sure if you're using this permission, there are a couple of test cases that you can do:
Request this permission by yourself:
public class MainActivity extends AppCompatActivity {
public final static int REQUEST_CODE = 10101;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (checkDrawOverlayPermission()) {
startService(new Intent(this, PowerButtonService.class));
}
}
public boolean checkDrawOverlayPermission() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE);
return false;
} else {
return true;
}
}
@Override
@TargetApi(Build.VERSION_CODES.M)
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
if (Settings.canDrawOverlays(this)) {
startService(new Intent(this, PowerButtonService.class));
}
}
}
}Check if this or this is not your case
Check out this post to be aware, that when installing app through Play Store this permission is automatically granted (I have not checked is, therefore cannot confirm)
The permission model can be understood, just sometimes requires more digging.
Android Studio - showing new activity over other apps results in a blackscreen
After lots of trial and error I figured out that the issues was indeed caused by a missing permission, but one that I could not find on any stack overflow answer related to black screen problems. On top of that, I believe it's an issue that only occurred because I used a Xiaomi device for testing.
There are currently two separate permissions for displaying screens over other apps that you will need to grant:
- Display over other apps, also called Display pop-up window. This is the android.permission.ACTION_MANAGE_OVERLAY_PERMISSION that I wasn't sure was even needed. So to emphasize, I definetly do need this permission.
- Display pop-up windows while running in the background. This is the permission I was missing.
After I allowed them both (which you can do under Settings > Apps > Manage Apps > Your App > Other Permissions) everything worked fine.
To direct the user directly to the settings menu where they can allow these permissions, I used the code from this stack overflow answer. This is also where I got the info that it's a xiaomi-specific "issue".
Related Topics
How to Use Python to Execute Adb Commands
How to Validate Password Field in Android
How to Quit Android Application Programmatically
Android Studio - Textview Not Showing in Design View Layout
How to Change Styling of Textinput Placeholder in React Native
Videoview to Match Parent Height and Keep Aspect Ratio
How to Remove Background Resource of Button
Recyclerview Is Cutting Off the Last Item
Chrome on Android Resizes Font
How to Set Default Font Family For Entire Android App
How to Change the Icon Color Selected on Bottom Navigation Bar in Android Studio
Open External Links in the Browser With Android Webview
Limitations on Opening Pdf File in Android
How to Completely Disable Selinux in Android L in the Init.Rc File
How to Get Data from Edit Text in a Recyclerview