How to Open Draw Overlay Permission Popup in Miui

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.:

  1. Normal permission - do nothing with them, just declare in the Manifest
  2. Vulnerable permissions - declare in Manifest and ask for permission at first time. They can be changed through system settings
  3. 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 check Settings.canDrawOverlays() or Settings.System.canWrite() appropriately

If you don't have SYSTEM_ALERT_WINDOW permission:

  1. check if you have a Toast visible when interacting with the permissions popup. Though the Overlay Detected popup doesn't mention it, a Toast also counts as an overlay
  2. 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:

  1. 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));
    }
    }
    }
    }
  2. Check if this or this is not your case

  3. 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:

  1. 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.
  2. 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



Leave a reply



Submit