web-dev-qa-db-fra.com

La superposition d'écran a détecté des blocs Android autorisations

J'ai remarqué un problème étrange avec mon application Android sur mon nouveau téléphone. Les fenêtres contextuelles d'autorisation du SDK 23 telles que le stockage externe sont bloquées par l'alerte jointe ci-dessous. Je pensais au départ que cela était lié à mon téléphone, mais cela ne semble pas affecter les autres applications installées.

Ce problème est-il peut-être lié à l'installation d'une version de débogage ou est-ce un problème avec la gestion de mes autorisations? Je pensais que cela pouvait en quelque sorte être lié à l'une des plateformes publicitaires que j'utilise, mais j'ai essayé de les désactiver et cela a quand même été visible.

enter image description here

J'ai collé la fonction de sauvegarde d'image qui génère cette demande d'autorisation ci-dessous. J'utilise Dexter pour économiser sur l'écriture de tout un tas de passe-partout hideux

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

[~ # ~] mise à jour [~ # ~] : Étant donné que de nombreuses personnes le mentionnent, comme indiqué précédemment, ce problème n'est pas dû au superposition app installée. Dans le menu Dessiner par-dessus d'autres applications, j'ai les applications suivantes: Musique Google Play, services Google Play, Photos, TalkBack, Twitch, Twitter. Tous sont réglés sur No .

De plus, j'ai testé d'autres applications telles que Google Hangouts et Twitter qui comportent également des actions nécessitant des autorisations dangereuses. Je suis en mesure de fournir ces autorisations sans ce problème.


[~ # ~] solution [~ # ~] : J'ai marqué la réponse de R. Zagorski comme cela inclut beaucoup de cas généraux. Pour moi, c’était en fait un Toast qui interrompait mon flux d’autorisations. Ce popup a perdu tellement de temps en m'envoyant sur le mauvais chemin ...

Ceci est le Toast que j'avais visible pendant les premières secondes qui ont suivi l'affichage de la fenêtre d'autorisation:

enter image description here

42
alexgophermix

Cette fenêtre contextuelle est générée par l’autorisation manifest.PERMISSION.SYSTEM_ALERT_WINDOW déclarée par le manifeste. Il y a 3 catégories d'autorisations, que le développeur doit connaître:

  1. Autorisation normale - ne faites rien avec eux, déclarez simplement dans le manifeste
  2. Autorisations vulnérables - Déclarez dans Manifest et demandez une autorisation dès la première fois. Ils peuvent être modifiés via les paramètres du système
  3. Autorisations dangereuses précédentes: SYSTEM_ALERT_WINDOW et WRITE_SETTINGS appartiennent à cette catégorie. Ils doivent être accordés mais ne sont pas visibles dans les paramètres système. Pour le demander, vous n'utilisez pas de méthode standard (int checkSelfPermission (String permission)) mais vous devez vérifier Settings.canDrawOverlays() ou Settings.System.canWrite() de manière appropriée.

Si vous n'avez pas l'autorisation SYSTEM_ALERT_WINDOW :

  1. vérifie si vous avez un Toast visible lors de l'interaction avec la fenêtre contextuelle des autorisations. Toast compte également comme une superposition
  2. vérifie si l'une de vos dépendances l'exige .

Si vous n'êtes pas sûr d'utiliser cette autorisation, vous pouvez effectuer plusieurs cas de test:

  1. Demander cette permission par vous-même:

    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. Vérifiez si this ou this n'est pas votre cas

  3. Vérifiez cet article pour être conscient que, lors de l'installation de l'application via Play Store, cette autorisation est automatiquement accordée (je n'ai pas vérifié si, je ne peux donc pas confirmer)

Le modèle de permission peut être compris, il suffit parfois de creuser davantage.

51
R. Zagórski

Ce n'est pas un problème, vous avez juste une application de superposition installée, les plus courantes sont

  • Facebook Messenger
  • Whatsapp avec Pop-up activé
  • Têtes de chat Seebye
  • Viber
  • Toute application affichant un menu ou quelque chose à l'écran est une application superposée.

fermez-le, puis essayez.

9
Ahmed I. Elsayed

Cela est généralement dû à l'utilisation d'une application flottante.

Pour les utilisateurs de Samsung Android Phone:

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

Si vous trouvez une application avec une bulle, affichez la superposition d'écran. Si une application ajuste la luminosité de votre téléphone, désactivez également l'option de superposition d'écran sur ces applications. Le point est, vous devez comprendre l'application coupable et désactiver la superposition d'écran.

Source: Erreur de superposition d'écran détectée sur Android

2
Certified

Lorsqu'une superposition d'écran est détectée, le système ne vous permettra plus de continuer à accorder des autorisations pour les applications. Parce que la superposition d'écran peut recevoir l'entrée de l'utilisateur. Vous devez donc désactiver toutes les opérations de "superposition d’écran" avant d’accorder des autorisations pour vos applications. Ce n'est pas le problème de votre application. Toutes les applications ayant le SDK cible 23 rencontrent ce problème.

2
TOP

Ce popup est devenu un problème avec l’inclusion du gestionnaire d’autorisations dans Android Marshmallow. Si des applications installées sur votre téléphone ont la permission de se superposer à l’écran, il existe un certain nombre de paramètres d’autorisation, Accès au fichier inclus, que vous ne pouvez pas modifier sans désactiver au préalable ces autorisations de superposition d'écran. Pour moi, mon application texte et l'application de messagerie Facebook sont les coupables. Chaque fois que je souhaite donner à une autre application les autorisations demandées, je dois cliquer sur le Ouvrez l’option Paramètres de cette fenêtre contextuelle et révoquez l’accès en superposition d’écran pour les deux applications susmentionnées, puis rouvrez-la pour obtenir à nouveau l’invitation d’autorisation. Ensuite, je dois réactiver les autorisations de superposition si je souhaite que mes messages Je pense que votre application va bien, la gestion des autorisations d’Android n’est qu’un gâchis déroutant.

2
jakeinator21

J'ai résolu ce problème en installant Alert Window Checker: https://play.google.com/store/apps/details?id=jp.sfapps.alertwindowchecker . Il vous indique quelles applications utilisent actuellement la fonction de superposition d'écran.

Dans mon cas, j'ai dû désactiver le détecteur de balayage dans l'application ES FileExplorer pour résoudre ce problème.

0
bma350

J'ai cherché beaucoup de solutions sur Google, mais rien n'a fonctionné. Puis j'ai essayé avec toutes les options dans les réglages :)

Enfin, je peux vous donner un moyen précis de désactiver la superposition -

Sélectionnez Paramètre> Application> Application par défaut> Assistance au périphérique> Option "Désactiver la lecture de texte à l'écran".

0
Pankaj