Bagaimana cara mengirim parameter dari notifikasi-klik ke suatu aktivitas?

206

Saya dapat menemukan cara untuk mengirim parameter ke aktivitas saya dari notifikasi saya.

Saya memiliki layanan yang membuat pemberitahuan. Ketika pengguna mengklik pemberitahuan saya ingin membuka aktivitas utama saya dengan beberapa parameter khusus. Misalnya id item, sehingga aktivitas saya dapat memuat dan menyajikan tampilan detail item khusus. Lebih spesifik, saya mengunduh file, dan ketika file diunduh saya ingin notifikasi memiliki niat bahwa ketika diklik itu membuka aktivitas saya dalam mode khusus. Saya telah mencoba menggunakan putExtrapada maksud saya, tetapi sepertinya tidak bisa mengekstraknya, jadi saya pikir saya salah melakukannya.

Kode dari layanan saya yang membuat Pemberitahuan:

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

Kode dari Aktivitas saya yang mencoba mengambil parameter tambahan dari pemberitahuan:

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

Ekstra selalu nol dan saya tidak pernah memasukkan apa pun ke dalam log saya.

Btw ... onCreateini hanya berjalan ketika aktivitas saya mulai, jika aktivitas saya sudah dimulai saya juga ingin mengumpulkan ekstra dan menyajikan aktivitas saya sesuai dengan item_id yang saya terima.

Ada ide?

Vidar Vestnes
sumber

Jawaban:

241

Lihatlah panduan ini ( membuat pemberitahuan ) dan untuk sampel ApiDemos "StatusBarNotifications" dan "NotificationDisplay".

Untuk mengelola jika aktivitas sudah berjalan, Anda memiliki dua cara:

  1. Tambahkan flag FLAG_ACTIVITY_SINGLE_TOP ke Intent saat meluncurkan aktivitas, dan kemudian di kelas aktivitas implementasikan event handler onNewIntent (Intent intent) , dengan cara itu Anda dapat mengakses maksud baru yang dipanggil untuk aktivitas (yang tidak sama dengan hanya memanggil getIntent (), ini akan selalu mengembalikan Intent pertama yang meluncurkan aktivitas Anda.

  2. Sama seperti nomor satu, tetapi alih-alih menambahkan bendera ke Intent Anda harus menambahkan "singleTop" di aktivitas Anda AndroidManifest.xml.

Jika Anda menggunakan ekstra maksud, ingat untuk memanggil PendingIntent.getActivity()dengan bendera PendingIntent.FLAG_UPDATE_CURRENT, jika tidak, tambahan yang sama akan digunakan kembali untuk setiap pemberitahuan.

Lucas S.
sumber
95
dan untuk menjawab pertanyaan pengguna tentang tambahan menjadi nol: Anda harus menelepon PendingIntent.getActivity()dengan bendera PendingIntent.FLAG_UPDATE_CURRENT, jika tidak, tambahan yang sama akan digunakan kembali untuk setiap pemberitahuan.
Matthias
2
u menyelamatkan hari saya tapi mengapa mentransfer data sederhana seperti ini sangat rumit di android
Illegal Argument
8
Jika Anda memiliki notifikasi yang berbeda, pastikan untuk menggunakan ID permintaan yang berbeda saat menelepon PendingIntent.getActivity()selain pengaturan FLAG_ACTIVITY_SINGLE_TOPpada Intentdan FLAG_UPDATE_CURRENTpada PendingIntent. Lihat stackoverflow.com/questions/7370324/…
schnatterer
101

Saya memiliki masalah yang sama dengan aplikasi saya menampilkan pemberitahuan pesan. Ketika ada beberapa notifikasi dan mengklik setiap notifikasi, ia menampilkan detail notifikasi itu dalam aktivitas pesan tampilan. Saya memecahkan masalah parameter tambahan yang sama sedang diterima dalam maksud pesan tampilan.

Berikut adalah kode yang memperbaikinya. Kode untuk membuat Intent notifikasi.

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

Kode untuk melihat Aktivitas Pesan.

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


}
Muhammad Yousaf Sulahria
sumber
29

Mungkin agak terlambat, tetapi: alih-alih ini:

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

Gunakan ini:

Bundle extras = getIntent().getExtras();
if(extras !=null) {
    String value = extras.getString("keyName");
}
pinaise
sumber
20
Mungkin terlambat untuk OP, tetapi tidak pernah terlambat untuk yang lain di Internet :)
espinchi
19

Mengalami masalah yang sama di sini. Saya mengatasinya dengan menggunakan kode permintaan yang berbeda, menggunakan id yang sama dengan pemberitahuan, sambil membuat PendingIntent. tetapi masih tidak tahu mengapa ini harus dilakukan.

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

Setelah membaca beberapa daftar email dan forum lain saya menemukan bahwa triknya tampaknya menambahkan beberapa data unik ke maksudnya.

seperti ini:

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

Saya tidak mengerti mengapa ini perlu dilakukan, Ada hubungannya dengan maksud tidak dapat diidentifikasi hanya dengan tambahannya ...

Vidar Vestnes
sumber
8
Anroid menggunakan kembali maksud, tindakan maksud dan kode permintaan membuatnya unik, tetapi bukan data tambahan. Jadi, Anda perlu menetapkan id permintaan unik atau menggunakan tindakan maksud yang berbeda.
Bachi
10

Saya mencoba segalanya tetapi tidak ada yang berhasil.

akhirnya datang dengan solusi berikut.

1- tambahkan manifes untuk android aktivitas: launchMode = "singleTop"

2- saat membuat niat tertunda lakukan hal berikut, gunakan bundel alih-alih langsung menggunakan intent.putString () atau intent.putInt ()

                    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); 
Dheeraj Sachan
sumber
3
Ini bekerja untuk saya. Harus menggunakan nilai requestCode yang berbeda dan flag PendingIntent.FLAG_UPDATE_CURRENT.
phuongle
4

AndroidManifest.xml

Sertakan launchMode = "singleTop"

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

SMSReceiver.java

Tetapkan bendera untuk Intent dan 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 () - dipanggil setiap kali, muat ekstra.

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

Semoga ini bisa membantu, ini didasarkan pada jawaban lain di sini di stackoverflow, tetapi ini adalah yang terbaru yang bekerja untuk saya.

Miguel Jesus
sumber
3

Mudah, ini solusi saya menggunakan objek!

POJO saya

public class Person implements Serializable{

    private String name;
    private int age;

    //get & set

}

Pemberitahuan Metode

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

Aktivitas Baru

 private Person person;

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

Semoga berhasil!!

David Hackro
sumber
3

Setelah melakukan pencarian saya mendapat solusi dari panduan pengembang 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);

Untuk Mendapatkan nilai ekstra Intent di kelas Kegiatan Tes, Anda perlu menulis kode berikut:

 Intent intent = getIntent();
 String extra = intent.getStringExtra("extra") ;
mohit
sumber
3
Untuk apa stackBuilder?
AlexioVay
1

Dalam implementasi pemberitahuan Anda, gunakan kode seperti ini:

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

Untuk Mendapatkan nilai ekstra Intent di ExampleActivity, gunakan kode berikut:

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

CATATAN SANGAT PENTING: metode Intent :: putExtra () adalah yang kelebihan beban. Untuk mendapatkan kunci tambahan, Anda harus menggunakan metode Intent :: get [Type] Extra () .

Catatan: NOTIFICATION_ID dan NOTIFICATION_CHANNEL_ID adalah konstanta yang dideklarasikan dalam ExampleActivity

Carlos Espinoza
sumber
1

G'day, saya juga dapat mengatakan bahwa saya mencoba semua yang disebutkan dalam posting ini dan beberapa lagi dari tempat lain. Masalah # 1 bagi saya adalah bahwa Intent baru selalu memiliki bundel nol. Masalah saya adalah terlalu banyak berfokus pada perincian "apakah saya sudah memasukkan .ini atau .itu". Solusi saya adalah mengambil langkah mundur dari detail dan melihat keseluruhan struktur notifikasi. Ketika saya melakukan itu, saya berhasil menempatkan bagian-bagian kunci dari kode dalam urutan yang benar. Jadi, jika Anda mengalami masalah serupa, periksa:

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

2a. Bundle bundle = new Bundle();

// Aku suka menentukan tipe data yang jauh lebih baik. mis. 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());

Dengan urutan ini saya mendapatkan bundel yang valid.

Peter Suter
sumber
0

Jika Anda menggunakan

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

di file AndroidManifest.xml Anda agar Activity dapat diluncurkan, Anda harus menggunakan yang berikut ini dalam niat Anda:

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

Penting adalah untuk mengatur data unik misalnya menggunakan id unik seperti:

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

untuk penggunaan Layanan PendingIntent.FLAG_UPDATE_CURRENT

bagi saya bekerja.

Ali Bagheri
sumber
0

Silakan gunakan sebagai PendingIntent sambil menampilkan pemberitahuan daripada itu akan diselesaikan.

Intensi PendingIntent = PendingIntent.getActivity (this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Tambahkan PendingIntent.FLAG_UPDATE_CURRENT sebagai bidang terakhir.

M.Noman
sumber