“ requestCode” ใช้สำหรับอะไรใน PendingIntent


111

พื้นหลัง:

ฉันใช้ PendingIntent สำหรับการเตือนผ่าน AlarmManager

ปัญหา:

ตอนแรกฉันคิดว่าในการยกเลิกอันก่อนหน้านี้ฉันต้องระบุ requestCode ที่แน่นอนที่ฉันเคยใช้มาก่อนเพื่อเริ่มการปลุก

แต่แล้วฉันก็พบว่าฉันคิดผิดตามที่API การยกเลิกบอก:

ลบสัญญาณเตือนใด ๆ ที่มีเจตนาที่ตรงกัน การเตือนภัยไม่ว่าประเภทใดก็ตามที่มี Intent ตรงกับการเตือนนี้ (ตามที่กำหนดโดย filterEquals (Intent)) จะถูกยกเลิก

ดูที่ " filterEquals " เอกสารระบุว่า:

ตรวจสอบว่าเจตนาสองอย่างเหมือนกันสำหรับวัตถุประสงค์ของการแก้ไขเจตนา (การกรอง) หรือไม่ นั่นคือถ้าการกระทำข้อมูลประเภทคลาสและหมวดหมู่เหมือนกัน ข้อมูลนี้ไม่ได้เปรียบเทียบข้อมูลเพิ่มเติมใด ๆ ที่รวมอยู่ใน Intent

เลยไม่เข้าใจว่า "requestCode" มีไว้เพื่ออะไร ...

คำถาม:

"requestCode" ใช้ทำอะไร

จะเกิดอะไรขึ้นถ้าฉันสร้างการเตือนภัยหลายรายการโดยใช้ "requestCode" เดียวกัน พวกเขาลบล้างกันและกัน?


หากคุณใช้ requestCode เดียวกันคุณจะได้รับ PendingIntent เดียวกัน
pskink

3
สำหรับ PendingIntent.getBroadcast () ดูเหมือนว่า requestCode จะถูกละเว้นโดย Android ใน API 22 จะไม่ทำให้เจตนาที่รอดำเนินการของคุณไม่เหมือนใคร ใช้สำหรับ getActivity () (และอาจจะ getService () แต่ฉันยังไม่ได้ทดสอบ) stackoverflow.com/a/33203752/2301224
Baker

@Baker นี่ไม่ถือว่าเป็นบั๊กเหรอ? หากเป็นข้อบกพร่องคุณควรเขียนเกี่ยวกับเรื่องนี้ที่นี่: code.google.com/p/android/issues/list
นักพัฒนา Android

1
ที่จริงเอกสารระบุ usaga ของ 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 Right ดังนั้นประเด็นในการใช้ requestCode คืออะไร? สามารถใช้ได้ที่ไหน?
นักพัฒนา Android

คำตอบ:


77
  1. requestCode ใช้เพื่อดึงข้อมูลอินสแตนซ์เจตนาที่รอดำเนินการเดียวกันในภายหลัง (สำหรับการยกเลิก ฯลฯ )
  2. ใช่ฉันเดาว่าสัญญาณเตือนจะลบล้างกันและกัน ฉันจะเก็บรหัสคำขอที่ไม่ซ้ำกัน

5
กำลังตั้งค่า requestCode ให้ไม่ซ้ำกันซึ่งจำเป็นแม้ในกรณีที่ Intent ของการเตือนภัยแตกต่างกันมาก (ตัวอย่างหนึ่งสำหรับบริการ A และอีกรายการสำหรับ Service B เป็นต้น)? นอกจากนี้เอกสารประกอบทำไมไม่พูดอะไรเกี่ยวกับเรื่องนี้? เป็นไปได้หรือไม่ที่จะลบสัญญาณเตือนประเภทใดประเภทหนึ่งออกไม่ว่า requestCode จะเป็นอย่างไร
นักพัฒนา Android

1
ไม่จำเป็นสำหรับเจตนาที่แตกต่างกัน และฉันไม่รู้ว่าทำไมเอกสารถึงไม่พูดอะไรเกี่ยวกับเรื่องนี้ แต่ฉันได้เรียนรู้สิ่งนี้เมื่อตั้งค่าการปลุกซ้ำและเมื่อใช้จุดประสงค์เดียวกัน
Minhaj Arfin

2
ฉันกำลังพูดถึง PendingIntent startActivityForResult ใช้เจตนาปกติ
นักพัฒนา Android

2
จุดประสงค์ของ "startActivityForResult กับ PendingIntent โดยใช้กิจกรรมพร็อกซี" คืออะไร ช่วยยกตัวอย่างได้ไหม
นักพัฒนา Android

3
ฉันเห็นด้วย; เอกสารสำหรับ PendingIntent และ AlarmManager มีทั้งหมด sh! t - แย่ลงเนื่องจากการที่ไม่สามารถแสดงรายการสัญญาณเตือนโดยใช้โปรแกรมได้
ใครสักคน

34

ฉันแค่ต้องการเพิ่มคำตอบของ @Minhaj Arfin

1- requestCode ใช้เพื่อรับเจตนาที่รอดำเนินการเดียวกันในภายหลัง (สำหรับการยกเลิก ฯลฯ )

2- ใช่พวกเขาจะถูกแทนที่ตราบเท่าที่คุณระบุผู้รับเดียวกันกับเจตนาของคุณที่คุณระบุไว้ใน PendingIntent ของคุณ

ตัวอย่าง:

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

จากตัวอย่างข้างต้นพวกเขาจะไม่ลบล้างซึ่งกันและกันเนื่องจากตัวรับสัญญาณต่างกัน (AlarmReceiverFirst และ 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);

จากตัวอย่างข้างต้นพวกเขาจะลบล้างซึ่งกันและกันเนื่องจากตัวรับสัญญาณเหมือนกัน (AlarmReceiverSecond)


Intent startIntent4 = เจตนาใหม่ (บริบท AlarmReceiverSecond.class); PendingIntent pendingIntent4 = PendingIntent.getService (บริบท 0, startIntent4, 0); จะเป็นไรไหม? ฉันหมายความว่าสิ่งนี้จะไม่แทนที่เพราะมันเรียก getService () แทนที่จะเป็น getBroadcast ()?
Jenix

ขออภัยที่ถามคำถามอื่น แต่เนื่องจาก stackoverflow ไม่อนุญาตให้เขียนคำถามโดยไม่มีบรรทัดรหัสเดียว .. อาร์กิวเมนต์สุดท้ายของวิธีการ PendingIntent เช่น getBroadcast () ไม่เกี่ยวข้องกับการลบล้างหรือไม่? ฉันเคยใส่ 0 ไว้ที่นั่นเหมือนกับโค้ดตัวอย่างของคุณด้านบน แต่ฉันก็เห็นหลายคนใส่ค่าตัวเลือกเฉพาะแทน 0
Jenix

1
@Jenix คุณใช้AlarmReceiverSecond.classตามเจตนาแล้วใช้PendingIntent.getService(). มันจะไม่ทำงานเนื่องจากAlarmReceiverSecond.classเป็น a BroadcastReceiverไม่ใช่Service
HendraWD

1
เกี่ยวกับแฟล็กเป็นคุณสมบัติที่คุณสามารถตั้งค่าได้ซึ่งจะทำให้พฤติกรรมของ PendingIntent ของคุณเป็นไปตามแฟล็กที่คุณระบุ 0 หมายถึงการปิดธงทั้งหมด
HendraWD

อ่าฉันมันโง่ฮ่า ๆ ฉันคิดอะไรอยู่ในโลก .. ฉันสับสนเล็กน้อยเกี่ยวกับ PendingIntent และคำตอบของคุณก็เป็นประโยชน์จริงๆ และฉันแค่อยากจะทำให้ชัดเจนขึ้น แต่ตอนนี้ฉันตระหนักว่าคำถามของฉันไม่สมเหตุสมผลในตอนแรก ขอบคุณ!
Jenix

2

ในกรณีของฉันฉันต้องการเปิดกิจกรรมเดียวกันโดยมีเจตนาที่แตกต่างกันสองรายการดังนั้นหากมี FCMS สองรายการขึ้นไปในถาดรายการใดรายการหนึ่งจะเปิดเฉพาะรายการอื่นจะไม่เปิดดังนั้นฉันจึงเปลี่ยนรหัสคำขอที่มีเจตนาที่รอดำเนินการแล้วจึงใช้งานได้

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

ไม่จำเป็นต้องตรวจสอบรหัสเพิ่มเติมสำหรับกรณีของฉันคุณสามารถบอกได้ไหมว่าในกรณีนี้จะต้องมีอินสแตนซ์เจตนาที่รอดำเนินการ เกี่ยวกับคำถามที่เปลี่ยนรหัสคำขอช่วยให้ฉันไปที่หน้าจอที่ถูกต้องฉันไม่รู้ว่านี่เป็นวิธีที่ถูกต้องหรือไม่และสำหรับฉันข้อผิดพลาดเกิดขึ้นเฉพาะเมื่อมี FCM หลายตัวอยู่ในถาดเท่านั้น
JSONParser

เหตุใดจึงต้องตั้งรหัสคำขออื่นถ้าคุณไม่ต้องการ
นักพัฒนา Android

ตกลงฉันจะอธิบายรายละเอียดฉันมี ACTIVITY A มันหมายถึงการแสดงคำถามฉันจะส่งรหัสจากการแจ้งเตือนผ่านความตั้งใจจากนั้นทำการร้องขอเครือข่ายสำหรับ id นั้นและดึงคำถามเฉพาะดังนั้นสิ่งที่เกิดขึ้นเมื่ออยู่ที่นั่น มีการแจ้งเตือนมากกว่า 1 รายการในถาดการแจ้งเตือนจากนั้นฉันคลิกที่รายการใดรายการหนึ่งฉันได้รับรหัสคำถามซึ่งอยู่ใน GCM แรกหลังจากเปลี่ยนรหัสคำขอความตั้งใจที่รอดำเนินการเป็นค่าที่ไม่ซ้ำกันซึ่งได้ผล ฉันหวังว่าฉันจะทำให้มันชัดเจนในตอนนี้หากต้องการการสนทนาเพิ่มเติมฉันอยู่ที่นั่นฉันต้องการเรียนรู้เพิ่มเติมขอบคุณ
JSONParser

โอ้คุณหมายความว่าอย่างอื่นมันจะไม่ได้ผลเลยใช่ไหม? ขออภัยในความสับสน คำถามนี้ถูกถามเมื่อนานมาแล้วและฉันจำได้ไม่ดีเลย ...
นักพัฒนา android

1

สิ่งสำคัญอย่างหนึ่งrequestCodeที่จะทำให้แอปของคุณมีปัญหาอย่างมากคือเมื่อใช้วิดเจ็ต วิดเจ็ตจะไม่ทำงานหลังจากรีบูตโทรศัพท์หากrequestCodeเหมือนกัน นั่นหมายความว่าpendingIndentคุณตั้งค่าไว้บนremoteViewsวิดเจ็ตของคุณต้องตั้งค่า requestCode ที่ไม่ซ้ำกันโดยปกติจะเป็น widgetId ที่มาพร้อมกับตัวเลข


1

จริงๆแล้วเอกสารระบุชัดเจนว่าใช้รหัสคำขออะไร:

หากคุณต้องการใช้งานออบเจ็กต์ PendingIntent ที่แตกต่างกันหลายรายการพร้อมกันอย่างแท้จริง (เช่นใช้เป็นการแจ้งเตือนสองรายการที่แสดงพร้อมกัน) คุณจะต้องตรวจสอบให้แน่ใจว่ามีบางอย่างที่แตกต่างกันเกี่ยวกับวัตถุเหล่านี้เพื่อเชื่อมโยงกับวัตถุอื่น PendingIntents นี่อาจเป็นแอตทริบิวต์ Intent ใด ๆ ที่พิจารณาโดย Intent # filterEquals (Intent) หรือจำนวนเต็มรหัสคำขอที่แตกต่างกันที่ระบุให้กับ getActivity (Context, int, Intent, int), getActivities (Context, int, Intent [], int), getBroadcast ( Context, int, Intent, int) หรือ getService (Context, int, Intent, int)

เนื่องจากดูเหมือนว่าจะยังไม่ชัดเจนนักให้ฉันพยายามอธิบาย:

เมื่อคุณต้องการใช้PendingIntentออบเจ็กต์อย่าเพิ่งสร้างอินสแตนซ์วัตถุ แต่คุณได้รับหนึ่งจากระบบโดยใช้PendingIntentวิธีการแบบคง ( getActivity, getBroadcast, getServiceฯลฯ ) ระบบจะเก็บอินสแตนซ์ PendingIntent ไว้มากมายและให้หนึ่งอินสแตนซ์แก่คุณ สิ่งใดที่ให้คุณขึ้นอยู่กับพารามิเตอร์อินพุตที่คุณส่งผ่านไปยังวิธีการ getter เหล่านี้ ป้อนพารามิเตอร์เหล่านี้คือ: Contextคือรับเป้าหมายของเจตนาที่Intentจะใช้และrequestCode flagsเมื่อคุณผ่านสิ่งเดียวกันเจตนาContextเดียวกันrequestCodeและเหมือนกัน (หมายถึงเจตนาที่filterEqualsมีเจตนาอื่น) คุณจะได้รับPendingIntentวัตถุเดียวกัน ประเด็นคือระบบต้องการให้มีPendingIntentวัตถุน้อยที่สุดเท่าที่จะเป็นไปได้ดังนั้นจึงมีแนวโน้มที่จะนำวัตถุที่มีอยู่กลับมาใช้ใหม่ให้มากที่สุด

ตัวอย่างเช่นคุณมีการแจ้งเตือนในปฏิทินสองรายการสำหรับวันที่ต่างกันสองวัน เมื่อคุณคลิกที่หนึ่งในนั้นคุณต้องการให้แอปของคุณเปิดจนถึงวันที่ที่ตรงกันของการแจ้งเตือนนั้น ในสถานการณ์นั้นคุณมีContextเป้าหมายเดียวกันและIntentวัตถุที่คุณส่งผ่านจะแตกต่างกันเฉพาะใน EXTRA_DATA (ซึ่งระบุวันที่ที่ควรเปิด) หากคุณให้สิ่งเดียวกันrequestCodeเมื่อได้รับPendingIntentวัตถุคุณจะได้รับPendingIntentวัตถุเดียวกัน ดังนั้นเมื่อสร้างการแจ้งเตือนครั้งที่สองคุณจะแทนที่Intentวัตถุเก่าด้วย EXTRA_DATA ใหม่และจบลงด้วยการแจ้งเตือนสองรายการที่ชี้ไปที่วันที่เดียวกัน

หากคุณต้องการมีPendingIntentวัตถุสองชิ้นที่แตกต่างกันตามที่คุณควรจะเป็นในสถานการณ์นี้คุณควรระบุที่แตกต่างกันrequestCodeเมื่อได้รับPendingIntentวัตถุ


แต่อย่างที่ฉันได้กล่าวไปแล้วในการยกเลิกการเตือนคุณไม่สามารถใช้เพียง requestCode ได้ มันไม่มีความหมายอะไรสำหรับมัน คุณจะต้องใส่ข้อมูลเพิ่มเติมเพื่อแยกความแตกต่างระหว่างข้อมูลเหล่านี้ ฉันจำไม่ได้ แต่ฉันคิดว่าคุณสามารถใช้ requestCode เดียวกันสำหรับการเตือนหลายครั้งได้
นักพัฒนา Android

@androiddeveloper สิ่งที่คุณพูดไม่ถูกต้อง ลองมัน.
Eir
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.