web-dev-qa-db-ja.com

画面オーバーレイ検出ブロックAndroid権限

新しいスマートフォンのAndroidアプリに奇妙な問題があることに気付きました。外部ストレージなどのSDK 23の許可ポップアップは、以下の添付アラートによってブロックされます。最初はこれが私の携帯電話に関連していると思っていましたが、インストールされている他のアプリには影響がないようです。

この問題はおそらくデバッグバージョンのインストールに関連していますか、それとも許可の処理に何か問題がありますか?どういうわけか、使用している広告プラットフォームの1つに関連していると思いましたが、それらを無効にしようとしても表示されました。

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

UPDATE:多くの人が言及しているため、前述のように、この問題はオーバーレイアプリがインストールされているためではありません。 他のアプリの上に描画するメニューには、Google Playミュージック、Google Playサービス、写真、TalkBack、Twitch、Twitterのアプリケーションがあります。 これらはすべてNoに設定されます。

さらに、危険なアクセス許可を必要とするアクションもあるGoogleハングアウトやTwitterなどの他のアプリケーションをテストしましたが、この問題なくこれらのアクセス許可を提供できます。


ソリューション:多くの一般的なケースが含まれているため、ソリューションとして R。Zagorski の答えをマークしました。私にとっては、実際にToastが私の許可フローを破壊していました。このポップアップは、まったく間違ったパスで私を送信することにより、非常に時間を無駄にしました...

これは、許可ポップアップが表示されてから最初の数秒間に表示されていたToastです。

enter image description here

42
alexgophermix

このポップアップは、マニフェストで宣言されている manifest.PERMISSION.SYSTEM_ALERT_WINDOW 許可が原因です。開発者は、次の3つのカテゴリの許可に注意する必要があります。

  1. 通常の許可-マニフェストで宣言するだけで何もしません
  2. 脆弱なアクセス許可 -マニフェストで宣言し、最初にアクセス許可を要求します。システム設定により変更できます
  3. 上記の危険な権限: SYSTEM_ALERT_WINDOW および WRITE_SETTINGS はこのカテゴリに属します。それらは許可される必要がありますが、システム設定には表示されません。それを要求するには、標準の方法(int checkSelfPermission (String permission))を使用しませんが、Settings.canDrawOverlays()またはSettings.System.canWrite()を適切にチェックする必要があります

SYSTEM_ALERT_WINDOW 権限がない場合:

  1. パーミッションポップアップと対話するときにToastが表示されているかどうかを確認してください。オーバーレイ検出ポップアップは言及していませんが、Toastはオーバーレイとしてもカウントされます
  2. 依存関係のいずれかで必要かどうかを確認します

この権限を使用しているかどうかわからない場合は、いくつかのテストケースを実行できます。

  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. this または this が当てはまらないかどうかを確認します

  3. この投稿 をチェックして、Playストアからアプリをインストールすると、この許可が自動的に付与されることに注意してください(チェックしていないため、確認できません)

許可モデルは理解できますが、さらに掘り下げる必要がある場合があります。

51
R. Zagórski

それは問題ではありません、あなたはオーバーレイアプリをインストールしているだけです、最も一般的なのは

  • Facebook Messenger
  • ポップアップが有効なWhatsapp
  • Seebyeチャットヘッド
  • Viber
  • 画面にメニューなどを表示するアプリは、オーバーレイアプリです。

閉じてから、試してください。

9

通常、これはフローティングアプリの使用が原因です。

Samsung Android Phoneユーザーの場合:

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

バブルのあるアプリを見つけたら、画面オーバーレイを表示します。アプリが携帯電話の明るさを調整する場合は、それらのアプリでも画面オーバーレイオプションを無効にします。ポイントは、犯人アプリを把握し、画面オーバーレイを無効にする必要があることです。

ソース: Androidで画面オーバーレイ検出エラーを修正

2
Certified

スクリーンオーバーレイが検出された場合、システムはアプリへのアクセス許可の付与を続行できません。画面オーバーレイはユーザーの入力を受け取ることができるためです。そのため、アプリにアクセス許可を付与する前に、すべての「スクリーンオーバーレイ」を無効にする必要があります。アプリの問題ではありません。ターゲットSDK 23を持つすべてのアプリは、この問題を抱えています。

2
TOP

このポップアップは、Android Marshmallowに権限マネージャーを含めることで問題になりました。画面にオーバーレイする権限を持つアプリが携帯電話にインストールされている場合、ファイルアクセスを含むいくつかの権限設定があり、これらの画面オーバーレイ権限を最初に無効にしないと変更できません。私にとって、私のテキストアプリとFacebookメッセンジャーアプリが原因です。他のアプリに要求されたアクセス許可を付与するたびに、そのポップアップの[設定を開く]オプションをクリックし、前述の2つのアプリのスクリーンオーバーレイアクセスを取り消してから、問題のアプリを再度開いてアクセス許可のプロンプトを再度取得する必要があります。メッセージポップアップまたはチャットヘッドが必要な場合は、オーバーレイのアクセス許可を再度有効にする必要があります。それは本当に迷惑です。あなたのアプリは大丈夫だと思います。Androidのパーミッション管理は混乱を招く混乱です。

2
jakeinator21

Alert Window Checkerをインストールしてこの問題を修正しました: https://play.google.com/store/apps/details?id=jp.sfapps.alertwindowchecker 。現在、スクリーンオーバーレイ機能を使用しているアプリケーションを示します。

私の場合、この問題を修正するには、アプリケーションES FileExplorerでスワイプ検出を無効にする必要がありました

0
bma350

私は非常に多くのソリューションを探しましたが、何も機能しませんでした。次に、設定のすべてのオプションを試しました:)

最後に、オーバーレイを無効にする明確な方法を示します-

[設定]> [アプリケーション]> [デフォルトのアプリケーション]> [デバイスアシスタンス]> [画面上のテキストの読み取りを有効にする]オプションに移動します

0
Pankaj