web-dev-qa-db-fra.com

Android O - FLAG_SHOW_WHEN_LOCKED est obsolète

Je cible mon application sur Android O . Dans mon application, je dispose d’un service d’emploi qui affiche une fenêtre par-dessus toutes les autres applications. allumez-le . Ce comportement a été obtenu dans les versions antérieures d'Android, mais sous Android O, il ne fonctionne pas comme prévu.

J'ai lu que je devais utiliser l'indicateur TYPE_APPLICATION_OVERLAY et ajouté également l'autorisation <uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW"/> dans le fichier manifeste. 

Cela fonctionne donc bien lorsque l'écran est allumé, mais lorsque celui-ci est éteint, j'ai remarqué qu'il ne l'allumait pas. Lorsque j'ai allumé l'écran, j'ai constaté que la fenêtre avait été créée par-dessus d'autres applications.

Ma question est donc puisque les drapeaux FLAG_TURN_SCREEN_ON et FLAG_SHOW_WHEN_LOCKED sont obsolètes dans l’API Android 27, quelles sont les méthodes alternatives pour le faire?

c'est mon code actuel:

private void showView()
{
    if (!wakeLockAcquired)
    {
        wakeLock.acquire();
        wakeLockAquired = true;
    }

    windowManager = (WindowManager)context.getSystemService(WINDOW_SERVICE);

    final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
            ,
            WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON ,
            PixelFormat.RGBA_8888);

    RelativeLayout layout = buildView();
    windowManager.addView(layout, layoutParams);
    windowManager.updateViewLayout(layout, layoutParams);
}

Remarques:

  • buildView est une fonction qui renvoie un relativeLayout. Dans cette fonction, j'ajoute le contenu de manière dynamique (TextView, ImageView, etc ...).
  • wakeLockAcquired est un membre booléen et prend la valeur false lorsque la vue est détruite.
6
Elior

OK, donc j'ai réussi à le résoudre avec quelques solutions de contournement et l'aide de la réponse de @Umair.

Comme je le disais, j'affiche une vue créée dans un service d'arrière-plan à l'aide de WindowManager et avec le code que j'ai ajouté à la question ci-dessus, la vue est affichée au-dessus de toutes les autres applications, mais ne tourne pas l'écran lorsque la version Android est Android 8.

Les méthodes qui remplacent maintenant les drapeaux: FLAG_SHOW_WHEN_LOCKEDFLAG_TURN_SCREEN_ON sont visibles pour les activités et non pour les services ou pour WindowManager. Transformer le contexte en activité n’est pas une bonne idée et ne vous aidera pas :)

Donc, ce que j'ai fait pour l'instant (solution temporaire) est de créer une activité transparente. Lorsque j'appelle la méthode showView() depuis mon service d'arrière-plan, je lance également l'activité transparente.

Dans l'activité - dans la méthode onCreate, j'appelle les méthodes:

setShowWhenLocked(true) 
setTurnScreenOn(true)

et lorsque la vue est détruite, l'activité est également gênée par l'aide du récepteur de radiodiffusion :) l'écran est maintenant allumé et la vue est au-dessus de toutes les autres applications.

Je sais que vous pouvez me dire que je peux déplacer mon code à l'intérieur de mon service vers la nouvelle activité.

La raison pour laquelle je l'ai fait de cette façon:

J'utilise un logiciel de reconnaissance vocale ... et lorsque je l'ai codé dans l'activité, les choses ne fonctionnaient pas. Je veux dire quand l'écran est verrouillé avec le motif, l'activité passe en pause et je ne peux pas obtenir les résultats. donc le motif a rejeté mon activité .. 

J'ai donc décidé de créer une vue à l'aide du gestionnaire de fenêtres et cela fonctionnait bien jusqu'à présent - lorsque Google (l'équipe Android) a décidé de déconseiller ces indicateurs ... C'est donc ma solution pour l'instant ... et j'espère que quelqu'un trouvera un meilleure solution pour ce problème.

5
Elior

Donc, selon la documentation Android, ces méthodes étaient obsolètes. Vous devez donc utiliser showWhenLocked or setShowWhenLocked(boolean) à la place. 

FLAG_TURN_SCREEN_ON

int FLAG_TURN_SCREEN_ON Cette constante est obsolète en API niveau 27 . Utilisez turnScreenOn ou setTurnScreenOn (booléen) à la place pour empêcher un double événement non intentionnel du cycle de vie.

Indicateur de fenêtre: lorsqu'il est défini comme une fenêtre ajoutée ou rendue visible, une fois la fenêtre a été montrée alors le système passera le pouvoir l’activité utilisateur du gestionnaire (comme si l’utilisateur avait réveillé le périphérique) sur allume l'écran.

Et FLAG_SHOW_WHEN_LOCKED

int FLAG_SHOW_WHEN_LOCKED Cette constante est obsolète en API niveau 27 . Utilisez plutôt showWhenLocked ou setShowWhenLocked (booléen) pour éviter un double événement involontaire du cycle de vie.

Indicateur de fenêtre: indicateur spécial permettant aux fenêtres d'être affichées lorsque l'écran est fermé à clef. Cela laissera la priorité aux fenêtres d’application sur la touche garde ou tout autre écran de verrouillage. Peut être utilisé avec FLAG_KEEP_SCREEN_ON pour allumer l'écran et afficher les fenêtres directement avant d'afficher la clé fenêtre de garde. Peut être utilisé avec FLAG_DISMISS_KEYGUARD pour automatiquement rejette complètement les gardes-clés non sécurisés. Ce drapeau ne s'applique qu'au la plus haute fenêtre plein écran.

Donc, selon la documentation, ces méthodes étaient déconseillées par an unintentional double life-cycle event. Vous pouvez en savoir plus à leur sujet ici . https://developer.Android.com/reference/Android/view/WindowManager.LayoutParams.html

6
Umair

KeyguardManager allume l'écran si attr turnScreenOn est à true, alors l'ordre des méthodes et l'appel à requestDismissKeyguard sont nécessaires J'utilise ce code pour l'activité, j'espère que ça va aider:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
        setShowWhenLocked(true)
        setTurnScreenOn(true)
        val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
        keyguardManager.requestDismissKeyguard(this, null)
    } else {
        this.window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
                WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON)
    }
}
3
Dmitry Ognyov

Vivez-vous cela

setShowWhenLocked(true)
setTurnScreenOn(true)

ne pas allumer l'écran plus longtemps dans Android 9? Ou est-ce juste mon cas?

0
Perry