Apa yang digunakan "requestCode" di PendingIntent?

110

Latar Belakang:

Saya menggunakan PendingIntent untuk alarm melalui AlarmManager.

Masalah:

Awalnya saya berpikir bahwa untuk membatalkan yang sebelumnya, saya harus memberikan requestCode persis seperti yang saya gunakan sebelumnya untuk memulai alarm.

Tapi kemudian saya menemukan saya salah, seperti yang dikatakan API pembatalan :

Hapus semua alarm dengan Intent yang cocok. Alarm apa pun, jenis apa pun, yang Intentnya cocok dengan alarm ini (sebagaimana ditentukan oleh filterEquals (Intent)), akan dibatalkan.

melihat " filterEquals ", dokumentasinya mengatakan:

Tentukan apakah dua maksud sama untuk tujuan resolusi maksud (pemfilteran). Artinya, jika tindakan, data, jenis, kelas, dan kategorinya sama. Ini tidak membandingkan data tambahan apa pun yang disertakan dalam maksud.

jadi saya tidak mengerti untuk apa "requestCode" ...

Pertanyaan:

Untuk apa "requestCode" digunakan?

Bagaimana jika saya membuat beberapa alarm dengan "requestCode" yang sama? apakah mereka saling menimpa?

pengembang android
sumber
jika Anda menggunakan requestCode yang sama, Anda akan mendapatkan PendingIntent yang sama
pskink
3
Untuk PendingIntent.getBroadcast (), requestCode tampaknya diabaikan oleh Android. Mulai API 22, itu tidak akan menjadikan Pending Intent Anda unik. Apakah untuk getActivity () (dan mungkin getService () tetapi saya belum menguji). stackoverflow.com/a/33203752/2301224
Tukang roti
@Baker Bukankah ini dianggap bug? Jika ini adalah bug, Anda harus menuliskannya di sini: code.google.com/p/android/issues/list
pengembang android
1
Sebenarnya, dokumentasi menentukan usaga dari requestiCode: If you truly need multiple distinct PendingIntent objects active at the same time (such as to use as two notifications that are both shown at the same time), then you will need to ensure there is something that is different about them to associate them with different PendingIntents. This may be any of the Intent attributes considered by Intent#filterEquals(Intent), or different request code integers supplied.
Eir
@Eir Benar, jadi apa gunanya menggunakan requestCode? Dimana bisa digunakan?
Pengembang android

Jawaban:

77
  1. requestCode digunakan untuk mengambil instance maksud tertunda yang sama nanti (untuk membatalkan, dll).
  2. Ya, tebakan saya adalah alarm akan menimpa satu sama lain. Saya akan membuat kode permintaan tetap unik.
Minhaj Arfin
sumber
5
apakah menyetel requestCode menjadi unik diperlukan bahkan jika maksud alarm sangat berbeda (satu untuk layanan A dan satu untuk layanan B, misalnya)? Juga, kenapa dokumentasinya tidak mengatakan apapun tentang itu? Apakah mungkin untuk menghapus semua alarm dari jenis tertentu, apa pun kode permintaannya?
Pengembang android
1
Tidak, Ini tidak perlu untuk maksud yang berbeda. Dan saya tidak tahu mengapa dokumentasi tidak mengatakan apa-apa tentang itu, tapi saya mempelajarinya saat menyetel alarm berulang dan juga saat menggunakan maksud yang sama.
Minhaj Arfin
2
Saya berbicara tentang PendingIntent. startActivityForResult menggunakan maksud normal.
Pengembang android
2
apa tujuan dari "startActivityForResult dengan PendingIntent menggunakan aktivitas proxy"? dapatkah anda memberi contoh?
Pengembang android
3
Saya setuju; dokumentasi untuk PendingIntent dan AlarmManager benar-benar buruk - diperburuk oleh fakta bahwa tidak mungkin untuk membuat daftar alarm secara terprogram.
Seseorang di suatu tempat pada
33

Saya hanya ingin menambahkan jawaban @Minhaj Arfin

1- requestCode digunakan untuk mendapatkan maksud tertunda yang sama nanti (untuk membatalkan, dll)

2- Ya, mereka akan menimpa selama Anda menentukan Penerima yang sama dengan Maksud Anda yang Anda tentukan di PendingIntent Anda

contoh:

Intent startIntent1 = new Intent(context, AlarmReceiverFirst.class);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, startIntent1, 0);

Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, 0);

Dari contoh di atas, mereka tidak akan menimpa satu sama lain karena penerima berbeda (AlarmReceiverFirst dan AlarmReceiverSecond)

Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, 0);

Intent startIntent3 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent3 = PendingIntent.getBroadcast(context, 0, startIntent3, 0);

Dari contoh di atas, mereka akan saling menimpa, karena penerima sama (AlarmReceiverSecond)

HendraWD
sumber
Maksud startIntent4 = Maksud baru (konteks, AlarmReceiverSecond.class); PendingIntent pendingIntent4 = PendingIntent.getService (konteks, 0, startIntent4, 0); akan baik-baik saja? Maksud saya, bukankah ini akan menimpa karena memanggil getService () dan bukan getBroadcast ()?
Jenix
Maaf untuk menanyakan pertanyaan lain tetapi karena stackoverflow tidak mengizinkan saya untuk menulis pertanyaan tanpa satu baris kode .. Bukankah argumen terakhir dari metode PendingIntent seperti getBroadcast () ada hubungannya dengan overriding? Saya biasa meletakkan 0 di sana seperti kode contoh Anda di atas, tetapi saya juga melihat banyak orang meletakkan beberapa nilai opsi tertentu alih-alih 0.
Jenix
1
@Jenix Anda gunakan AlarmReceiverSecond.classpada maksud dan kemudian gunakan PendingIntent.getService(). Ini tidak akan berhasil, karena AlarmReceiverSecond.classadalah BroadcastReceiver, bukanService
HendraWD
1
Tentang flag, ini adalah properti yang bisa Anda setel, yang akan membuat perilaku PendingIntent Anda sesuai dengan flag yang Anda berikan. 0 berarti semua bendera dimatikan
HendraWD
Ah saya bodoh haha ​​Apa yang sedang saya pikirkan .. Saya sedikit bingung tentang PendingIntent dan jawaban Anda sangat membantu. Dan saya hanya ingin membuatnya lebih jelas tetapi sekarang saya menyadari pertanyaan saya awalnya tidak masuk akal. Terima kasih!
Jenix
2

dalam kasus saya, saya ingin membuka aktivitas yang sama dengan dua maksud yang berbeda jadi jika dua atau lebih FCMS ada di baki, salah satu dari mereka hanya akan membuka yang lain tidak, jadi saya mengubah kode permintaan dari maksud tertunda kemudian berhasil.

 PendingIntent pendingIntent =
                            PendingIntent.getActivity(this, **Some unique id for all GCMS** /* Request code */, intent,
                                    PendingIntent.FLAG_ONE_SHOT);
JSONParser
sumber
tidak perlu memeriksa kode lebih lanjut untuk kasus saya, dapatkah Anda memberi tahu dalam hal apa contoh maksud yang tertunda akan diperlukan. Sehubungan dengan pertanyaan mengubah kode permintaan membantu saya membuka layar yang benar, saya tidak tahu apakah ini cara yang benar dan bagi saya kesalahan hanya terjadi ketika beberapa FCM ada di baki
JSONParser
Jadi mengapa menetapkan kode permintaan yang berbeda, jika Anda tidak membutuhkannya?
Pengembang android
ok saya akan menjelaskan secara rinci, saya punya beberapa KEGIATAN A, itu dimaksudkan untuk menunjukkan pertanyaan saya akan meneruskan id dari pemberitahuan melalui maksud dan kemudian membuat permintaan jaringan untuk id itu dan mengambil pertanyaan tertentu, jadi apa yang terjadi ketika itu Ada lebih dari 1 pemberitahuan di baki pemberitahuan dan kemudian saya klik salah satu dari mereka saya mendapatkan id pertanyaan yang ada di GCM pertama, setelah mengubah kode permintaan maksud yang tertunda ke beberapa nilai unik itu berhasil. Saya harap saya menjelaskannya sekarang, jika ada diskusi lagi yang diperlukan, saya di sana, saya juga ingin mempelajari lebih lanjut, terima kasih
JSONParser
Oh maksudmu kalau tidak itu tidak akan berhasil sama sekali, kan? Maaf atas kebingungannya. Pertanyaan ini sudah lama ditanyakan dan saya sama sekali tidak mengingatnya dengan baik ...
pengembang android
1

satu hal penting tentang requestCodeitu yang akan sangat mengganggu aplikasi Anda adalah saat menggunakan widget. widget tidak akan berfungsi setelah ponsel di-boot ulang jika requestCodekeduanya sama. itu berarti yang pendingIndentAnda setel di remoteViewswidget Anda harus disetel ke requestCode unik, biasanya widgetId yang menyertai angka.

Alireza Jamali
sumber
0

Sebenarnya, dokumentasi dengan jelas menyatakan untuk apa kode permintaan digunakan:

Jika Anda benar-benar membutuhkan beberapa objek PendingIntent berbeda yang aktif pada saat yang sama (seperti untuk digunakan sebagai dua notifikasi yang keduanya ditampilkan pada saat yang sama), maka Anda perlu memastikan ada sesuatu yang berbeda pada objek tersebut untuk mengaitkannya dengan yang berbeda. PendingIntents. Ini bisa berupa salah satu atribut Intent yang dipertimbangkan oleh Intent # filterEquals (Intent), atau integer kode permintaan berbeda yang diberikan ke getActivity (Context, int, Intent, int), getActivities (Context, int, Intent [], int), getBroadcast ( Context, int, Intent, int), atau getService (Context, int, Intent, int).

Karena sepertinya masih belum begitu jelas, izinkan saya mencoba menjelaskan:

Saat Anda ingin menggunakan sebuah PendingIntentobjek, Anda tidak hanya membuat satu. Sebaliknya, Anda memperoleh satu dari sistem dengan menggunakan PendingIntentmetode statis ( getActivity, getBroadcast, getServicedll). Sistem menyimpan banyak instance PendingIntent dan memberi Anda satu. Yang mana yang diberikannya kepada Anda, itu tergantung pada parameter input yang Anda berikan ke metode pengambil ini. Parameter masukan tersebut adalah Context:, yaitu penerima target maksud, yang Intentakan digunakan, requestCodedan flags. Saat Anda meneruskan Intent yang sama Context, sama , requestCodedan sama (artinya maksud itu filterEqualsdengan maksud lain), Anda mendapatkan PendingIntentobjek yang sama . Intinya adalah bahwa sistem ingin memiliki PendingIntentobjek sesedikit mungkin, sehingga cenderung menggunakan kembali objek yang sudah ada, sebanyak mungkin.

Misalnya, Anda memiliki dua notifikasi kalender, untuk dua tanggal berbeda. Saat Anda mengeklik salah satunya, Anda ingin aplikasi Anda terbuka ke tanggal yang sesuai dari pemberitahuan itu. Dalam skenario itu, Anda memiliki Contexttarget yang sama , dan Intentobjek yang Anda lewati hanya berbeda dalam EXTRA_DATA (yang menentukan tanggal buka). Jika Anda memberikan hal yang sama requestCodesaat mendapatkan PendingIntentobjek, maka Anda akan mendapatkan PendingIntentobjek yang sama . Jadi, saat membuat notifikasi kedua, Anda akan mengganti Intentobjek lama dengan EXTRA_DATA baru, dan berakhir dengan dua notifikasi yang mengarah ke tanggal yang sama.

Jika Anda ingin memiliki dua PendingIntentobjek yang berbeda , seperti yang seharusnya dalam skenario ini, Anda harus menentukan objek yang berbeda requestCodesaat mendapatkan PendingIntentobjek.

Eir
sumber
Tapi seperti yang saya sebutkan, untuk membatalkan alarm, Anda tidak bisa hanya menggunakan requestCode. Itu tidak berarti apa-apa untuk itu. Anda harus memasukkan data tambahan untuk membedakannya. Saya tidak ingat tetapi saya pikir Anda bahkan dapat menggunakan requestCode yang sama untuk beberapa alarm.
Pengembang android
@androiddeveloper yang baru saja Anda katakan salah. Cobalah.
Eir