检测到的屏幕重叠会阻止Android权限 [英] Screen overlay detected blocks Android permissions

查看:109
本文介绍了检测到的屏幕重叠会阻止Android权限的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到新手机上的Android应用存在一个奇怪的问题. SDK 23权限弹出式窗口(如外部存储设备)被以下附加的警报阻止.我最初以为这与我的手机有关,但似乎并没有影响我安装的其他任何应用.

I've noticed a strange issue with my Android app on my new phone. SDK 23 permission popups like external storage are blocked by the attached alert below. I initially thought this was related to my phone, but it doesn't seem to affect any of my other installed apps.

此问题可能与安装调试版本有关,还是我的权限处理有问题?我以为它可能与我使用的一个广告平台有关,但我尝试禁用它们,但它仍然显示

Is this issue perhaps related to having a debug version installed, or is it something wrong with my permission handling? I thought it could somehow be related to one of the ad platforms I'm using but I tried disabling them and it still showed up

我在下面粘贴了生成此许可请求的图像保存功能.我正在使用 Dexter 来节省编写一大堆丑陋的样板

I've pasted the image saving function that is generate this permission request below. I'm using Dexter to save on writing a whole bunch of hideous boilerplate

public static void saveToExternalStorageIfAllowed(final Context context, final Bitmap bitmapImage, final String title) {
    final Tracker t = ((LoLHistory) context.getApplicationContext()).getTracker(LoLHistory.TrackerName.APP_TRACKER);

    // saving to publicly visible/accessible folder. Requires write permission
    int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
        // do not have permissions to write, request
        t.send(new HitBuilders.EventBuilder()
                .setCategory("FILE")
                .setAction("PermissionMissing")
                .setLabel("WRITE_EXTERNAL")
                .build());
        Dexter.checkPermission(new PermissionListener() {
            @Override
            public void onPermissionGranted(PermissionGrantedResponse response) {
                t.send(new HitBuilders.EventBuilder()
                        .setCategory("FILE")
                        .setAction("PermissionGranted")
                        .setLabel("WRITE_EXTERNAL")
                        .build());

                saveToExternalStorage(context, bitmapImage, title);
            }

            @Override
            public void onPermissionDenied(PermissionDeniedResponse response) {
                t.send(new HitBuilders.EventBuilder()
                        .setCategory("FILE")
                        .setAction("PermissionDenied")
                        .setLabel("WRITE_EXTERNAL")
                        .build());
            }

            @Override
            public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {/* ... */}
        }, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    } else {
        saveToExternalStorage(context, bitmapImage, title);
    }
}

private static void saveToExternalStorage(Context context, Bitmap bitmapImage, String title) {
    Tracker t = ((LoLHistory) context.getApplicationContext()).getTracker(LoLHistory.TrackerName.APP_TRACKER);

    // create image folder if does not exist
    File imagesFolder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), context.getString(R.string.app_name));
    if (!imagesFolder.mkdirs() && !imagesFolder.isDirectory()) {
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            // failed to create and is not a directory. Something went wrong...
            t.send(new HitBuilders.EventBuilder()
                    .setCategory("FILE")
                    .setAction("CreateDirFailed")
                    .setLabel(imagesFolder.getPath())
                    .build());
        } else {
            t.send(new HitBuilders.EventBuilder()
                    .setCategory("FILE")
                    .setAction("CreateDirFailedMediaNotMounted")
                    .setLabel(imagesFolder.getPath())
                    .build());
        }
    }

    // delete image if already exists so FOS can create a new one
    File image = new File(imagesFolder, title + ".jpg");
    if (image.exists()) {
        // image already exists, deleting to start from clean state
        if (!image.delete()) {
            // failed to delete
            t.send(new HitBuilders.EventBuilder()
                    .setCategory("FILE")
                    .setAction("DeleteFailed")
                    .setLabel(image.getPath())
                    .build());
        }
    }

    // compress bitmap and write to file stream. FOS creates file if does not exist
    FileOutputStream out = null;
    try {
        out = new FileOutputStream(image);
        bitmapImage.compress(Bitmap.CompressFormat.JPEG, 50, out);
        out.flush();
    } catch (Exception e) {
        e.printStackTrace();
        t.send(new HitBuilders.ExceptionBuilder()
                .setDescription(e.getLocalizedMessage())
                .setFatal(true)
                .build());
    } finally {
        try {
            if (out != null) {
                out.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
            t.send(new HitBuilders.ExceptionBuilder()
                    .setDescription(e.getLocalizedMessage())
                    .setFatal(true)
                    .build());
        }
    }

    // get Uri from saved image
    Uri uriSavedImage = Uri.fromFile(image);

    // media scan the new file so it shows up in the gallery
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    mediaScanIntent.setData(uriSavedImage);
    context.sendBroadcast(mediaScanIntent);
}


更新:由于有很多人提到它,因此如前所述,此问题不是由于安装了覆盖应用程序引起的.在覆盖其他应用程序菜单下,我具有以下应用程序:Google Play音乐,Google Play服务,照片,TalkBack,Twitch,Twitter. 所有这些均设置为否".


UPDATE: Since a lot of people are mentioning it, as stated earlier this issue is not due to having an overlay app installed. Under the Draw over other apps menu, I have the following applications: Google Play Music, Google Play services, Photos, TalkBack, Twitch, Twitter. All of these are set to No.

此外,我还测试了其他应用程序(例如Google Hangouts和Twitter),这些应用程序也具有需要危险权限的操作,并且能够提供这些权限而不会出现此问题.

Additionally, I have tested other applications like Google Hangouts and Twitter which also have actions that require Dangerous Permissions and I am able to provide those permissions without this issue.

解决方案: 我已标记R. Zagorski的答案是解决方案,因为它包含许多一般情况.对我而言,实际上是Toast破坏了我的权限流程.通过将我发送到完全错误的路径,此弹出窗口浪费了很多时间...

SOLUTION: I have marked R. Zagorski's answer as the solution as it includes a lot of general cases. For me it was actually a Toast that was breaking my permissions flow. This popup wasted so much time by sending me on the completely wrong path...

这是在权限弹出窗口出现后的头几秒钟内我看到的Toast:

This is the Toast I had visible for the first few seconds after the permission popup showed up:

推荐答案

此弹出窗口是由 manifest.PERMISSION.SYSTEM_ALERT_WINDOW 权限. 开发人员必须了解的3类权限.

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. 普通权限-对它们不执行任何操作,只需在清单中声明即可
  2. 脆弱的权限-在清单中声明并询问第一次获得许可.可以通过系统设置更改它们
  3. 具有危险权限: SYSTEM_ALERT_WINDOW WRITE_SETTINGS 属于此类别.必须授予它们,但它们在系统设置中不可见.要请求它,您无需使用标准方式(int checkSelfPermission (String permission)),但必须适当地检查Settings.canDrawOverlays()Settings.System.canWrite()
  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


如果您没有 SYSTEM_ALERT_WINDOW 权限:


If you don't have SYSTEM_ALERT_WINDOW permission:

  1. 检查与权限弹出窗口进行交互时是否可见Toast.尽管检测到覆盖"弹出窗口没有提及,但Toast也算作覆盖
  2. 检查您的依赖项是否需要.
  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. 自行请求此权限:

  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));
            }
        }
    }
}

  • 检查是否

  • Check if this or this is not your case

    查看这篇文章注意,通过Play商店安装应用时,该权限会自动授予(我没有检查过,因此无法确认)

    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权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆