屏幕叠加检测到阻止Android权限

时间:2016-08-26 21:27:26

标签: android permissions oneplusthree

我注意到我的新手机上的Android应用程序出现了一个奇怪的问题。 SDK 23权限弹出窗口(如外部存储)将被下面附加的警报阻止。我最初认为这与我的手机有关,但它似乎并没有影响我的其他任何已安装的应用程序。

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

enter image description here

我已粘贴了以下生成此权限请求的图像保存功能。我正在使用Dexter来节省编写一大堆可怕的样板

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

更新:由于很多人提到它,如前所述,此问题并非由于安装了叠加应用。在 Draw over other apps 菜单下,我有以下应用程序:Google Play音乐,Google Play服务,照片,TalkBack,Twitch,Twitter。 所有这些都设置为否

此外,我还测试了其他应用程序,例如Google Hangouts和Twitter,这些应用程序也有需要危险权限的操作,我可以在没有此问题的情况下提供这些权限。

: 我已经将R. Zagorski的答案标记为解决方案,因为它包含了很多一般情况。对我而言,实际上是一个Toast正在破坏我的权限流。这个弹出窗口浪费了很多时间,让我走上了完全错误的道路......

这是我在权限弹出窗口出现后的前几秒看到的Toast

enter image description here

8 个答案:

答案 0 :(得分:48)

此弹出窗口是由清单声明的manifest.PERMISSION.SYSTEM_ALERT_WINDOW权限引起的。 这三种权限是开发人员必须注意的。:

  1. 正常权限 - 不对它们执行任何操作,只需在Manifest中声明
  2. Vulnerable permissions - 在Manifest中声明,并在第一时间获得许可。可以通过系统设置更改它们
  3. 以上危险权限:SYSTEM_ALERT_WINDOWWRITE_SETTINGS属于此类别。必须授予它们,但在系统设置中不可见。要求使用,请不要使用标准方式(int checkSelfPermission (String permission)),但必须正确检查Settings.canDrawOverlays()Settings.System.canWrite()
  4. 如果您没有SYSTEM_ALERT_WINDOW权限:

    1. 检查在与权限弹出窗口进行交互时是否显示Toast虽然“覆盖检测到”弹出式窗口未提及,但Toast也会计为叠加层
    2. 检查您的任何依赖项是否需要
    3. 如果您不确定是否使用此权限,则可以执行以下几个测试用例:

      1. 自行申请此权限:

        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. 检查thisthis是否属于您的情况

      3. 请注意this post注意,当通过Play商店安装应用时,会自动授予此权限(我没有检查过,因此无法确认)

      4. 可以理解权限模型,有时需要更多挖掘。

答案 1 :(得分:9)

这不是问题,你只安装了一个叠加应用,最常见的是

  • Facebook Messenger
  • 启用了弹出窗口的Whatsapp
  • Seebye Chat heads
  • Viber的
  • 任何在屏幕上显示菜单或其他内容的应用都是叠加应用。

关闭它,然后尝试。

答案 2 :(得分:2)

此弹出窗口成为Android Marshmallow中包含权限管理器的问题。如果您的手机上安装了任何有权在屏幕上叠加的应用,则会有许多权限设置,包括文件访问权限,您无法在不先禁用这些屏幕覆盖权限的情况下进行更改。对我来说,我的文本应用程序和Facebook Messenger应用程序是罪魁祸首。每次我想给任何其他应用程序所请求的权限时,我必须单击该弹出窗口上的“打开设置”选项并撤消上述两个应用程序的屏幕叠加访问权限,然后重新打开相关应用程序以再次获得权限提示。然后,如果我想要我的消息弹出窗口或聊天头,我必须再次重新启用覆盖权限。这真的很烦人。我认为你的应用程序很好,android的权限管理只是一个令人困惑的混乱。

答案 3 :(得分:2)

检测到屏幕覆盖时,系统不允许您继续授予应用权限。因为屏幕叠加可以接收用户的输入。 所以你必须禁用所有&#34;屏幕覆盖&#34;授予您的应用权限之前的事情。 这不是您的应用程序的问题。所有具有目标SDK 23的应用都会遇到此问题。

答案 4 :(得分:2)

通常,这是由使用浮动应用程序引起的。

对于三星Android手机用户:

Open the Settings
Then Applications > Application manager
Press on More > Apps that can appear on top

如果您发现带有气泡的应用,请显示屏幕叠加层。如果应用调整了手机的亮度,请在这些应用上禁用屏幕覆盖选项。重点是,你必须找出罪魁祸首应用程序并禁用屏幕叠加。

来源:Fix Screen Overlay Detected Error On Android

答案 5 :(得分:0)

我用Google搜索了这么多解决方案,但没有任何效果。然后我尝试了设置中的所有选项:)

最后,我可以给你明确的方法来禁用叠加 -

转到设置&gt;申请&gt;默认应用&gt;设备辅助&gt; “在屏幕上翻阅文本”选项

答案 6 :(得分:0)

我已通过安装警告窗口检查器修复此问题:https://play.google.com/store/apps/details?id=jp.sfapps.alertwindowchecker。它指示您当前正在使用屏幕叠加功能的应用程序。

就我而言,我必须在应用程序ES FileExplorer中禁用滑动检测器来解决此问题

答案 7 :(得分:0)

重启手机对我有用。