当前位置: 首页 > 知识库问答 >
问题:

检测到屏幕覆盖阻止Android权限

薛博赡
2023-03-14

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

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

我已经粘贴了下面生成此权限请求的图像保存功能。我正在使用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 Music、Google Play services、Photos、TalkBack、Twitch、Twitter。所有这些都设置为否。

此外,我还测试了其他应用程序,如Google Hangouts和Twitter,这些应用程序也有需要危险权限的操作,我能够提供这些权限,而没有这个问题。

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

这是Toast我在权限弹出窗口出现后的前几秒钟可见:

共有3个答案

蒲德曜
2023-03-14

这个弹出窗口成为了一个问题,因为AndroidMarshmallow中包含了权限管理器。如果你的手机上安装了任何有权在屏幕上覆盖的应用程序,有许多权限设置,包括文件访问权限,如果不先禁用这些屏幕覆盖权限,你就不能更改这些设置。对我来说,我的文本应用程序和脸书信使应用程序是罪魁祸首。每次我想给任何其他应用程序请求的权限时,我都必须单击弹出窗口上的打开设置选项,撤销上述两个应用程序的屏幕覆盖访问权限,然后重新打开有问题的应用程序,再次获得权限提示。然后,如果我想要我的消息弹出窗口或聊天头像,我必须再次重新启用覆盖权限。这真的很烦人。我认为你的应用程序很好,android的权限管理只是一团糟。

乐正浩宕
2023-03-14

这不是问题,你只是安装了一个覆盖应用程序,最常见的是

  • Facebook Messenger
  • 启用弹出窗口的Whatsapp
  • 再见聊天头像
  • Viber
  • 任何在屏幕上显示菜单或其他内容的应用程序都是覆盖应用程序。

关上它,然后试试。

丁嘉
2023-03-14

此弹出窗口是由清单引起的。许可。清单声明的SYSTEM\u ALERT\u窗口权限。开发人员必须注意以下三类权限:

  1. 正常权限-对其不做任何操作,只需在清单中声明

如果您没有SYSTEM_ALERT_WINDOW权限:

  1. 检查在与权限弹出菜单交互时是否有可见的Toast。虽然检测到的覆盖弹出窗口没有提到它,但是Toast也算作覆盖

如果您不确定是否正在使用此权限,可以使用以下几个测试用例:

>

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

检查这是否不是你的情况

查看这篇文章要注意,当通过Play Store安装应用程序时,此权限会自动授予(我没有选中is,因此无法确认)

权限模型可以理解,只是有时候需要多挖掘。

 类似资料:
  • 我发现下面的问题屏幕覆盖检测时,在Motog3Marshmallow移动点击权限。 我在到处的互联网搜索中找到了许多解决方案,您可以查看以下内容: > 删除esfile资源管理器 https://www.youtube.com/watch?v=QHidevTDrYI 检测到屏幕覆盖阻止Android权限 https://android.stackexchange.com/questions/148

  • 运行我的android应用程序时出现以下错误: 检测到屏幕覆盖: 要更改此权限设置,您首先必须从设置中关闭屏幕覆盖 我的应用程序没有列在显示的列表中。 如何解决这个错误?

  • 我创建了一个应用程序,它在后台连续运行,并显示浮动覆盖文本视图(通过使用权限android.permission.SYSTEM_ALERT_WINDOW)。 我在联想Android设备中遇到问题,当其他应用程序尝试请求用户权限时,会出现一个警报对话框,显示“检测到屏幕覆盖”。虽然我在Redmi 3S Prime设备上测试了同一应用程序,但权限对话框中的“允许”按钮是不可单击的,直到我关闭了应用程序

  • 在我的应用程序中,我请求获得在Android SDK 23中访问SMS的权限(运行时权限),但问题是出现了对话框屏幕覆盖,并且未授予访问权限。我禁用了所有其他应用程序覆盖,但没有任何更改。我找到了这个链接,但没有帮助 问题是我如何通过编程修复它?

  • 安装应用程序时,如何默认启用屏幕覆盖权限。 现在我面临一些问题,当捕获图像询问运行时权限时,一些设备不允许它打开屏幕覆盖设置对话框的权限。在用户看来,他们不知道为什么对话框显示以及他们做了什么。 当打开覆盖设置屏幕时,一些应用程序会自动启用屏幕覆盖权限。 下面我使用代码。 此代码直接打开覆盖设置屏幕。所有应用程序的显示列表。 我的要求是显示权限特定的应用程序或启用覆盖权限而无需用户交互。 做需要.

  • 我有一个应用程序小部件,当它更新时,获取具有与小部件匹配的维度的图像,并将该图像放入(通过)。它工作得很好。 但是对于支持主屏幕旋转的设备(我不是说基于设备方向的