วิธีส่งพารามิเตอร์จากการแจ้งเตือนคลิกไปยังกิจกรรมได้อย่างไร


206

ฉันสามารถหาวิธีส่งพารามิเตอร์ไปยังกิจกรรมของฉันได้จากการแจ้งเตือนของฉัน

ฉันมีบริการที่สร้างการแจ้งเตือน เมื่อผู้ใช้คลิกที่การแจ้งเตือนฉันต้องการเปิดกิจกรรมหลักของฉันด้วยพารามิเตอร์พิเศษบางอย่าง เช่นรหัสรายการดังนั้นกิจกรรมของฉันสามารถโหลดและนำเสนอมุมมองรายละเอียดรายการพิเศษ เจาะจงมากขึ้นฉันกำลังดาวน์โหลดไฟล์และเมื่อดาวน์โหลดไฟล์ฉันต้องการให้การแจ้งเตือนมีความตั้งใจที่เมื่อคลิกมันจะเปิดกิจกรรมของฉันในโหมดพิเศษ ฉันพยายามใช้putExtraตามความตั้งใจของฉันแล้ว แต่ดูเหมือนจะไม่สามารถดึงออกมาได้ดังนั้นฉันคิดว่าฉันทำผิด

รหัสจากบริการของฉันที่สร้างการแจ้งเตือน:

        // construct the Notification object.
     final Notification notif = new Notification(R.drawable.icon, tickerText, System.currentTimeMillis());


    final RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.custom_notification_layout);
    contentView.setImageViewResource(R.id.image, R.drawable.icon);
    contentView.setTextViewText(R.id.text, tickerText);
    contentView.setProgressBar(R.id.progress,100,0, false);
    notif.contentView = contentView;        

    Intent notificationIntent = new Intent(context, Main.class);
    notificationIntent.putExtra("item_id", "1001"); // <-- HERE I PUT THE EXTRA VALUE
    PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
    notif.contentIntent = contentIntent;

    nm.notify(id, notif);

รหัสจากกิจกรรมของฉันที่พยายามดึงพารามิเตอร์พิเศษจากการแจ้งเตือน:

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);


    Bundle extras = getIntent().getExtras();
    if(extras != null){
        Log.i( "dd","Extra:" + extras.getString("item_id") );
    }

ความพิเศษอยู่เสมอและฉันไม่เคยได้อะไรเลยในบันทึกของฉัน

แต่onCreateถ้ากิจกรรมของฉันเริ่มขึ้นถ้ากิจกรรมของฉันเริ่มขึ้นแล้วฉันยังต้องการรวบรวมสิ่งพิเศษและแสดงกิจกรรมของฉันตามรายการที่ฉันได้รับ

ความคิดใด ๆ

คำตอบ:


241

ดูคู่มือนี้ ( สร้างการแจ้งเตือน ) และตัวอย่าง ApiDemos "StatusBarNotifications" และ "NotificationDisplay"

สำหรับการจัดการว่ากิจกรรมกำลังทำงานอยู่คุณมีสองวิธี:

  1. เพิ่ม FLAG_ACTIVITY_SINGLE_TOPตั้งค่าสถานะเป็น Intent เมื่อเรียกใช้กิจกรรมจากนั้นในคลาสกิจกรรมจะใช้ ตัวจัดการเหตุการณ์onNewIntent (เจตนาเจตนา)ด้วยวิธีนี้คุณสามารถเข้าถึงเจตนาใหม่ที่ถูกเรียกใช้สำหรับกิจกรรม (ซึ่งไม่เหมือนกับการเรียก getIntent () สิ่งนี้จะส่งคืนเจตนาแรกที่เปิดตัวกิจกรรมของคุณเสมอ

  2. เหมือนกับหมายเลขหนึ่ง แต่แทนที่จะเพิ่มแฟล็กลงใน Intent คุณต้องเพิ่ม"singleTop"ในกิจกรรม AndroidManifest.xml ของคุณ

หากคุณใช้บริการเสริมโดยเจตนาโปรดโทรติดต่อPendingIntent.getActivity()ด้วยธงPendingIntent.FLAG_UPDATE_CURRENTมิฉะนั้นบริการเสริมอื่น ๆ จะถูกนำมาใช้ซ้ำสำหรับการแจ้งเตือนทุกครั้ง


95
และเพื่อตอบคำถามของผู้ใช้เกี่ยวกับความพิเศษเป็นโมฆะ: คุณต้องโทรหาPendingIntent.getActivity()ด้วยธงPendingIntent.FLAG_UPDATE_CURRENTมิฉะนั้นความพิเศษอื่น ๆ จะถูกนำมาใช้ซ้ำสำหรับการแจ้งเตือนทุกครั้ง
Matthias

2
ยูบันทึกวันของฉัน แต่ทำไมการถ่ายโอนข้อมูลที่เรียบง่ายเช่นนี้ซับซ้อนดังนั้นในหุ่นยนต์
อาร์กิวเมนต์ที่ผิดกฎหมาย

8
หากคุณควรจะมีการแจ้งเตือนที่แตกต่างกันให้แน่ใจว่าจะใช้รหัสคำขอที่แตกต่างกันเมื่อโทรPendingIntent.getActivity()นอกเหนือไปจากการตั้งค่าFLAG_ACTIVITY_SINGLE_TOPบนIntentและบนFLAG_UPDATE_CURRENT PendingIntentดูstackoverflow.com/questions/7370324/…
schnatterer

101

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

นี่คือรหัสที่แก้ไขสิ่งนี้ รหัสสำหรับการสร้างเจตนาการแจ้งเตือน

 Intent notificationIntent = new Intent(getApplicationContext(), viewmessage.class);
    notificationIntent.putExtra("NotificationMessage", notificationMessage);
    notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingNotificationIntent = PendingIntent.getActivity(getApplicationContext(),notificationIndex,notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT);
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    notification.setLatestEventInfo(getApplicationContext(), notificationTitle, notificationMessage, pendingNotificationIntent);

รหัสสำหรับดูกิจกรรมข้อความ

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    onNewIntent(getIntent());
}

@Override
public void onNewIntent(Intent intent){
    Bundle extras = intent.getExtras();
    if(extras != null){
        if(extras.containsKey("NotificationMessage"))
        {
            setContentView(R.layout.viewmain);
            // extract the extra-data in the Notification
            String msg = extras.getString("NotificationMessage");
            txtView = (TextView) findViewById(R.id.txtMessage);
            txtView.setText(msg);
        }
    }


}

29

อาจจะสายไปสักหน่อย แต่: แทนสิ่งนี้:

public void onNewIntent(Intent intent){
    Bundle extras = intent.getExtras();
    Log.i( "dbg","onNewIntent");

    if(extras != null){
        Log.i( "dbg", "Extra6 bool: "+ extras.containsKey("net.dbg.android.fjol"));
        Log.i( "dbg", "Extra6 val : "+ extras.getString("net.dbg.android.fjol"));

    }
    mTabsController.setActiveTab(TabsController.TAB_DOWNLOADS);
}

ใช้สิ่งนี้:

Bundle extras = getIntent().getExtras();
if(extras !=null) {
    String value = extras.getString("keyName");
}

20
อาจจะสายสำหรับ OP แต่มันไม่สายสำหรับคนอื่น ๆ ในอินเทอร์เน็ต :)
espinchi

19

พบปัญหาเดียวกันที่นี่ ฉันแก้ไขได้โดยใช้รหัสการร้องขอที่แตกต่างกันใช้รหัสเดียวกันเป็นการแจ้งเตือนในขณะที่สร้าง PendingIntent แต่ก็ยังไม่รู้ว่าทำไมต้องทำเช่นนี้

PendingIntent contentIntent = PendingIntent.getActivity(context, **id**, notificationIntent, 0);
notif.contentIntent = contentIntent;
nm.notify(**id**, notif);

14

หลังจากอ่านรายชื่ออีเมลและฟอรัมอื่น ๆ ฉันพบว่าเคล็ดลับดูเหมือนว่าจะเพิ่มข้อมูลที่ไม่ซ้ำกันลงในเจตนา

แบบนี้:

   Intent notificationIntent = new Intent(Main.this, Main.class);
   notificationIntent.putExtra("sport_id", "sport"+id);
   notificationIntent.putExtra("game_url", "gameURL"+id);

   notificationIntent.setData((Uri.parse("foobar://"+SystemClock.elapsedRealtime()))); 

ฉันไม่เข้าใจว่าทำไมต้องทำเช่นนี้มันมีบางอย่างที่เกี่ยวข้องกับเจตนาไม่สามารถระบุได้เฉพาะสิ่งพิเศษเท่านั้น ...


8
แอนรอยด์นำมาใช้ซ้ำการกระทำโดยเจตนาและรหัสขอทำให้มันไม่ซ้ำกัน แต่ไม่ใช่ข้อมูลเพิ่มเติม ดังนั้นคุณต้องตั้งรหัสคำขอที่ไม่ซ้ำหรือใช้การกระทำที่แตกต่างกัน
Bachi

10

ฉันพยายามทุกอย่าง แต่ไม่มีอะไรทำงาน

ในที่สุดก็เกิดขึ้นกับการแก้ปัญหาต่อไปนี้

1- ในรายการเพิ่มสำหรับกิจกรรม android: launchMode = "singleTop"

2- ในขณะที่ทำการเจตนาที่ค้างอยู่ให้ทำสิ่งต่อไปนี้ใช้มัดแทนการใช้โดยตรง

                    Intent notificationIntent = new Intent(getApplicationContext(), CourseActivity.class);

                    Bundle bundle = new Bundle();
                    bundle.putString(Constants.EXAM_ID,String.valueOf(lectureDownloadStatus.getExamId()));
                    bundle.putInt(Constants.COURSE_ID,(int)lectureDownloadStatus.getCourseId());
                    bundle.putString(Constants.IMAGE_URL,lectureDownloadStatus.getImageUrl());

                    notificationIntent.putExtras(bundle);

                    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
                            Intent.FLAG_ACTIVITY_SINGLE_TOP);
                    PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),
                            new Random().nextInt(), notificationIntent,
                            PendingIntent.FLAG_UPDATE_CURRENT); 

3
มันใช้งานได้สำหรับฉัน ต้องใช้ค่า requestCode ที่แตกต่างกันและ PendingIntent.FLAG_UPDATE_CURRENT
phuongle

4

AndroidManifest.xml

รวม launchMode = "singleTop"

<activity android:name=".MessagesDetailsActivity"
        android:launchMode="singleTop"
        android:excludeFromRecents="true"
        />

SMSReceiver.java

ตั้งค่าสถานะสำหรับ Intent และ PendingIntent

Intent intent = new Intent(context, MessagesDetailsActivity.class);
    intent.putExtra("smsMsg", smsObject.getMsg());
    intent.putExtra("smsAddress", smsObject.getAddress());
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

    PendingIntent contentIntent = PendingIntent.getActivity(context, notification_id, intent, PendingIntent.FLAG_UPDATE_CURRENT);

MessageDetailsActivity.java

onResume () - ถูกเรียกทุกครั้งโหลดค่าพิเศษ

Intent intent = getIntent();
    String extraAddress = intent.getStringExtra("smsAddress");
    String extraBody = intent.getStringExtra("smsMsg");

หวังว่ามันจะช่วยได้มันขึ้นอยู่กับคำตอบอื่น ๆ ที่นี่ใน stackoverflow แต่นี่เป็นการปรับปรุงที่ดีที่สุดสำหรับฉัน


3

ง่ายนี่เป็นวิธีแก้ปัญหาของฉันโดยใช้วัตถุ!

POJO ของฉัน

public class Person implements Serializable{

    private String name;
    private int age;

    //get & set

}

วิธีการแจ้งเตือน

  Person person = new Person();
  person.setName("david hackro");
  person.setAge(10);

    Intent notificationIntent = new Intent(this, Person.class);
    notificationIntent.putExtra("person",person);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.notification_icon)
                .setAutoCancel(true)
                .setColor(getResources().getColor(R.color.ColorTipografiaAdeudos))
                .setPriority(2)
                .setLargeIcon(bm)
                .setTicker(fotomulta.getTitle())
                .setContentText(fotomulta.getMessage())
                .setContentIntent(PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT))
                .setWhen(System.currentTimeMillis())
                .setContentTitle(fotomulta.getTicketText())
                .setDefaults(Notification.DEFAULT_ALL);

กิจกรรมใหม่

 private Person person;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_notification_push);
    person = (Person) getIntent().getSerializableExtra("person");
}

โชคดี!!


3

หลังจากทำการค้นหาบางอย่างฉันได้รับคำแนะนำจากคู่มือผู้พัฒนา android

PendingIntent contentIntent ;
Intent intent = new Intent(this,TestActivity.class);
intent.putExtra("extra","Test");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);

stackBuilder.addParentStack(ArticleDetailedActivity.class);

contentIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);

ในการรับค่าเพิ่มเติมเจตนาในคลาสกิจกรรมการทดสอบคุณต้องเขียนโค้ดต่อไปนี้:

 Intent intent = getIntent();
 String extra = intent.getStringExtra("extra") ;

3
มีstackBuilderไว้เพื่ออะไร
Alexio

1

ในการใช้งานการแจ้งเตือนของคุณให้ใช้รหัสดังนี้:

NotificationCompat.Builder nBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
...
Intent intent = new Intent(this, ExampleActivity.class);
intent.putExtra("EXTRA_KEY", "value");

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
nBuilder.setContentIntent(pendingIntent);
...

หากต้องการรับค่าเพิ่มเติมที่ต้องการในตัวอย่างActivityให้ใช้รหัสต่อไปนี้:

...
Intent intent = getIntent();
if(intent!=null) {
    String extraKey = intent.getStringExtra("EXTRA_KEY");
}
...

หมายเหตุสำคัญมาก:วิธีIntent :: putExtra ()เป็นโอเวอร์โหลด เพื่อให้ได้เสริมคีย์ข้อมูล, คุณจำเป็นต้องใช้เจตจำนง :: รับ [Type] พิเศษ ()วิธีการ

หมายเหตุ: NOTIFICATION_IDและNOTIFICATION_CHANNEL_IDเป็นค่าคงที่ที่ประกาศใน ExampleActivity


1

G'day ฉันก็สามารถพูดได้ว่าฉันลองทุกอย่างที่กล่าวถึงในโพสต์เหล่านี้และอีกไม่กี่ที่อื่น ปัญหาอันดับ 1 สำหรับฉันก็คือ Intent ใหม่มักจะมีบันเดิลว่างอยู่เสมอ ปัญหาของฉันมุ่งเน้นไปที่รายละเอียดของ "ฉันได้รวม. thats หรือ. that" ไว้มากเกินไป โซลูชันของฉันใช้เวลาถอยห่างจากรายละเอียดและดูโครงสร้างโดยรวมของการแจ้งเตือน เมื่อฉันทำฉันจัดการเพื่อวางส่วนสำคัญของรหัสในลำดับที่ถูกต้อง ดังนั้นหากคุณมีปัญหาที่คล้ายกันตรวจสอบ:

1. Intent notificationIntent = new Intent(MainActivity.this, NotificationActivity.class);

2a. Bundle bundle = new Bundle();

// ฉันชอบระบุประเภทข้อมูลที่ดีกว่ามาก เช่น bundle.putInt

2b. notificationIntent.putExtras(bundle);
3. PendingIntent contentIntent = PendingIntent.getActivity(MainActivity.this, WIZARD_NOTIFICATION_ID, notificationIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
4. NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
5.          NotificationCompat.Builder nBuilder =
                    new NotificationCompat.Builder(this)
                            .setSmallIcon(R.drawable.ic_notify)
                            .setContentTitle(title)
                            .setContentText(content)
                            .setContentIntent(contentIntent)
                            .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
                            .setAutoCancel(false)//false is standard. true == automatically removes the notification when the user taps it.
                            .setColor(getResources().getColor(R.color.colorPrimary))
                            .setCategory(Notification.CATEGORY_REMINDER)
                            .setPriority(Notification.PRIORITY_HIGH)
                            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
            notificationManager.notify(WIZARD_NOTIFICATION_ID, nBuilder.build());

ด้วยลำดับนี้ฉันได้รับชุดข้อมูลที่ถูกต้อง


0

ถ้าคุณใช้

android:taskAffinity="myApp.widget.notify.activity"
android:excludeFromRecents="true"

ในไฟล์ AndroidManifest.xml ของคุณเพื่อให้กิจกรรมเริ่มทำงานคุณต้องใช้สิ่งต่อไปนี้ตามความตั้งใจของคุณ:

Intent notificationClick = new Intent(context, NotifyActivity.class);
    Bundle bdl = new Bundle();
    bdl.putSerializable(NotifyActivity.Bundle_myItem, myItem);
    notificationClick.putExtras(bdl);
    notificationClick.setData(Uri.parse(notificationClick.toUri(Intent.URI_INTENT_SCHEME) + myItem.getId()));
    notificationClick.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);  // schließt tasks der app und startet einen seperaten neuen

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addParentStack(NotifyActivity.class);
    stackBuilder.addNextIntent(notificationClick);

    PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    mBuilder.setContentIntent(notificationPendingIntent);

สิ่งสำคัญคือการตั้งค่าข้อมูลที่ไม่ซ้ำเช่นใช้รหัสเฉพาะเช่น:

notificationClick.setData(Uri.parse(notificationClick.toUri(Intent.URI_INTENT_SCHEME) + myItem.getId()));


0

โปรดใช้เป็น PendingIntent ขณะที่แสดงการแจ้งเตือนมากกว่าที่จะได้รับการแก้ไข

PendingIntent เจตนา = PendingIntent.getActivity (สิ่งนี้, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

เพิ่ม PendingIntent.FLAG_UPDATE_CURRENT เป็นฟิลด์สุดท้าย

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