web-dev-qa-db-fra.com

Comment supprimer les notifications sur l'écran de verrouillage sous Android 5 (Lollipop) tout en les laissant dans la zone de notification?

Après la mise à niveau vers Android 5.0 Lollipop, il a commencé à afficher automatiquement la notification en cours sur l’écran de verrouillage.

Parfois, les utilisateurs ne veulent pas tous les voir, ils demandent donc aux développeurs comment laisser les notifications dans la zone d'état tout en les masquant sur l'écran de verrouillage.

La seule façon que j’ai trouvée est de forcer les utilisateurs à utiliser le verrouillage de l’écran (par exemple, Gesture ou code PIN) et par programme setVisibility () to VISIBILITY_SECRET . Mais tous ne veulent pas utiliser le verrouillage de l'écran.

Existe-t-il un indicateur (ou une combinaison d'indicateurs) indiquant à la notification: ne soyez pas visible sur l'écran de verrouillage, mais dans la zone de notification?

17
Tomáš Hubálek

Utiliser la visibilité et la priorité

Comme couvert par cette réponse , vous pouvez utiliser VISIBILITY_SECRET pour supprimer la notification sur l'écran de verrouillage lorsque l'utilisateur dispose d'un garde-clavier sécurisé (il ne suffit pas de glisser ou de ne pas en protéger) et de supprimer les notifications sensibles.

Pour couvrir le reste des cas, vous pouvez masquer par programmation la notification à partir de l'écran de verrouillage et de la barre d'état en définissant la priorité de la notification sur PRIORITY_MIN chaque fois que le protège-clavier est présent, puis réinitialisez la priorité en cas d'absence du verrou.

Désavantages

  • Avec un émulateur Android 5, il semble que la notification apparaisse très brièvement sur l'écran de verrouillage, puis disparaisse.
  • Ne fonctionne plus à partir d'Android O Developer Preview 2 lorsque l'utilisateur ne dispose pas d'un écran de verrouillage sécurisé (par exemple, un balayage uniquement) car les priorités de notification sont obsolètes .

Exemple

final BroadcastReceiver notificationUpdateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        NotificationManager notificationManager =
            (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);

        NotificationCompat.Builder builder =
            new NotificationCompat.Builder(context);
            .setVisibility(NotificationCompat.VISIBILITY_SECRET);

        KeyguardManager keyguardManager =
            (KeyguardManager)context.getSystemService(Context.KEYGUARD_SERVICE);

        if (keyguardManager.isKeyguardLocked())
            builder.setPriority(NotificationCompat.PRIORITY_MIN);

        notificationManager.notify(YOUR_NOTIFICATION_ID, notification);
    }
};

//For when the screen might have been locked
context.registerReceiver(notificationUpdateReceiver,
    new IntentFilter(Intent.ACTION_SCREEN_OFF));

//Just in case the screen didn't get a chance to finish turning off but still locked
context.registerReceiver(notificationUpdateReceiver,
    new IntentFilter(Intent.ACTION_SCREEN_ON));

//For when the user unlocks the device
context.registerReceiver(notificationUpdateReceiver,
    new IntentFilter(Intent.ACTION_USER_PRESENT));

//For when the user changes users
context.registerReceiver(notificationUpdateReceiver,
    new IntentFilter(Intent.ACTION_USER_BACKGROUND));
context.registerReceiver(notificationUpdateReceiver,
    new IntentFilter(Intent.ACTION_USER_FOREGROUND));
14
Sam

On dirait que VISIBILITY_SECRET est l’approche la plus propre. Selon la documentation:

une notification peut être faite VISIBILITY_SECRET, qui supprimera son icône et son symbole jusqu'à ce que l'utilisateur ait contourné le lockscreen.

Selon la source (NotificationData dans le projet SystemUI AOSP), VISIBILITY_SECRET est le seul moyen de le faire:

boolean shouldFilterOut(StatusBarNotification sbn) {
    if (!(mEnvironment.isDeviceProvisioned() ||
            showNotificationEvenIfUnprovisioned(sbn))) {
        return true;
    }

    if (!mEnvironment.isNotificationForCurrentProfiles(sbn)) {
        return true;
    }

    if (sbn.getNotification().visibility == Notification.VISIBILITY_SECRET &&
            mEnvironment.shouldHideSensitiveContents(sbn.getUserId())) {
        return true;
    }
    return false;
}

Les seuls autres types de notifications qui semblent filtrés sont les notifications enfants d'un groupe où un résumé est présent. Donc, à moins que vous n'ayez plusieurs motifs avec un motif valide pour résumé, VISIBILITY_SECRET est ce qu'il y a de mieux.

6
Jim Vitek

Vous pouvez définir la priorité de la notification sur PRIORITY_MIN . Cela devrait masquer la notification sur l'écran de verrouillage. Il masque également l'icône de la barre d'état (vous ne savez pas si vous le souhaitez), mais la notification elle-même reste visible dans la zone de notification.

4
Floern

J'ai créé un 'LockscreenIntentReceiver' pour ma notification en cours qui ressemble à ceci:


    private class LockscreenIntentReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        try { 
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                Log.d(TAG, "LockscreenIntentReceiver: ACTION_SCREEN_OFF");
                disableNotification();
            } else if (action.equals(Intent.ACTION_USER_PRESENT)){
                Log.d(TAG, "LockscreenIntentReceiver: ACTION_USER_PRESENT");
                // NOTE: Swipe unlocks don't have an official Intent/API in Android for detection yet,
                // and if we set ungoing control without a delay, it will get negated before it's created
                // when pressing the lock/unlock button too fast consequently.
                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (NotificationService.this.isNotificationAllowed()) {
                            enableNotification((Context)NotificationService.this);
                        }
                    }
                }, 800);
            }
        } catch (Exception e) {
            Log.e(TAG, "LockscreenIntentReceiver exception: " + e.toString());
        }
    }
}

Ce code supprimera essentiellement la notification en cours lorsque l'utilisateur verrouille le téléphone (la suppression sera visible très brièvement). Et une fois que l'utilisateur déverrouille le téléphone, la notification en cours est restaurée après le délai (800 ms ici). enableNotification () est une méthode qui crée la notification et appelle startForeground () . Actuellement vérifié pour fonctionner sur Android 7.1.1.

N'oubliez pas que vous devez enregistrer et désenregistrer le récepteur en conséquence.

0
ItWillDo