webentwicklung-frage-antwort-db.com.de

Wie unterdrücke ich Benachrichtigungen auf dem Sperrbildschirm in Android 5 (Lollipop), lasse sie aber im Benachrichtigungsbereich?

Nach dem Upgrade auf Android 5.0 Lollipop werden automatisch laufende Benachrichtigungen auf dem Sperrbildschirm angezeigt.

Manchmal möchten Benutzer nicht alle von ihnen sehen, deshalb fragen sie Entwickler, wie sie Benachrichtigungen im Statusbereich zulassen, sie aber auf dem Sperrbildschirm ausblenden sollen.

Die einzige Möglichkeit, die ich gefunden habe, besteht darin, Benutzer zu zwingen, die Bildschirmsperre (z. B. Geste oder PIN) und programmgesteuert setVisibility () to VISIBILITY_SECRET zu verwenden. Aber nicht alle wollen die Bildschirmsperre verwenden.

Gibt es eine Flagge (oder eine Kombination von Flaggen), die zur Benachrichtigung sagt: Nicht auf dem Sperrbildschirm sichtbar, aber im Benachrichtigungsbereich sichtbar?

17

Verwenden Sie Sichtbarkeit und Priorität

Wie in diese Antwort beschrieben, können Sie VISIBILITY_SECRET verwenden, um die Benachrichtigung auf dem Sperrbildschirm zu unterdrücken, wenn der Benutzer über eine sichere Tastensperre (nicht nur Wischen oder keine Tastensperre) verfügt und vertrauliche Benachrichtigungen unterdrückt werden.

Um den Rest der Fälle abzudecken, können Sie die Benachrichtigung programmgesteuert auf dem Sperrbildschirm und in der Statusleiste ausblenden, indem Sie die Priorität der Benachrichtigung auf PRIORITY_MIN setzen, wenn die Tastensperre vorhanden ist, und die Priorität dann zurücksetzen, wenn die Tastensperre nicht vorhanden ist.

Nachteile

  • Bei Verwendung eines Android 5-Emulators scheint dies dazu zu führen, dass die Benachrichtigung sehr kurz auf dem Sperrbildschirm angezeigt wird, dann aber verschwindet.
  • Funktioniert ab Android O Developer Preview 2 nicht mehr, wenn der Benutzer keinen sicheren Sperrbildschirm hat (z. B. nur Wischen), da Benachrichtigungsprioritäten veraltet sind .

Beispiel

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

Scheint, als ob VISIBILITY_SECRET den saubersten Ansatz macht. Gemäß der Dokumentation:

es kann eine Benachrichtigung über VISIBILITY_SECRET erfolgen, die das Symbol und den Ticker unterdrückt, bis der Benutzer den Sperrbildschirm umgangen hat.

Gemäß der Quelle (NotificationData im SystemUI AOSP-Projekt) ist VISIBILITY_SECRET die einzige Möglichkeit, dies zu tun:

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

Die einzige andere Art von Benachrichtigungen, die herausgefiltert werden, sind untergeordnete Benachrichtigungen in einer Gruppe, in der eine Zusammenfassung vorhanden ist. Wenn Sie also nicht mehrere mit einem gültigen Grund für eine Zusammenfassung haben, ist VISIBILITY_SECRET das Beste, was derzeit möglich ist.

6
Jim Vitek

Sie können die Priorität der Benachrichtigung auf PRIORITY_MIN setzen. Dies sollte die Benachrichtigung auf dem Sperrbildschirm verbergen. Außerdem wird das Symbol in der Statusleiste ausgeblendet (nicht sicher, ob Sie das möchten), aber die Benachrichtigung selbst ist im Benachrichtigungsbereich weiterhin sichtbar.

4
Floern

Ich habe einen "LockscreenIntentReceiver" für meine laufende Benachrichtigung erstellt, der so aussieht:


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

Mit diesem Code wird im Grunde genommen die laufende Benachrichtigung entfernt, wenn der Benutzer das Telefon sperrt (das Entfernen wird sehr kurz angezeigt). Und sobald der Benutzer das Telefon entsperrt, wird die laufende Benachrichtigung nach der Verzögerungszeit (800 ms hier) wiederhergestellt. enableNotification () ist eine Methode, die die Benachrichtigung erstellt und startForeground () aufruft. Derzeit für Android 7.1.1 geprüft.

Sie müssen nur daran denken, den Empfänger entsprechend zu registrieren und die Registrierung aufzuheben.

0
ItWillDo