Pemberitahuan lewat Intent Extras lama

134

saya membuat pemberitahuan di dalam BroadcastReceiver melalui kode ini:

String ns = Context.NOTIFICATION_SERVICE;
        NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns);
        int icon = R.drawable.ic_stat_notification;
        CharSequence tickerText = "New Notification";
        long when = System.currentTimeMillis();

        Notification notification = new Notification(icon, tickerText, when);
        notification.defaults |= Notification.DEFAULT_VIBRATE;
        long[] vibrate = {0,100,200,200,200,200};
        notification.vibrate = vibrate;
        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        CharSequence contentTitle = "Title";
        CharSequence contentText = "Text";
        Intent notificationIntent = new Intent(context, NotificationActivity.class);
        notificationIntent.putExtra(Global.INTENT_EXTRA_FOO_ID, foo_id);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

        notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

        int mynotification_id = 1;

        mNotificationManager.notify(mynotification_id, notification);

Ketika saya mengklik notifikasi, itu membuka NotificationActivity dan di dalam Activity saya dapat mengambil foo_id dari Intent-Bundle (misal 1)

Namun jika notifikasi lain dipicu dan saya mengkliknya lagi, aktivitas masih menerima nilai "lama" (1) dari Intent-Bundle. Saya sudah mencoba menghapus bundel dengan clear (), tetapi saya menerima efek yang sama. Saya pikir sth salah dengan kode saya ..

BrianM
sumber
tolong beri tahu saya bagaimana Anda mendapatkan data dari niat yang tertunda
user49557
untuk menyadari bahwa itu mengirimkan ekstra lama, membuat triase saya lebih mudah.
Utsav Gupta

Jawaban:

268

Anda mengirim kode permintaan yang sama untuk intensitas Anda yang tertunda. Ubah ini:

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

Untuk:

PendingIntent contentIntent = PendingIntent.getActivity(context, UNIQUE_INT_PER_CALL, notificationIntent, 0);

Maksud tidak dibuat jika Anda mengirim params yang sama. Mereka digunakan kembali.

IncrediApp
sumber
1
jadi UNIQUE_INT_PER_CALL adalah Integer yang harus saya berikan? atau ini variabel statis yang dideklarasikan di suatu tempat?
BrianM
23
Android gotcha # 147 - jadi Intentyang memiliki tambahan berbeda (via putExtra) dianggap sama dan digunakan kembali karena saya tidak memberikan id unik untuk beberapa panggilan niat tertunda - api mengerikan
wal
Anda tahu, saya sangat ceroboh. Hanya berpikir bagaimana itu bisa tetap 0 dalam satu blok (dalam kasus saya) :(
Exigente05
3
Ini sangat berguna bagi saya, hanya tip untuk orang lain, kemungkinan Anda sedang membangun notifikasi dengan metode yang sama, sehingga Anda dapat mengatur id untuk niat tertunda yang baru menjadi sama dengan yang akan Anda buka gunakan untuk notifikasi id unik!
James McNee
1
@IncrediApp, apakah itu sama dengan PendingIntent.getBroadcast (); ?
Shruti
139

Atau, Anda dapat menggunakan kode berikut untuk menghasilkan PendingIntent Anda:

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Dari dokumen untuk PendingIntent.FLAG_UPDATE_CURRENT:

Jika PendingIntent yang dijelaskan sudah ada, maka simpan tetapi ganti data tambahannya dengan apa yang ada di Intent baru ini. Ini dapat digunakan jika Anda membuat maksud di mana hanya perubahan ekstra, dan tidak peduli bahwa entitas yang menerima PendingIntent Anda sebelumnya akan dapat meluncurkannya dengan tambahan baru Anda, bahkan jika mereka tidak secara eksplisit diberikan kepadanya.

ChristophK
sumber
Terima kasih ... berfungsi dengan baik untuk bendera ini yang menambahkan "PendingIntent.FLAG_UPDATE_CURRENT" :)
Najib Ahmed Puthawala
1
Bekerja untuk saya, menggunakan niat yang tertunda untuk mentransfer status dari pengaturan alarm ke penerima siaran.
William T. Mallard
Saya hanya berharap saya tahu tentang apa yang sebenarnya dilakukan flag-flag ini sebelum saya mengirimkan pemberitahuan kepada pengguna saya (!) Senang ini menyelesaikan kesengsaraan saya ...
James Andrew
42

Anda melewati ID yang sama. Dalam situasi seperti ini, buat id unik dari waktu seperti ini:

int iUniqueId = (int) (System.currentTimeMillis() & 0xfffffff);

Dan begini:

PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),iUniqueId, intentForNotification, 0);
hderanga
sumber
3
mengapa tidak menggunakan Random baru (). nextInt ()
exloong
@hderanga apa yang dilakukan dengan menambahkan "& 0xfffffff" ke int di atas?
AJW
3
@AJW System.currentTimeMillis()mengembalikan panjang, sedangkan requestIdparameter PendingIntent.getActivity()membutuhkan int. 0xffffffffadalah bitmask. Meskipun ada sedikit lebih banyak untuk itu, penjelasan sederhana adalah bahwa melakukan `long & 0xffffffff 'memberikan 32-bit terendah dari yang lama dan membuang 32-bit tertinggi, membuat Anda pada dasarnya int 32-bit. Ini lebih baik daripada hanya melemparkan ke int karena itu tidak akan membuang bit tanda (jika Anda membuang panjang yang lebih besar dari int ke sebuah bit tanda akan melimpah dan Anda akan berpotensi berakhir dengan nilai negatif )
Jordan Bondo
8

Bagi siapa pun yang mencari pendekatan terbaik setelah sekian lama, Anda harus melewati PendingIntent.FLAG_UPDATE_CURRENT sebagai argumen terakhir seperti yang ditunjukkan di bawah ini

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Anda bahkan tidak perlu memberikan id unik baru.

Anda perlu melakukan ini untuk waktu berikutnya dan seterusnya bukan untuk pertama kalinya

Lemah lembut
sumber
1
Itu tidak berhasil, saya tiba di sini karena itulah yang saya lakukan.
Brill Pappin
Anda perlu melakukan ini untuk kali berikutnya bukan untuk pertama kalinya, ini akan berhasil.
Lembut
0

Kode permintaan Anda adalah 0 untuk semua notifikasi. Ubah baris berikut:

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

Dengan:

PendingIntent contentIntent = PendingIntent.getActivity(context, new Random().nextInt(), notificationIntent, 0);
Faisal Shaikh
sumber
1
Apakah ada manfaat menggunakan "Random baru (). NextInt ()" daripada "System.currentTimeMillis ()"?
AJW
menggunakan acak dapat dengan mudah membuat kembali nilai integer yang sama lagi secara tidak sengaja, sehingga menyebabkan bug yang sangat sulit untuk menemukan maksud lama yang dilewatkan.
Sam
@ AJW ada dalam kasus saya. Saya membuat 2 pemberitahuan berbeda dalam milidetik yang sama persis, sehingga salah satunya mendapat tambahan yang salah.
artman
0

Hanya ingin menambahkan opsi lain

 PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
pellucide
sumber