Android bloque l'affichage des notifications sur l'écran de verrouillage

Introduction

        [Description des exigences personnalisées] : après avoir inséré la carte SD, dans l'état de l'écran de verrouillage, supprimez l'invite "La carte SD peut être utilisée pour transférer des photos et des fichiers multimédias"

Démontage des exigences : il doit être normalement affiché dans la barre d'état déroulante de SystemUI, et seules les notifications dans l'état de l'écran de verrouillage doivent être bloquées.

2. Envoyer une notification

Cherchez d'abord la chaîne "peut être utilisé pour transférer des photos et des fichiers multimédias"

est dans /frameworks/base/core/res/res/values-zh-rCN.xml

Recherchez le fichier faisant référence à la chaîne dans le code source : StorageNotification.java Le chemin est :

 frameworks/base/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java

Le code logique après insertion de SD est :

 private void onVolumeStateChangedInternal(VolumeInfo vol) {
        switch (vol.getType()) {
            case VolumeInfo.TYPE_PRIVATE:
                onPrivateVolumeStateChangedInternal(vol);
                break;
                //SD卡
            case VolumeInfo.TYPE_PUBLIC:
                onPublicVolumeStateChangedInternal(vol);
                break;
        }
    }

Ensuite, une fois la carte SD montée avec succès, la méthode onVolumeMounted(vol) sera utilisée

private Notification onVolumeMounted(VolumeInfo vol) {
....
Notification.Builder builder = buildNotificationBuilder(vol, title, text)
....
}

Dans la méthode, l'objet générateur de notification sera créé

private Notification.Builder buildNotificationBuilder(VolumeInfo vol, CharSequence title,
            CharSequence text) {
        Notification.Builder builder =
                new Notification.Builder(mContext, NotificationChannels.STORAGE)
                        .setSmallIcon(getSmallIcon(vol.getDisk(), vol.getState()))
                        .setColor(mContext.getColor(R.color.system_notification_accent_color))
                        .setContentTitle(title)
                        .setContentText(text)
                        .setStyle(new Notification.BigTextStyle().bigText(text))
                        .setVisibility(Notification.VISIBILITY_PUBLIC)
                        .setLocalOnly(true)
                        .extend(new Notification.TvExtender());
        overrideNotificationAppName(mContext, builder, false);
        return builder;
    }

Ensuite, revenez à onPublicVolumeStateChangedInternal. Lorsque le générateur est créé avec succès, l'étape suivante consiste à envoyer une notification

 private void onPublicVolumeStateChangedInternal(VolumeInfo vol) {
....
mNotificationManager.notifyAsUser(vol.getId(), SystemMessage.NOTE_STORAGE_PUBLIC,
                    notif, UserHandle.of(vol.getMountUserId()));
....
}

3. Afficher la notification

Les développeurs qui connaissent le module SystemUI peuvent visualiser directement le fichier qui gère l'affichage des notifications dans l'état de l'écran verrouillé :

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java est un fichier d'interface avec ces deux méthodes :

L'une consiste à filtrer par userId, et l'autre à filtrer les communications cachées par String key

    boolean shouldHideNotifications(int userId);
    boolean shouldHideNotifications(String key);

Le fichier d'implémentation spécifique est le fichier NotificationLockscreenUserManagerImpl.java

Je filtre en utilisant la méthode clé

public boolean shouldHideNotifications(String key) {
        if (getEntryManager() == null) {
            Log.wtf(TAG, "mEntryManager was null!", new Throwable());
            return true;
        }
        return isLockscreenPublicMode(mCurrentUserId)
                && getEntryManager().getNotificationData().getVisibilityOverride(key) ==
                        Notification.VISIBILITY_SECRET;
    }

Rechercher globalement où cette méthode est appelée

 

 Dans la méthode shouldFilterOut du fichier NotificationFilter.java

  /**
     * @return true if the provided notification should NOT be shown right now.
     */
    public boolean shouldFilterOut(NotificationEntry entry) {
        final StatusBarNotification sbn = entry.notification;
        if (!(getEnvironment().isDeviceProvisioned()
                || showNotificationEvenIfUnprovisioned(sbn))) {
            return true;
        }

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

        if (getUserManager().isLockscreenPublicMode(sbn.getUserId())
                && (sbn.getNotification().visibility == Notification.VISIBILITY_SECRET
                        || getUserManager().shouldHideNotifications(sbn.getUserId())
                        || getUserManager().shouldHideNotifications(sbn.getKey()))) {
            return true;
        }
....

}

La signification de cette méthode est de filtrer les notifications dans des conditions spécifiques, il existe donc une solution à cela. Dans cette méthode, nous renvoyons vrai selon des conditions de jugement spécifiques, indiquant que cette notification doit être filtrée sur l'écran de verrouillage.

4. Solutions

Étant donné que la clé est utilisée comme condition de jugement, ajoutez une méthode liée à la clé à l'endroit où la notification est envoyée

 private Notification.Builder buildNotificationBuilder(VolumeInfo vol, CharSequence title,
            CharSequence text) {
        Notification.Builder builder =
                new Notification.Builder(mContext, NotificationChannels.STORAGE)
                        .setSmallIcon(getSmallIcon(vol.getDisk(), vol.getState()))
                        .setColor(mContext.getColor(R.color.system_notification_accent_color))
                        .setContentTitle(title)
                        .setContentText(text)
                        .setStyle(new Notification.BigTextStyle().bigText(text))
                        .setVisibility(Notification.VISIBILITY_PUBLIC)
                        .setLocalOnly(true)
                        //加上这个自定义的key  不需要显示在锁屏界面
                        .setGroup("not_show_on_lockscreen")
                        .extend(new Notification.TvExtender());
        overrideNotificationAppName(mContext, builder, false);
        return builder;
    }

Ensuite, dans la méthode de filtrage pour afficher les notifications, ajoutez une condition de jugement et renvoyez true

    public boolean shouldFilterOut(NotificationEntry entry) {
        final StatusBarNotification sbn = entry.notification;
        if (!(getEnvironment().isDeviceProvisioned()
                || showNotificationEvenIfUnprovisioned(sbn))) {
            return true;
        }
        //在锁屏界面不显示SD卡的通知
        if ("not_show_on_lockscreen".equals(sbn.getGroupKey())) {
            return true;
        }
        //
   ....

   }

Supongo que te gusta

Origin blog.csdn.net/u012514113/article/details/130186104
Recomendado
Clasificación