Comment mettre à jour la Notification avec RemoteViews?

je crée une notification avec RemoteViews à partir d'un custom Service, qui s'exécute avec notification en mode premier plan (c'est-à-dire que le service reste actif tant que la notification est visible à l'utilisateur). La Notification est définie comme étant en cours afin que l'utilisateur ne puisse pas la retirer.

j'aimerais changer par exemple bitmap dans ImageView, contenu dans la mise en page de la vue à distance ou changer la valeur du texte dans un TextView. Layout en vue à distance est défini avec layout XML fichier.

mon problème est qu'une fois la notification créée et visible à l'utilisateur, si je l'appelle RemoteViewsfonctions setImageViewResource() modifier Bitmap dans un ImageView, le changement n'est pas visible, sauf si je fais appel setImageViewResource() je l'appelle par la suite:

NotificationManager.notify( id, notification );

ou

Service.startForeground(id,notification);

cela ne me semble pas juste. Je ne peux pas croire que de mettre à jour RemoteViews UI dans une notification qui est déjà créée, je dois ré-initialiser notification. Si j'ai Button contrôle dans une notification, il se met à jour sur touch et release. Il doit y avoir un moyen de faire ça correctement, mais je ne sais pas comment.

Voici mon code qui crée la notification à l'intérieur de mon Service exemple:

this.notiRemoteViews = new MyRemoteViews(this,this.getApplicationContext().getPackageName(),R.layout.activity_noti1);

Notification.Builder notibuilder = new Notification.Builder(this.getApplicationContext());
notibuilder.setContentTitle("Test");
notibuilder.setContentText("test");
notibuilder.setSmallIcon(R.drawable.icon2);
notibuilder.setOngoing(true);

this.manager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
this.noti = notibuilder.build();
this.noti.contentView = this.notiRemoteViews;
this.noti.bigContentView = this.notiRemoteViews;
this.startForeground(NOTIFICATION_ID, this.noti);

Et la fonction qui 'des forces de changement de l'INTERFACE de notification:

public void updateNotiUI(){
    this.startForeground(NOTIFICATION_ID, this.noti);
}

à l'intérieur de MyRemoteViews classe, lorsque nécessaire, je fais ceci pour apporter des modifications à l'INTERFACE utilisateur:

this.setImageViewResource(R.id.iconOFF, R.drawable.icon_off2);
this.ptMyService.updateNotiUI();

est-ce que quelqu'un peut me dire ce que est la bonne façon de mettre à jour les composants UI d'un RemoteViews dans la notification?

25
demandé sur naXa 2014-04-01 18:57:38

3 réponses

voici un exemple détaillé pour mettre à jour la notification en utilisant RemoteViews:

private static final int NOTIF_ID = 1234;
private NotificationCompat.Builder mBuilder;
private NotificationManager mNotificationManager;
private RemoteViews mRemoteViews;
private Notification mNotification;
...

// call this method to setup notification for the first time
private void setUpNotification(){

    mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    // we need to build a basic notification first, then update it
    Intent intentNotif = new Intent(this, MainActivity.class);
    intentNotif.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pendIntent = PendingIntent.getActivity(this, 0, intentNotif, PendingIntent.FLAG_UPDATE_CURRENT);

    // notification's layout
    mRemoteViews = new RemoteViews(getPackageName(), R.layout.custom_notification_small);
    // notification's icon
    mRemoteViews.setImageViewResource(R.id.notif_icon, R.drawable.ic_launcher);
    // notification's title
    mRemoteViews.setTextViewText(R.id.notif_title, getResources().getString(R.string.app_name));
    // notification's content
    mRemoteViews.setTextViewText(R.id.notif_content, getResources().getString(R.string.content_text));

    mBuilder = new NotificationCompat.Builder(this);

    CharSequence ticker = getResources().getString(R.string.ticker_text);
    int apiVersion = Build.VERSION.SDK_INT;

    if (apiVersion < VERSION_CODES.HONEYCOMB) {
        mNotification = new Notification(R.drawable.ic_launcher, ticker, System.currentTimeMillis());
        mNotification.contentView = mRemoteViews;
        mNotification.contentIntent = pendIntent;

        mNotification.flags |= Notification.FLAG_NO_CLEAR; //Do not clear the notification
        mNotification.defaults |= Notification.DEFAULT_LIGHTS;

        // starting service with notification in foreground mode
        startForeground(NOTIF_ID, mNotification);

    }else if (apiVersion >= VERSION_CODES.HONEYCOMB) {
        mBuilder.setSmallIcon(R.drawable.ic_launcher)
                .setAutoCancel(false)
                .setOngoing(true)
                .setContentIntent(pendIntent)
                .setContent(mRemoteViews)
                .setTicker(ticker);

        // starting service with notification in foreground mode
        startForeground(NOTIF_ID, mBuilder.build());
    }
}

// use this method to update the Notification's UI
private void updateNotification(){

    int api = Build.VERSION.SDK_INT;
    // update the icon
    mRemoteViews.setImageViewResource(R.id.notif_icon, R.drawable.icon_off2);
    // update the title
    mRemoteViews.setTextViewText(R.id.notif_title, getResources().getString(R.string.new_title));
    // update the content
    mRemoteViews.setTextViewText(R.id.notif_content, getResources().getString(R.string.new_content_text));

    // update the notification
    if (api < VERSION_CODES.HONEYCOMB) {
        mNotificationManager.notify(NOTIF_ID, mNotification);
    }else if (api >= VERSION_CODES.HONEYCOMB) {
        mNotificationManager.notify(NOTIF_ID, mBuilder.build());
    }
}

Mise en page de la Notification, c'est à dire res/layout/custom_notification_small.xml:

<!-- We have to set the height to 64dp, this is the rule of the small notification -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="64dp"
    android:orientation="horizontal"
    android:id="@+id/notif_small"
    android:background="@drawable/notification_background">

    <ImageView
        android:id="@+id/notif_icon"
        android:contentDescription="@string/notif_small_desc"
        android:layout_width="47dp"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:src="@drawable/ic_launcher"
        android:layout_marginLeft="7dp"
        android:layout_marginRight="9dp"/>

    <TextView
        android:id="@+id/notif_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/notif_icon"
        android:singleLine="true"
        android:paddingTop="8dp"
        android:textSize="17sp"
        android:textStyle="bold"
        android:textColor="#000000"
        android:text="@string/app_name"/>

    <TextView
        android:id="@+id/notif_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/notif_icon"
        android:paddingBottom="9dp"
        android:layout_alignParentBottom="true"
        android:singleLine="true"
        android:textSize="13sp"
        android:textColor="#575757"
        android:text="Content" />
</RelativeLayout>

j'Espère que cet exemple vous aide beaucoup!

REMARQUE: Vous ne pouvez pas mettre à jour le custom NotificationCompat sur la pré-Nid d'abeille, j'ai donc ajouté un autre moyen de le mettre à jour sur la pré-Nid d'abeille, c'est à dire la vérification de l'API de niveau premier et utiliser le obsolète Notification à la place.

36
répondu Anggrayudi H 2017-09-12 02:20:56

Vous devez appeler NotificationManager.notify(id, notification) pour faire savoir au système de Notification que vous voulez mettre à jour la vue notification. Voici le lien docs http://developer.android.com/training/notify-user/managing.html.

ont une méthode qui renvoie L'objet Notification.

private Notification getNotification(NotificationCompat.Builder mBuilder) {
    RemoteViews mRemoteViews = new RemoteViews(getPackageName(), R.layout.notification_layout);
    // Update your RemoteViews
    mBuilder.setContent(mRemoteView);
    Notification mNotification = mBuilder.build();
    // set mNotification.bigContentView if you want to
    return mNotification;

}

private void refreshNotification() {
    mNotificationManager.notify(getNotification(mNotificationBuilder),
                        NOTIFICATION_ID);
    // mNotificationBuilder is initialized already
}

Notez aussi que bigContentView et RemoteViews ne sont pas complètement redessiné. Si certains éléments de bigContentView ont une visibilité définie à GONE, et si vous voulez montrer la prochaine fois, vous devez définir explicitement la visibilité VISIBLE.

2
répondu Froyo 2015-06-11 06:21:04

Ne pas stocker Notification objet, mais le Notification.Builder objet. Produire de nouvelles notification à chaque fois avant de le pousser à

NotificationManager.notify( id, notification );
-1
répondu dykzei eleeot 2018-03-12 02:12:09