protected void displayNotification(String response) {
Intent intent = new Intent(context, testActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
Notification notification = new Notification(R.drawable.icon, "Upload Started", System.currentTimeMillis());
notification.setLatestEventInfo(context, "Upload", response, pendingIntent);
nManager.notify((int)System.currentTimeMillis(), notification);
}
Cette fonction sera appelée plusieurs fois. Je voudrais pour chaque notification
lancer TestActivity lorsque vous cliquez dessus. Malheureusement, seule la première notification lance testActivity. Cliquez sur le reste pour réduire la fenêtre de notification.
Informations supplémentaires: La fonction displayNotification()
est dans une classe appelée UploadManager
. Context
est passé dans UploadManager
à partir de activity
qui instancie. La fonction displayNotification()
est appelée plusieurs fois à partir d'une fonction, également dans UploadManager, qui s'exécute dans une AsyncTask
.
Éditer 1: J'ai oublié de mentionner que je passe la réponse de chaîne dans Intent intent
sous la forme d'une extra
.
protected void displayNotification(String response) {
Intent intent = new Intent(context, testActivity.class);
intent.putExtra("response", response);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Cela fait une grande différence car j'ai besoin de la "réponse" supplémentaire pour refléter la réponse de String lors de la création de la notification. À la place, en utilisant PendingIntent.FLAG_UPDATE_CURRENT
, la "réponse" supplémentaire reflète la réponse de String lors du dernier appel à displayNotification()
.
Je sais pourquoi c'est en lisant la documentation sur FLAG_UPDATE_CURRENT
. Cependant, je ne sais pas trop comment y remédier pour le moment.
N'utilisez pas Intent.FLAG_ACTIVITY_NEW_TASK
pour PendingIntent.getActivity, utilisez FLAG_ONE_SHOT à la place
Copié des commentaires:
Puis définissez une action fictive sur l’intention, sinon les extras sont supprimés. Par exemple
intent.setAction(Long.toString(System.currentTimeMillis()))
A été aux prises avec RemoteViews
et plusieurs Intents
différents pour chaque Button
sur le widget HomeScreen
.
1. intent.setAction(Long.toString(System.currentTimeMillis()));
2. PendingIntent.FLAG_UPDATE_CURRENT
PackageManager pm = context.getPackageManager();
Intent intent = new Intent(context, MyOwnActivity.class);
intent.putExtra("foo_bar_extra_key", "foo_bar_extra_value");
intent.setAction(Long.toString(System.currentTimeMillis()));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
views.setOnClickPendingIntent(my_button_r_id_received_in_parameter, pendingIntent);
J'ai plusieurs widgets qui ont un PendingIntent attaché à chacun. Chaque fois qu'on en a eu une, ils l'ont tous été. Les drapeaux sont là pour décrire ce qui se passe avec PendingIntents qui sont exactement les mêmes.
La description de FLAG_UPDATE_CURRENT se lit beaucoup mieux maintenant:
Si le même PendingIntent que vous créez existe déjà, mettez à jour tous les anciens vers le nouvel PendingIntent que vous créez.
La définition d’exactement la même chose s’applique à l’ensemble de PendingIntent SAUF les extras. Ainsi, même si vous avez des extras différents pour chaque intention (pour moi, j’ajoutais appWidgetId), ils sont identiques sous Android.
Ajouter .setAction avec une chaîne unique factice indique le système d'exploitation. Celles-ci sont complètement différentes et ne mettent à jour rien. En fin de compte, voici mon implémentation qui fonctionne comme je le voulais, où chaque widget a sa propre configuration. Intention attachée:
Intent configureIntent = new Intent(context, ActivityPreferences.class);
configureIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
configureIntent.setAction("dummy_unique_action_identifyer" + appWidgetId);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, configureIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Une solution encore meilleure si vous travaillez avec des émissions. Les objets uniques en attente sont également définis par des codes de demande uniques. Voici ma solution:
//Weee, magic number, just want it to be positive nextInt(int r) means between 0 and r
int dummyuniqueInt = new Random().nextInt(543254);
PendingIntent pendingClearScreenIntent = PendingIntent.getBroadcast(context,
dummyuniqueInt, clearScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
J'ai eu le même problème et j'ai pu le résoudre en changeant l'indicateur en
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Je vois des réponses mais pas d'explications. En outre, aucune des réponses n'abordant toutes les solutions possibles, je vais donc essayer de le préciser.
Documentation:
Si vous avez réellement besoin de plusieurs objets PendingIntent distincts et actifs en même temps (par exemple, pour utiliser deux notifications affichées simultanément), vous devez vous assurer qu'il existe quelque chose de différent pour les associer à différentes PendingIntents. Il peut s'agir de l'un des attributs d'intention pris en compte par Intent.filterEquals ou de différents entiers de code de requête fournis à getActivity (Context, int, Intent, int), getActivities (Context, int, Intent [], int), getBroadcast (Context, int , Intent, int) ou getService (Context, int, Intent, int).
Cause du problème: _
Vous créez 2 notifications avec 2 intentions en attente. Chaque intention en attente est associée à une intention:
Intent intent = new Intent(context, testActivity.class);
Cependant, ces deux intentions sont égales. Par conséquent, lorsque votre deuxième notification arrive, elle lance la première intention.
Solution:
Vous devez rendre chaque intention unique, afin qu'aucune intention en attente ne soit jamais égale. Comment faites-vous les intentions uniques? Pas par les extras que vous avez mis avec putExtra()
. Même si les suppléments sont différents, les intentions peuvent toujours être égales. Pour que chaque intention soit unique, vous devez définir une valeur unique pour l'action d'intention, les données, le type, la classe, la catégorie ou le code de requête:
intent.setAction(...)
intent.setData(...)
intent.setType(...)
intent.setClass(...)
intent.addCategory(...)
PendingIntent.getActivity(context, YOUR_UNIQUE_CODE, intent, Intent.FLAG_ONE_SHOT);
Note: Il peut être difficile de définir un code de requête unique, car vous avez besoin d'un int, tandis que System.currentTimeMillis()
est long, ce qui signifie que certains chiffres seront supprimés. Par conséquent, je recommanderais soit d'aller avec le catégorie _ ou le action et de définir une chaîne unique.
Comme le dit la documentation, utilisez un code de requête unique:
Si vous avez vraiment besoin de plusieurs objets PendingIntent distincts actifs à En même temps (par exemple, pour utiliser deux notifications qui sont toutes les deux affichées en même temps), vous devrez alors vous assurer qu'il y a quelque chose c’est différent de les associer à différents PendingIntents. Cela peut être n'importe lequel des attributs d'intention pris en compte par Intent.filterEquals, ou différents entiers de code de demande fournis à getActivity (Context, int, Intent, Int), getActivities (Context, int, Intent [], int), getBroadcast (Contexte, int, Intent, int) ou getService (Context, int, Intent, int).
Fwiw, j'ai eu plus de chance avec PendingIntent.FLAG_CANCEL_CURRENT
qu'avec PendingIntent.FLAG_UPDATE_CURRENT
.
J'ai eu le même problème et je l'ai corrigé par les étapes ci-dessous
1) Effacer tout drapeau pour intention
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
2) insérez intent.setAction par le code ci-dessous
intent.setAction(Long.toString(System.currentTimeMillis()));
3) pour Pendingintent, insérez le code ci-dessous
PendingIntent Pintent = PendingIntent.getActivity(ctx,0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
J'espère travailler avec vous
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contient deux paramètres int, le deuxième et le dernier. Le second est "code de requête" et doit être un numéro unique (par exemple, id de votre notification), sinon si (comme dans votre exemple, il est égal à zéro, il sera toujours remplacé).
// Use pending Intent and also use unique id for display notification....
// Get a PendingIntent containing the entire back stack
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager mNotificationManager = (NotificationManager) sqlitewraper.context.getSystemService(Context.NOTIFICATION_SERVICE);
// Issue the notification
mNotificationManager.notify(id, builder.build());
J'ai le même problème et utilise le PendingIntent.html.FLAG_UPDATE_CURRENT pour le corriger.
J'ai vérifié le code source. Dans ActivityManagerService.Java , la méthode de clé est la suivante. Lorsque l'indicateur est PendingIntent.FLAG_UPDATE_CURRENT et que updateCurrent est à true. Certains extras seront remplacés par de nouveaux et nous aurons un PendingIntent remplacé.
IIntentSender getIntentSenderLocked(int type, String packageName,
int callingUid, int userId, IBinder token, String resultWho,
int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
Bundle bOptions) {
// ... omitted
final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
|PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntentRecord.Key key = new PendingIntentRecord.Key(
type, packageName, activity, resultWho,
requestCode, intents, resolvedTypes, flags, bOptions, userId);
WeakReference<PendingIntentRecord> ref;
ref = mIntentSenderRecords.get(key);
PendingIntentRecord rec = ref != null ? ref.get() : null;
if (rec != null) {
if (!cancelCurrent) {
if (updateCurrent) {
if (rec.key.requestIntent != null) {
rec.key.requestIntent.replaceExtras(intents != null ?
intents[intents.length - 1] : null);
}
if (intents != null) {
intents[intents.length-1] = rec.key.requestIntent;
rec.key.allIntents = intents;
rec.key.allResolvedTypes = resolvedTypes;
} else {
rec.key.allIntents = null;
rec.key.allResolvedTypes = null;
}
}
return rec;
}
rec.canceled = true;
mIntentSenderRecords.remove(key);
}
pour envoyer des données supplémentaires correctement, vous devez envoyer avec l'intention en attente l'ID de notification comme suit: PendingIntent waitingIntent = PendingIntent.getActivity (context, (int) System.currentTimeMillis () , intent, PendingIntent.FLAG_UPDATE_CURRENT);