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


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

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

экстры всегда null, и я никогда ничего не получаю в свой журнал.

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

какие идеи?

12 182

12 ответов:

взгляните на это руководство (создать уведомление) и к образцам ApiDemos "StatusBarNotifications" и "NotificationDisplay".

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

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

  2. то же самое, что и номер один, но вместо добавления флага к намерению вы должны добавить "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);

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

такой:

   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

установите флаги для намерения и 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, но это самый обновленный, который работал мне.

это легко, это мое решение с помощью объектов!

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

Удачи!!

после выполнения некоторого поиска я получил решение от Android developer guide

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 intent = getIntent();
 String extra = intent.getStringExtra("extra") ;

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

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

услуги используйте PendingIntent.FLAG_UPDATE_CURRENT

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

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

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

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