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);
}
Ta funkcja będzie wywoływana wiele razy. Chciałbym, aby każdy notification
uruchamiał testActivity po kliknięciu. Niestety, dopiero pierwsze powiadomienie uruchamia testActivity. Kliknięcie na resztę powoduje zminimalizowanie okna powiadomienia.
Dodatkowe informacje: Funkcja displayNotification()
znajduje się w klasie o nazwie UploadManager
. Context
jest przekazywany UploadManager
z tego, activity
co tworzy instancję. Funkcja displayNotification()
jest wywoływana wiele razy z funkcji, również w programie UploadManager, która działa w pliku AsyncTask
.
Edycja 1: zapomniałem wspomnieć, że przekazuję odpowiedź typu String do Intent intent
pliku 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);
To robi dużą różnicę, ponieważ potrzebuję dodatkowej „odpowiedzi”, aby odzwierciedlić, jaka była odpowiedź typu String w momencie tworzenia powiadomienia. Zamiast tego, PendingIntent.FLAG_UPDATE_CURRENT
dodatkowa „odpowiedź” odzwierciedla odpowiedź typu String podczas ostatniego wywołania displayNotification()
.
Wiem, dlaczego to jest po przeczytaniu dokumentacji FLAG_UPDATE_CURRENT
. Jednak w tej chwili nie wiem, jak to obejść.
źródło
Walczył z
RemoteViews
kilkoma różnymiIntents
dla każdegoButton
naHomeScreen
Widget. Działał po dodaniu tych: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);
źródło
setAction
setAction
, możesz zrobićaddCategory
.PendingIntent
używaIntent.filterEquals
do sprawdzania równości akcji, danych, typu, klasy i kategorii. developer.android.com/reference/android/content/…Ustaw działanie rozwiązało to dla mnie. Oto moje rozumienie sytuacji:
Mam wiele widżetów, do których dołączony jest PendingIntent. Za każdym razem, gdy ktoś został zaktualizowany, wszystkie zostały zaktualizowane. Flagi są tam, aby opisać, co dzieje się z PendingIntents, które są dokładnie takie same.
Opis FLAG_UPDATE_CURRENT czyta się teraz znacznie lepiej:
Jeśli ten sam PendingIntent, który tworzysz, już istnieje, zaktualizuj wszystkie stare do nowego PendingIntent, który tworzysz.
Definicja dokładnie tego samego wygląda na cały PendingIntent Z WYJĄTKIEM dodatków. Tak więc nawet jeśli masz różne dodatki w każdej intencji (dla mnie dodawałem appWidgetId), to do Androida są takie same.
Dodanie .setAction z fałszywym unikalnym ciągiem informuje system operacyjny. Są zupełnie inne i niczego nie aktualizują. Na koniec oto moja implementacja, która działa tak, jak chciałem, gdzie każdy widżet ma dołączoną własną intencję konfiguracji:
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);
AKTUALIZACJA
Jeszcze lepsze rozwiązanie w przypadku pracy z transmisjami. Unikalne PendingIntents są również definiowane przez unikalne kody żądań. Oto moje rozwiązanie:
//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);
źródło
Widzę odpowiedzi, ale żadnych wyjaśnień. Żadna z odpowiedzi również nie dotyczy wszystkich możliwych rozwiązań, więc postaram się to wyjaśnić.
Dokumentacja:
Przyczyna problemu:
Tworzysz 2 powiadomienia z 2 oczekującymi intencjami. Każda oczekująca intencja jest powiązana z intencją:
Intent intent = new Intent(context, testActivity.class);
Jednak te 2 intencje są równe, dlatego gdy nadejdzie drugie powiadomienie, uruchomi ono pierwszą intencję.
Rozwiązanie:
Musisz uczynić każdą intencję wyjątkową, aby żadne oczekujące intencje nigdy nie były równe. Jak sprawić, by intencje były wyjątkowe? Nie przez dodatki, które włożyłeś
putExtra()
. Nawet jeśli dodatki są różne, intencje mogą być jednakowe. Aby każda intencja była unikalna, musisz ustawić unikatową wartość akcji zamierzonej, danych, typu, klasy lub kategorii lub kodu żądania: (każdy z nich zadziała)intent.setAction(...)
intent.setData(...)
intent.setType(...)
intent.setClass(...)
intent.addCategory(...)
PendingIntent.getActivity(context, YOUR_UNIQUE_CODE, intent, Intent.FLAG_ONE_SHOT);
Uwaga : ustawienie unikalnego kodu żądania może być trudne, ponieważ potrzebujesz int, a
System.currentTimeMillis()
zwraca long, co oznacza, że niektóre cyfry zostaną usunięte. Dlatego radziłbym wybrać kategorię lub akcję i ustawić unikalny ciąg.źródło
Miałem ten sam problem i udało mi się go naprawić, zmieniając flagę na:
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
źródło
Zgodnie z dokumentacją użyj unikalnego kodu żądania:
źródło
Fwiw, miałem więcej szczęścia
PendingIntent.FLAG_CANCEL_CURRENT
niż zPendingIntent.FLAG_UPDATE_CURRENT
.źródło
Miałem ten sam problem i naprawiłem go, wykonując poniższe czynności
1) Wyczyść wszelkie flagi celowe
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
2) wstaw intent.setAction za pomocą poniższego kodu
intent.setAction(Long.toString(System.currentTimeMillis()));
3) dla Pendingintent wprowadź poniższy kod
PendingIntent Pintent = PendingIntent.getActivity(ctx,0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
Mam nadzieję, że będę z tobą pracować
źródło
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
W PendingIntent są dwa parametry int, drugi i ostatni. Drugi to „kod żądania” i musi to być niepowtarzalny numer (np. Identyfikator Twojego zgłoszenia), w przeciwnym razie (tak jak w Twoim przykładzie jest równy zero, zawsze zostanie nadpisany).
źródło
// 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());
źródło
aby wysłać dane wyjątkowo poprawnie, należy wysłać z intencją oczekującą identyfikator powiadomienia w następujący sposób: PendingIntent pendingIntent = PendingIntent.getActivity (context, (int) System.currentTimeMillis () , intent, PendingIntent.FLAG_UPDATE_CURRENT);
źródło
Mam ten sam problem i używam PendingIntent.html.FLAG_UPDATE_CURRENT, aby go naprawić.
Sprawdziłem kod źródłowy. W ActivityManagerService.java metoda klucza jest następująca. Gdy flaga ma wartość PendingIntent.FLAG_UPDATE_CURRENT, a parametr updateCurrent ma wartość true. Niektóre dodatki zostaną zastąpione nowymi, a my otrzymamy zmieniony PendingIntent.
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); }
źródło
Miałem ten sam problem i udało mi się go naprawić, zmieniając flagę na:
LayoutInflater factory = LayoutInflater.from(this); final View textEntryView = factory.inflate(R.layout.appointment, null); AlertDialog.Builder bulider= new AlertDialog.Builder(PatientDetail.this); final AlertDialog alert=bulider.create(); bulider.setTitle("Enter Date/Time"); bulider.setView(textEntryView); bulider.setPositiveButton("Save", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { EditText typeText=(EditText) textEntryView.findViewById(R.id.Editdate); EditText input1 =(EditText) textEntryView.findViewById(R.id.Edittime); getDateAndTime(typeText.getText().toString(),input1.getText().toString()); } }); bulider.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); bulider.show(); }
źródło