Как отправить параметры из уведомления-клика в активность?

Я могу найти способ отправить параметры моей деятельности из моего уведомления.

У меня есть сервис, который создает уведомления. Когда пользователь нажимает на уведомление, я хочу открыть свою основную деятельность с некоторыми специальными параметрами. Например, идентификатор элемента, чтобы моя деятельность могла загрузить и представить специальный подробный вид элемента. Точнее говоря, я загружаю файл, и когда файл загружается, я хочу, чтобы уведомление имело намерение, чтобы при нажатии оно открывало мою активность в специальном режиме. Я пытался использовать 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 запускается только тогда, когда моя активность начинается, если моя активность уже началась, я также хочу собрать дополнительные данные и представить свою активность в соответствии с item_id, который я получаю.

Есть идеи?

12 ответов

Решение

Посмотрите это руководство ( создание уведомления) и примеры ApiDemos "StatusBarNotifications" и "NotificationDisplay".

Для управления, если действие уже запущено, у вас есть два способа:

  1. Добавьте флаг FLAG_ACTIVITY_SINGLE_TOP в Intent при запуске действия, а затем в классе действия реализуйте обработчик события onNewIntent(намерение), чтобы вы могли получить доступ к новому намерению, которое было вызвано для действия (которое отличается от простого вызова getIntent). (), это всегда будет возвращать первое намерение, которое запустило вашу деятельность.

  2. То же, что номер один, но вместо добавления флага в Intent вы должны добавить "singleTop" в вашей активности AndroidManifest.xml.

Если вы используете намеренные дополнения, не забудьте позвонить PendingIntent.getActivity() с флагом PendingIntent.FLAG_UPDATE_CURRENT иначе одни и те же дополнения будут повторно использоваться для каждого уведомления.

У меня была похожая проблема, мое приложение отображает уведомления о сообщениях. Если имеется несколько уведомлений и щелчок по каждому уведомлению, он отображает детали этого уведомления в просмотре сообщения. Я решил проблему получения тех же дополнительных параметров в сообщении намерения.

Вот код, который это исправил. Код для создания уведомления о намерениях.

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


}

Может быть немного поздно, но: вместо этого:

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

Встреча та же проблема здесь. Я разрешаю его, используя другой код запроса, используя тот же идентификатор, что и уведомление, при создании PendingIntent. но до сих пор не знаю, почему это должно быть сделано.

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

Прочитав некоторые списки адресов электронной почты и другие форумы, я обнаружил, что уловка, кажется, добавляет некоторые уникальные данные к цели.

как это:

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

Я не понимаю, почему это нужно сделать, Это связано с тем, что намерение не может быть идентифицировано только по его дополнениям...

Я перепробовал все, но ничего не получалось.

в итоге придумали следующее решение.

1- в манифест добавить для активности Android: launchMode = "singleTop"

2 - делая отложенное намерение, сделайте следующее, используйте bundle вместо непосредственного использования intent.putString() или 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); 

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

Надеюсь, это поможет, это было основано на других ответах здесь на stackru, но это наиболее обновленный, который работал для меня.

В реализации уведомлений используйте такой код:

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

Чтобы получить дополнительные значения Intent в ExampleActivity, используйте следующий код:

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

ОЧЕНЬ ВАЖНОЕ ПРИМЕЧАНИЕ: метод Intent::putExtra() является перегруженным. Чтобы получить дополнительный ключ, вам нужно использовать метод Intent::get[Type]Extra().

Примечание. NOTIFICATION_ID и NOTIFICATION_CHANNEL_ID - константы, объявленные в ExampleActivity.

Это просто, это мое решение с использованием объектов!

МОЙ ПОЖО

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

Удачи!!

После некоторого поиска я получил решение от руководства разработчика 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 в классе Test Activity, вам нужно написать следующий код:

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

Пожалуйста, используйте как PendingIntent при отображении уведомления, чем оно будет разрешено.

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

Добавьте PendingIntent.FLAG_UPDATE_CURRENT в качестве последнего поля.

Доброго времени суток, я тоже могу сказать, что перепробовал все, что упоминалось в этих сообщениях, и еще несколько из других источников. Проблема №1 для меня заключалась в том, что новое намерение всегда имело нулевой пакет. Моя проблема заключалась в том, чтобы слишком много внимания уделять деталям типа "включил ли я.this или.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());

С этой последовательностью я получаю действительный комплект.

Если вы используете

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

в вашем файле AndroidManifest.xml для запуска Activity вы должны использовать следующее:

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

Для использования Сервисов PendingIntent.FLAG_UPDATE_CURRENT

для меня работа.

Другие вопросы по тегам