การแจ้งเตือนผ่าน Intent Extras แบบเก่า


135

ฉันกำลังสร้างการแจ้งเตือนภายใน BroadcastReceiver ผ่านรหัสนี้:

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

เมื่อฉันคลิกที่การแจ้งเตือนจะเปิด NotificationActivity และภายในกิจกรรมฉันสามารถดึง foo_id จาก Intent-Bundle (เช่น 1)

อย่างไรก็ตามหากมีการเรียกใช้การแจ้งเตือนอื่นและฉันคลิกอีกครั้งกิจกรรมจะยังคงได้รับค่า "เก่า" (1) จาก Intent-Bundle ฉันพยายามล้างบันเดิลด้วย clear () แต่ก็ได้รับผลเช่นเดียวกัน ฉันคิดว่า sth ผิดกับรหัสของฉัน ..


โปรดบอกฉันได้ไหมว่าคุณจะได้รับข้อมูลจากเจตนาที่รอดำเนินการได้อย่างไร
user49557

เมื่อรู้ว่ามันกำลังส่งของแถมเก่าทำให้การทดลองของฉันง่ายขึ้น
Utsav Gupta

คำตอบ:


270

คุณกำลังส่งรหัสคำขอเดียวกันสำหรับการเร่งรัดที่รอดำเนินการของคุณ เปลี่ยนสิ่งนี้:

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

ถึง:

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

ความตั้งใจจะไม่ถูกสร้างขึ้นหากคุณส่งพารามิเตอร์เดียวกัน นำกลับมาใช้ใหม่


1
ดังนั้น UNIQUE_INT_PER_CALL คือจำนวนเต็มที่ฉันต้องระบุ? หรือนี่คือตัวแปรคงที่ประกาศที่ไหนสักแห่ง?
BrianM

23
android gotcha # 147 - ดังนั้นสิ่งIntentที่มีความพิเศษที่แตกต่างกัน (ผ่านputExtra) จะถูกพิจารณาว่าเหมือนกันและใช้ซ้ำเพราะฉันไม่ได้ให้ ID เฉพาะสำหรับการโทรตามเจตนาที่รอดำเนินการ - api แย่
วอล

คุณรู้อะไรฉันประมาทมาก แค่คิดว่ามันจะเหลือ 0 ในหนึ่งบล็อกได้อย่างไร (ในกรณีของฉัน) :(
Exigente05

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

1
@IncrediApp เหมือนกันกับ PendingIntent.getBroadcast (); เหรอ?
ชรูติ

140

หรือคุณสามารถใช้รหัสต่อไปนี้เพื่อสร้าง PendingIntent ของคุณ:

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

จากเอกสารสำหรับPendingIntent.FLAG_UPDATE_CURRENT:

หาก PendingIntent ที่อธิบายไว้มีอยู่แล้วให้เก็บไว้ แต่แทนที่ข้อมูลพิเศษด้วยข้อมูลที่อยู่ใน Intent ใหม่นี้ สิ่งนี้สามารถใช้ได้หากคุณกำลังสร้าง Intent โดยเฉพาะส่วนเสริมเท่านั้นที่เปลี่ยนแปลงและไม่สนใจว่าเอนทิตีใด ๆ ที่ได้รับ PendingIntent ก่อนหน้านี้ของคุณจะสามารถเปิดใช้งานพร้อมกับสิ่งพิเศษใหม่ของคุณได้แม้ว่าจะไม่ได้ระบุไว้อย่างชัดเจนก็ตาม


ขอบคุณ ... ทำงานอย่างสมบูรณ์แบบสำหรับแฟล็กนี้ซึ่งเพิ่ม "PendingIntent.FLAG_UPDATE_CURRENT" :)
Najib Ahmed Puthawala

1
ทำงานให้ฉันโดยใช้ความตั้งใจที่รอดำเนินการเพื่อโอนสถานะจากการตั้งปลุกไปยังเครื่องรับสัญญาณ
William T. Mallard

ฉันแค่หวังว่าฉันจะรู้ว่าการตั้งค่าสถานะเหล่านี้ทำอะไรได้บ้างก่อนที่ฉันจะส่งการแจ้งเตือนไปยังผู้ใช้ของฉัน (!) ดีใจที่สิ่งนี้ช่วยแก้ไขปัญหาของฉันได้ ...
James Andrew

42

คุณกำลังส่งรหัสเดียวกัน ในสถานการณ์เช่นนี้ให้สร้างรหัสเฉพาะเป็นครั้งคราวดังนี้:

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

และวางไว้ดังนี้:

PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),iUniqueId, intentForNotification, 0);

3
ทำไมไม่ใช้ Random () ใหม่ nextInt ()
exloong

@hderanga การเพิ่ม "& 0xfffffff" ใน int ด้านบนทำอะไรได้บ้าง
AJW

3
@AJW System.currentTimeMillis()คืนค่า long ในขณะที่requestIdพารามิเตอร์ของPendingIntent.getActivity()รับ int 0xffffffffเป็นบิตมาสก์ แม้ว่าจะมีอะไรมากกว่านั้นคำอธิบายง่ายๆก็คือการทำ `` long & 0xffffffff '' ให้ 32 บิตต่ำสุดจาก long และทิ้ง 32 บิตสูงสุดทำให้คุณมี int 32 บิตเป็นหลัก สิ่งนี้ดีกว่าการแคสต์เป็น int เพียงอย่างเดียวเพราะมันจะไม่ทำให้บิตเครื่องหมายยุ่งเหยิง (ถ้าคุณร่ายยาวที่ใหญ่กว่า int ถึง int บิตเครื่องหมายจะล้นและคุณอาจจะปิดด้วยค่าลบ )
Jordan Bondo

8

สำหรับใครก็ตามที่กำลังมองหาแนวทางที่ดีที่สุดหลังจากผ่านไปนานคุณจะต้องส่งPendingIntent.FLAG_UPDATE_CURRENTเป็นอาร์กิวเมนต์สุดท้ายดังที่แสดงด้านล่าง

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

คุณไม่จำเป็นต้องระบุรหัสเฉพาะใหม่

คุณต้องทำในครั้งต่อไปไม่ใช่ครั้งแรก


1
นั่นไม่ได้ผลฉันมาที่นี่เพราะนั่นคือสิ่งที่ฉันทำ
Brill Pappin

คุณต้องทำครั้งต่อไปไม่ใช่ครั้งแรกก็จะได้ผล
อ่อนโยน

0

รหัสคำขอของคุณคือ 0 สำหรับการแจ้งเตือนทั้งหมด เปลี่ยนบรรทัดต่อไปนี้:

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

ด้วย:

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

1
มีประโยชน์ในการใช้ "new Random (). nextInt ()" มากกว่า "System.currentTimeMillis ()" หรือไม่?
AJW

การใช้การสุ่มสามารถสร้างค่าจำนวนเต็มเดียวกันอีกครั้งได้อย่างง่ายดายโดยไม่ได้ตั้งใจดังนั้นจึงทำให้ยากต่อการค้นหาข้อผิดพลาดของ Intent เก่าที่ถูกส่งผ่าน
แซม

@AJW มีในกรณีของฉัน ฉันสร้างการแจ้งเตือน 2 รายการที่แตกต่างกันในมิลลิวินาทีเดียวกันดังนั้นหนึ่งในนั้นจึงมีความพิเศษที่ไม่ถูกต้อง
ช่างศิลป์

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