2

Background

I've noticed that ever since Android O came, the function of Settings.canDrawOverlays had issues telling us if the app was granted with the draw-on-top permission (AKA "Display over other apps"), so I've reported about this:

The problem

Not sure why they were marked as fixed, but now that I've tested on my Pixel 2 with Android 8.1, I've noticed this function still ALWAYS returns false (so I've reported about this here) .

Thing is, I've tried finding an alternative and saw others also having this issue here on StackOverflow:

I don't know if this is an issue with Android 8.1, or just my Pixel 2, but I'm using the latest, stock rom version of it (OPM171019.013) .

What I've tried

I've tried all of the solutions that were suggested on the above links.

All of them return me the result that the permission is not granted, ever.

The only solution I've found that does something is this one, which just tells me that the permission was toggled.

One way to "solve" this, is to assume the permission is granted in case the app was installed via the Play Store, because it's granted by default when installing from there.

But this is not a good solution. Apps can be installed from outside of the Play Store, and the user can always turn off this permission manually.

EDIT: I don't know if that's even a possible "solution", because when I try on the app, I can't really draw on top, even if the permission is granted.

The questions

  1. How can I check for sure if the current app is granted with this permission?

  2. From which Android version does this issue occur? Or maybe it's an issue only for Pixel 2 ?

  3. Seeing that even after granting the permission, the app fails to draw on top, is there a possible solution for it?


EDIT: Speaking with others, I think this is a very specific issue on Pixel 2 with Android 8.1 . The reason is that the issue doesn't seem to appear on other devices with Android 8.1. I hope it gets fixed.

android developer
  • 114,585
  • 152
  • 739
  • 1,270

1 Answers1

2

I had the same issue, there is a problem with the function Settings.canDrawOverlays because that needs an app reboot to return true when you granted the permission, try these. I have a button that calls a Config Activity to enable Overlay

public void setOverlayPermissions(){
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:"+getPackageName()));
    startActivityForResult(intent,app.REQUEST_ID_OVERLAY_PERMISSIONS);
}

After that, in onActivityResult funtion

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == app.REQUEST_ID_OVERLAY_PERMISSIONS){
        new WaitingFor().execute();
    }

}

And then

private class WaitingFor extends AsyncTask{
    private ProgressDialog progressDialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog = new ProgressDialog(MainActivity.this);
        progressDialog.setCancelable(false);
        progressDialog.setMessage("Espera un momento...");
        progressDialog.show();
    }

    @Override
    protected Object doInBackground(Object[] objects) {
        try{
            Thread.sleep(2000);

        }catch (Exception ex){
            Log.e(TAG,ex.getMessage()+"");
        }
        return null;
    }

    @Override
    protected void onPostExecute(Object o) {
        super.onPostExecute(o);
        progressDialog.dismiss();
        if(verifyWindowOverlay()){
            FL.w(TAG,"Acepto Overlay");
            setPaso2();
        }else{
            FL.w(TAG,"NO acepto Overlay [Permission error]");
            Toast.makeText(MainActivity.this,"Falta configuracion, reintenta!", Toast.LENGTH_SHORT).show();
        }
    }
}

My verifyWindowsOverlay function

public boolean verifyWindowOverlay(){
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
        return true;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
        return Settings.canDrawOverlays(this);
    if(appOpsMgr.checkOpNoThrow(AppOpsManager.OPSTR_SYSTEM_ALERT_WINDOW, android.os.Process.myUid(), getPackageName()) == 0  || Settings.canDrawOverlays(this))
        return true;
    return false;
}

Good luck.

  • don't know why `Settings.canDrawOverlays(this)` return true even I did not grant the permission on setting screen on testing Android 10 device. Will `appOpsMgr.checkOpNoThrow` be helping? – Yeung Mar 24 '22 at 11:01