PendingIntent'te "requestCode" ne için kullanılıyor?


111

Arka fon:

AlarmManager aracılığıyla alarmlar için PendingIntent kullanıyorum.

Sorun:

İlk başta, öncekileri iptal etmek için, alarmı başlatmak için daha önce kullandığım tam requestCode'u sağlamam gerektiğini düşündüm.

Ama sonra iptal API'sinin dediği gibi yanıldığımı anladım :

Eşleşen bir Amacı olan tüm alarmları kaldırın. Amacı bununla eşleşen herhangi bir tür alarm (filterEquals (Amaç) ile tanımlandığı gibi) iptal edilecektir.

" filterEquals " a bakıldığında , dokümantasyon şunu söylüyor:

Amaç çözümleme (filtreleme) açısından iki amacın aynı olup olmadığını belirleyin. Yani eylemleri, verileri, türü, sınıfı ve kategorileri aynıysa. Bu, amaçlara dahil edilen ekstra verileri karşılaştırmaz.

bu yüzden "requestCode" un ne için olduğunu anlamıyorum ...

Soru:

"RequestCode" ne için kullanılır?

Aynı "requestCode" ile birden fazla alarm oluşturursam ne olur? birbirlerini geçersiz kılıyorlar mı?


aynı requestCode'u kullanırsanız, aynı PendingIntent
pskink

3
PendingIntent.getBroadcast () için, requestCode görünüşe göre Android tarafından yok sayılıyor. API 22'den itibaren, Bekleyen Niyetinizi benzersiz kılmayacaktır. GetActivity () için (ve belki getService () ama test etmedim). stackoverflow.com/a/33203752/2301224
Baker

@Baker Bu bir hata sayılmaz mı? Hata ise, buraya yazmalısınız: code.google.com/p/android/issues/list
android geliştiricisi

1
Aslında, dokümantasyon requestiCode'un kullanım amacını belirtiyor: 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 Doğru, öyleyse requestCode'u kullanmanın anlamı nedir? Nerelerde kullanılabilir?
android geliştiricisi

Yanıtlar:


77
  1. requestCode daha sonra aynı bekleyen niyet örneğini almak için kullanılır (iptal etme vb. için).
  2. Evet, tahminimce alarmlar birbirini geçersiz kılacak. İstek kodlarını benzersiz tutardım.

5
Alarmların amaçlarının çok farklı olması durumunda bile requestCode'u benzersiz olacak şekilde ayarlamak mı (örneğin biri A hizmeti ve diğeri hizmet B için)? Ayrıca, belgeler neden bu konuda hiçbir şey söylemiyor? RequestCode ne olursa olsun, belirli bir türdeki tüm alarmları kaldırmak mümkün müdür?
android geliştiricisi

1
Hayır, farklı niyetler için gerekli değildir. Dokümantasyonun neden bu konuda hiçbir şey söylemediğini bilmiyorum ama bunu tekrar eden alarmları ayarlarken ve aynı amacı kullanırken de öğrendim.
Minhaj Arfin

2
PendingIntent hakkında konuşuyordum. startActivityForResult normal bir amaç kullanır.
android geliştiricisi

2
"bir proxy etkinliği kullanarak PendingIntent ile startActivityForResult" un amacı nedir? bir örnek verebilir misin?
android geliştiricisi

3
Katılıyorum; PendingIntent ve AlarmManager için dokümantasyon, alarmları programlı olarak listelemenin mümkün olmaması nedeniyle daha da kötüleştirildi.
Someone Somewhere

33

@Minhaj Arfin cevabına sadece eklemek istiyorum

1- requestCode aynı bekleyen niyeti daha sonra elde etmek için kullanılır (iptal vb. İçin)

2- Evet, PendingIntent'inizde belirttiğiniz Amaç için aynı Alıcıyı belirttiğiniz sürece geçersiz kılınırlar.

misal:

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);

Yukarıdaki örnekte, onlar olmaz birbirlerini geçersiz alıcı farklı olduğu için, (AlarmReceiverFirst ve 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);

Yukarıdaki örnekte, onlar olacak , birbirlerine geçersiz alıcı aynı olduğu için (AlarmReceiverSecond)


Amaç startIntent4 = yeni Amaç (bağlam, AlarmReceiverSecond.class); PendingIntent pendingIntent4 = PendingIntent.getService (bağlam, 0, startIntent4, 0); o zaman olur mu? Demek istediğim, bu geçersiz kılma çünkü getBroadcast () yerine getService () çağırıyor mu?
Jenix

Başka bir soru sorduğum için üzgünüm ama stackoverflow tek bir kod satırı olmadan soru yazmama izin vermediği için .. PendingIntent'in getBroadcast () gibi yöntemlerinin son argümanının geçersiz kılma ile ilgisi yok mu? Yukarıdaki örnek kodunuz gibi oraya 0 koyardım ama aynı zamanda birçok kişinin 0 yerine belirli bir seçenek değeri koyduğunu da gördüm.
Jenix

1
@Jenix u AlarmReceiverSecond.classniyetinde kullanıyorsun ve sonra kullan PendingIntent.getService(). İşe yaramayacak, çünkü AlarmReceiverSecond.classa BroadcastReceiverdeğilService
HendraWD

1
Bayraklar hakkında, PendingIntent'inizin davranışını sağladığınız bayraklara göre yapacak olan, ayarlayabileceğiniz özelliklerdir. 0 tüm bayraklar kapalı demektir
HendraWD

Ah aptaldım haha ​​Ne düşünüyordum ki .. PendingIntent hakkında biraz kafam karıştı ve cevabınız gerçekten yardımcı oldu. Ve sadece daha açık hale getirmek istedim ama şimdi sorumun ilk başta mantıklı olmadığını anladım. Teşekkürler!
Jenix

2

benim durumumda aynı etkinliği iki farklı amaçla açmak istiyorum, bu nedenle tepside iki veya daha fazla FCMS varsa, bunlardan herhangi biri yalnızca açacak, diğeri açmayacak, bu yüzden bekleyen niyetin istek kodlarını değiştirdim, sonra çalıştı.

 PendingIntent pendingIntent =
                            PendingIntent.getActivity(this, **Some unique id for all GCMS** /* Request code */, intent,
                                    PendingIntent.FLAG_ONE_SHOT);

Benim durumum için kodu daha fazla kontrol etmeye gerek yoktu, hangi durumda bekleyen niyet örneğinin gerekli olacağını söyleyebilir misiniz? Soru değiştirme isteği koduyla ilgili olarak, doğru ekrana
gitmeme

Öyleyse, ihtiyacınız yoksa neden farklı bir istek kodu ayarlayasınız?
android geliştiricisi

tamam ayrıntılı olarak açıklayacağım, biraz AKTİVİTE A vardı, soruları göstermek için bildirimlerden kimliği ileteceğim ve sonra bu kimlik için bir ağ isteği yapacağım ve belirli soruyu getireceğim, o zaman orada ne oluyordu bildirim tepsisinde 1'den fazla bildirim var ve sonra, bekleyen niyet istek kodunu çalıştığı benzersiz bir değere değiştirdikten sonra, ilk GCM'deki soru kimliğini aldığım herhangi birine tıklıyorum. Umarım şimdi netleştirmişimdir, eğer daha fazla tartışma gerekirse oradayım, ayrıca daha fazlasını öğrenmek istiyorum, teşekkür ederim
JSONParser

Oh, yoksa hiç işe yaramayacağını kastettin, değil mi? Karışıklık için üzgünüm. Bu soru uzun zaman önce sorulmuştu ve hiç de iyi hatırlamıyorum ...
android geliştiricisi

1

requestCodeBununla ilgili olarak uygulamanızı ciddi şekilde rahatsız edecek önemli bir şey , widget'ları kullanırken. widget'lar requestCodeaynıysa telefon yeniden başlatıldıktan sonra çalışmaz . araçlarının pendingIndentüzerinde ayarlanmış remoteViewsWidget ayarlanması gerekir eşsiz requestCode, genellikle widgetId bir numara eşlik.


0

Aslında, belgeler istek kodunun ne için kullanıldığını açıkça belirtir:

Aynı anda aktif olan birden fazla farklı PendingIntent nesnesine gerçekten ihtiyacınız varsa (örneğin, her ikisi de aynı anda gösterilen iki bildirim olarak kullanmak gibi), onları farklı PendingIntents. Bu, Intent # filterEquals (Intent) tarafından değerlendirilen herhangi bir Intent özniteliği veya getActivity (Context, int, Intent, int), getActivities (Context, int, Intent [], int), getBroadcast ( Context, intent, Intent, int) veya getService (Context, int, Intent, int).

Görünüşe göre hala o kadar net değil, açıklamaya çalışayım:

Bir PendingIntentnesneyi kullanmak istediğinizde , sadece bir tanesini somutlaştırmazsınız. Aksine, kullandığınız sistemden birini elde PendingIntentstatik yöntemler ( getActivity, getBroadcast, getServicevs). Sistem bir grup PendingIntent örneğini tutar ve size bir tane verir. Size hangisini verdiği, bu alıcı yöntemlerine ilettiğiniz girdi parametrelerine bağlıdır. Bu girdi parametreleri şunlardır: Contextyani, amacın hedef alıcısı, Intentkullanılacak requestCodeve flags. Aynı Context, aynı requestCodeve aynı Niyeti ilettiğinizde ( filterEqualsbaşka bir niyetle bir niyet anlamına gelir ), aynı PendingIntentnesneyi elde edersiniz . Mesele şu ki, sistem PendingIntentmümkün olduğunca az nesneye sahip olmak istiyor , bu nedenle mevcut olanları olabildiğince yeniden kullanma eğiliminde.

Örneğin, iki farklı tarih için iki takvim bildiriminiz var. Bunlardan birine tıkladığınızda, uygulamanızın o bildirimin ilgili tarihine açılmasını istersiniz. Bu senaryoda, aynı Contexthedefe Intentsahipsiniz ve geçtiğiniz nesne yalnızca EXTRA_DATA'da farklılık gösterir (bu, açılması gereken tarihi belirtir). Nesneyi requestCodeelde ederken aynı şeyi sağlarsanız PendingIntent, o zaman aynı nesne elde edersiniz PendingIntent. Dolayısıyla, ikinci bildirimi oluştururken, eski Intentnesneyi yeni EXTRA_DATA ile değiştirecek ve aynı tarihi gösteren iki bildirimle son bulacaksınız.

PendingIntentBu senaryoda olması gerektiği gibi iki farklı nesneye sahip olmak istiyorsanız requestCode, PendingIntentnesneyi elde ederken farklı bir nesne belirlemelisiniz.


Ancak bahsettiğim gibi, alarmları iptal etmek için sadece requestCode'u kullanamazsınız. Bunun hiçbir anlamı yok. Aralarında ayrım yapmak için fazladan veri eklemeniz gerekecek. Hatırlamıyorum ama sanırım birden fazla alarm için aynı requestCode'u bile kullanabilirsiniz.
android geliştiricisi

@androiddeveloper az önce söyledikleriniz yanlış. Dene.
Eir
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.