2010-05-13 8 views
2

Je souhaite afficher une notification indiquant la progression d'une opération en cours . Cela fonctionne bien pour moi. Mais en même temps, la vue à distance doit contenir le bouton d'annulation pour arrêter l'opération en cours. L'intention de contenu habituelle doit toujours faire autre chose, c'est-à-dire ne pas annuler l'opération en cours. Il semble cependant que je ne peux avoir qu'une seule intention.PendingIntents dans les notifications

Je dois spécifier un contentIntent qui est lancé lorsque vous cliquez sur la notification: Si je ne précise pas que je reçois quelque chose le long de ces lignes :

E/ActivityManager( 62): Activity Manager Crash 
E/ActivityManager( 62): java.lang.IllegalArgumentException: contentIntent required ... 

Pour le bouton « annuler » Je mets une autre intention:

Intent cancelSyncIntent = new Intent("com.xyz.CANCEL_SYNC"); 
contentView.setOnClickPendingIntent(R.id.cancel_sync, 
            PendingIntent.getBroadcast(context, 0, 
            cancelSyncIntent, 0)); 

Mais cela ne fonctionne jamais. Je reçois toujours l'intention de contenu lorsque le bouton est cliqué. Il semble que je ne peux pas utiliser les boutons dans les affichages à distance des notifications ?!

Je pourrais probablement afficher un texte: "< < Appuyez sur pour annuler l'opération >>", mais cela semble plutôt lourd.

Mise à jour: Afer recommandations de J.:

final Notification n = new Notification(R.drawable.gen_auto_notification_icon, context.getResources() 
      .getString(
        fastSyncOnly ? R.string.fast_synchronization_running_notification_title 
          : R.string.synchronization_running_notification_title), new Date().getTime()); 

    n.flags = Notification.FLAG_ONGOING_EVENT; 

    final RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.in_progress_notification); 
    n.contentView = contentView; 

    // Intent cancelSyncIntent = new Intent("com.newsrob.CANCEL_SYNC"); 
    Intent cancelSyncIntent = new Intent(); 
    cancelSyncIntent.setClass(context, FireReceiver.class); 
    PendingIntent pendingCancelSyncIntent = PendingIntent.getActivity(context, 0, cancelSyncIntent, 0); 
    contentView.setOnClickPendingIntent(R.id.cancel_sync, pendingCancelSyncIntent); 

    Intent showDashboardIntent = new Intent(context, DashboardListActivity.class); 
    PendingIntent showDashboardPendingIntent = PendingIntent.getActivity(context, 0, showDashboardIntent, 0); 
    n.contentIntent = showDashboardPendingIntent; 

Répondre

3

Réponse courte: Vous ne pouvez pas avoir de vues enfant cliquables dans une vue de notification.

réponse plus longue ...

J'ai passé une journée à essayer d'obtenir que cela fonctionne aussi bien et a finalement renoncé et regardé à la source Android. Il semble que tout se passe dans makeNotificationView() dans StatusBarService.java. Dans là, le code gonfle une mise en page nommée "status_bar_latest_event" pour chaque ligne de la notification déroulante ombre. Il attrape un ViewGroup à partir de cette vue, il vient de gonfler nommé "content", appelle setDescendantFocusability (ViewGroup.FOCUS_BLOCK_DESCENDANTS) dessus, puis ajoute votre vue de notification en tant qu'enfant de cela. Donc, en supposant que je comprenne comment fonctionne FOCUS_BLOCK_DESCENDANTS, il semble qu'il n'y ait aucun espoir que votre vue ou l'un de ses enfants obtiennent des événements de focus ou de clic.

J'ai également suivi la logique de fonctionnement du PendingEvent principal que vous associez à votre Notification. Le même ViewGroup qui héberge votre vue Notification reçoit un appel setOnClickListener() pour enregistrer une classe d'écouteurs nommée "Launcher". Lorsque cette classe reçoit un événement onClick(), elle appelle simplement la méthode send() sur le PendingIntent que vous avez associé à la notification. J'espérais peut-être que la coordonnée du clic pourrait être transmise afin que je puisse au moins essayer de calculer quel bouton a été cliqué, mais pas une telle chance.

Quoi qu'il en soit, si quelqu'un connaît un moyen de contourner ce problème, j'aimerais l'entendre. Pour le moment, je tire juste mes boutons et je continue.

0

intention cancelSyncIntent = new Intent(); cancelSyncIntent .setClassName ("com.xyz", "com.xyz.CANCEL_SYNC");

PendingIntent pendingIntent = PendingIntent.getActivity(context, 
    0 /* no requestCode */, cancelSyncIntent , 0 /* no flags */); 
contentView.setOnClickPendingIntent(R.id.cancel_sync, pendingIntent); 
+0

Merci J. Etes-vous sûr que cela fonctionne de cette façon? J'essaie, voir ci-dessus, mais quand je tape sur "Annuler", je n'ai que le showDashboardIntent. –

Questions connexes