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.
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:
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:
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 :
Toast
visible lors de l'interaction avec la fenêtre contextuelle des autorisations. Toast
compte également comme une superpositionSi vous n'êtes pas sûr d'utiliser cette autorisation, vous pouvez effectuer plusieurs cas de test:
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));
}
}
}
}
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.
Ce n'est pas un problème, vous avez juste une application de superposition installée, les plus courantes sont
fermez-le, puis essayez.
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
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.
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.
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.
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".