Bir bildirim tıklamasından bir etkinliğe parametre nasıl gönderilir?


206

Bildirimimden etkinliğime parametre göndermenin bir yolunu bulabilirim.

Bildirim oluşturan bir hizmetim var. Kullanıcı bildirimi tıkladığında, ana faaliyetimi bazı özel parametrelerle açmak istiyorum. Örneğin bir öğe kimliği, böylece etkinliğim özel bir öğe ayrıntı görünümü yükleyebilir ve sunabilir. Daha spesifik olarak, bir dosya indiriyorum ve dosya indirildiğinde, bildirime tıklandığında etkinliğimi özel bir modda açma niyetinde olmasını istiyorum. putExtraNiyetimde kullanmaya çalıştım , ama onu ayıklayamıyorum, bu yüzden yanlış yaptığımı düşünüyorum.

Bildirimi oluşturan hizmetimin kodu:

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

Bildirimden fazladan parametreyi almaya çalışan Etkinliğimdeki kod:

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

Ekstralar her zaman boştur ve günlüküme hiçbir şey almam.

Btw ... onCreatesadece etkinliğim başladığında çalıştırılır, etkinliğim zaten başlamışsa ekstraları toplamak ve aldığım item_id'e göre etkinliğimi sunmak istiyorum.

Herhangi bir fikir?

Yanıtlar:


241

Bu kılavuza bir göz atın ( bildirim oluşturma ) ve ApiDemos "StatusBarNotifications" ve "NotificationDisplay" örneklerini inceleyin.

Etkinliğin zaten yürütülüp yürütülmediğini yönetmek için iki yolunuz vardır:

  1. Etkinliği başlatırken Niyet'e FLAG_ACTIVITY_SINGLE_TOP bayrağını ekleyin ve ardından etkinlik sınıfında onNewIntent (Niyet niyeti) olay işleyicisini uygulayın, böylece etkinlik için çağrılan yeni amaca erişebilirsiniz (yalnızca getIntent'i çağırmakla aynı şey değildir) (), bu her zaman etkinliğinizi başlatan ilk Niyeti döndürür.

  2. Bir numara ile aynı, ancak Niyet'e bir bayrak eklemek yerine AndroidManifest.xml etkinliğinize "singleTop" eklemeniz gerekir .

Amaç ekstraları kullanırsanız PendingIntent.getActivity(), bayrakla aramayı unutmayın PendingIntent.FLAG_UPDATE_CURRENT, aksi takdirde her bildirim için aynı ekstralar yeniden kullanılır.


95
ve kullanıcının ekstraların boş olmasıyla ilgili sorusunu cevaplamak için: PendingIntent.getActivity()Bayrağa başvurmanız gerekir PendingIntent.FLAG_UPDATE_CURRENT, aksi takdirde her bildirim için aynı ekstralar yeniden kullanılır.
Matthias

2
u günümü kurtardı ama neden böyle basit verileri android çok karmaşık aktarıyor
Yasadışı Argüman

8
Eğer var ise farklı bildirimler çağrılırken farklı istek kimlikleri kullandığınızdan emin olun PendingIntent.getActivity()ayara ek olarak FLAG_ACTIVITY_SINGLE_TOPüzerine Intentve FLAG_UPDATE_CURRENTüzerinde PendingIntent. Bkz. Stackoverflow.com/questions/7370324/…
schnatterer

101

Uygulamamda mesaj bildirimleri görüntülenen benzer bir sorun vardı. Birden fazla bildirim olduğunda ve her bir bildirimi tıkladığınızda bu bildirim ayrıntısını bir görünüm iletisi etkinliğinde görüntüler. Görünüm mesajı niyetinde aynı ekstra parametreler alma sorunu çözüldü.

İşte bunu düzelten kod. Bildirim Amacı oluşturma kodu.

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

İleti Etkinliğini görüntülemek için kod.

@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

Belki biraz geç, ama: bunun yerine:

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

Bunu kullan:

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

20
Belki OP için geç, ama internetteki diğerleri için asla geç değil :)
espinchi

19

Burada da aynı sorunla karşılaşıyoruz. Ben farklı istek kodu kullanarak çözmek, PendingIntent oluştururken bildirim olarak aynı kimliği kullanın. ama yine de bunun neden yapılması gerektiğini bilmiyorum.

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

14

Bazı e-posta listeleri ve diğer forumları okuduktan sonra hile niyetine som benzersiz veri eklemek gibi görünüyor bulundu.

bunun gibi:

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

Bunun neden yapılması gerektiğini anlamıyorum, sadece ekstraları ile tanımlanamayacak niyetle ilgili bir şey var ...


8
Anroid niyetleri yeniden kullanır, niyet eylemi ve istek kodu onu benzersiz kılar, ancak ekstra verileri değil. Bu nedenle, benzersiz bir istek kimliği ayarlamanız veya farklı amaç eylemleri kullanmanız gerekir.
Bachi

10

Her şeyi denedim ama hiçbir şey işe yaramadı.

Sonunda aşağıdaki çözümü buldum.

1- faaliyet android için manifest ekleyin: launchMode = "singleTop"

2- beklemede olan amacı yaparken aşağıdakileri yapın, doğrudan intent.putString () veya intent.putInt () yerine paket kullanın

                    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
Benim için çalışıyor. Farklı requestCode değeri ve PendingIntent.FLAG_UPDATE_CURRENT bayrağı kullanılmalıdır.
phuongle

4

AndroidManifest.xml

Dahil etme launchMode = "singleTop"

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

SMSReceiver.java

Niyet ve PendingIntent için bayrakları ayarlama

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 () - her zaman çağrılır, ekstraları yükleyin.

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

Umarım yardımcı olur, burada stackoverflow ile ilgili diğer cevaplara dayanıyordu, ama bu benim için çalışan en güncel olanı.


3

Kolay, bu nesneleri kullanarak benim çözümüm!

POJO'm

public class Person implements Serializable{

    private String name;
    private int age;

    //get & set

}

Yöntem Bildirimi

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

Yeni Aktivite

 private Person person;

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

İyi şanslar!!


3

Bazı arama yaptıktan sonra android geliştirici kılavuzundan çözüm aldım

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

Test Etkinliği sınıfında Niyet ekstra değeri elde etmek için aşağıdaki kodu yazmanız gerekir:

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

3
Ne stackBuilderiçin?
AlexioVay

1

Bildirim uygulamanızda şöyle bir kod kullanın:

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

SampleActivity'de Niyet ekstra değerleri almak için aşağıdaki kodu kullanın:

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

ÇOK ÖNEMLİ NOT: Niyet :: putExtra () yöntemi bir Aşırı Yükleme biridir. Ekstra anahtarı almak için Intent :: get [Type] Extra () yöntemini kullanmanız gerekir.

Not: NOTIFICATION_ID ve NOTIFICATION_CHANNEL_ID , SampleActivity'de bildirilen sabitlerdir


1

Gday, ben de bu yazılarda bahsettiğim her şeyi ve başka yerlerden birkaçını denediğimi söyleyebilirim. Benim için 1 numaralı sorun, yeni Niyet'in her zaman boş bir paket olmasıydı. Benim sorunum ".this or .that ekledim mi?" Benim çözümüm ayrıntıdan geri adım atmak ve bildirimin genel yapısına bakmaktı. Bunu yaptığımda, kodun önemli kısımlarını doğru sırada yerleştirmeyi başardım. Benzer sorunlar yaşıyorsanız şunları kontrol edin:

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

2a. Bundle bundle = new Bundle();

// Veri türünü daha iyi belirtmeyi seviyorum. örneğin 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());

Bu sıra ile geçerli bir paket alıyorum.


0

Eğer kullanırsan

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

Etkinliğin başlaması için AndroidManifest.xml dosyanızda, niyetinizde aşağıdakileri kullanmanız gerekir:

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

Önemli olan benzersiz verileri ayarlamaktır, örneğin:

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

0

Lütfen çözüleceğinden daha fazla bildirim gösterirken PendingIntent olarak kullanın.

PendingIntent intent = PendingIntent.getActivity (this, 0, bildirimIntent, PendingIntent.FLAG_UPDATE_CURRENT);

PendingIntent.FLAG_UPDATE_CURRENT öğesini son alan olarak ekleyin.

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.