it-swarm.com.de

Wie sendet man Parameter von einem Benachrichtigungsklick an eine Aktivität?

Ich kann einen Weg finden, Parameter aus meiner Benachrichtigung an meine Aktivität zu senden.

Ich habe einen Dienst, der eine Benachrichtigung erstellt. Wenn der Benutzer auf die Benachrichtigung klickt, möchte ich meine Hauptaktivität mit einigen speziellen Parametern öffnen. Z. B. eine Artikel-ID, damit meine Aktivität eine spezielle Element-Detailansicht laden und präsentieren kann. Genauer gesagt, ich lade eine Datei herunter. Wenn die Datei heruntergeladen wird, möchte ich, dass die Benachrichtigung beabsichtigt, dass beim Klicken auf meine Aktivität meine Aktivität in einem speziellen Modus geöffnet wird. Ich habe versucht, putExtra in meiner Absicht zu verwenden, kann es aber nicht extrahieren, also denke ich, dass ich es falsch mache.

Code von meinem Dienst, der die Benachrichtigung erstellt:

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

Code aus meiner Aktivität, der versucht, den zusätzlichen Parameter aus der Benachrichtigung abzurufen:

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

Die Extras sind immer null und ich bekomme nie etwas in mein Protokoll.

Übrigens ... der onCreate wird nur ausgeführt, wenn meine Aktivität beginnt. Wenn meine Aktivität bereits gestartet ist, möchte ich auch die Extras sammeln und meine Aktivität gemäß der item_id präsentieren, die ich erhalte.

Irgendwelche Ideen?

184
Vidar Vestnes

Werfen Sie einen Blick in diese Anleitung ( Erstellen einer Benachrichtigung ) und probieren Sie ApiDemos "StatusBarNotifications" und "NotificationDisplay".

Um zu verwalten, ob die Aktivität bereits läuft, haben Sie zwei Möglichkeiten:

  1. Fügen Sie dem Intent beim Start der Aktivität das Flag FLAG_ACTIVITY_SINGLE_TOP hinzu. Anschließend können Sie in der Aktivitätsklasse den onNewIntent (Intent Intent) - Ereignishandler implementieren. Auf diese Weise können Sie auf den neuen Intent zugreifen, der für die Aktivität aufgerufen wurde ist nicht gleichbedeutend mit dem Aufruf von getIntent (). Dies gibt immer die erste Absicht zurück, die Ihre Aktivität gestartet hat.

  2. Gleich wie Nummer eins, aber anstatt ein Flag zum Intent hinzuzufügen, müssen Sie "singleTop" in Ihrer Aktivität AndroidManifest.xml hinzufügen.

Wenn Sie Vorsatz-Extras verwenden, müssen Sie unbedingt PendingIntent.getActivity() mit dem Flag PendingIntent.FLAG_UPDATE_CURRENT aufrufen. Andernfalls werden dieselben Extras für jede Benachrichtigung verwendet.

225
Lucas S.

Ich hatte ein ähnliches Problem. In meiner Anwendung werden Nachrichtenbenachrichtigungen angezeigt. Wenn mehrere Benachrichtigungen vorhanden sind und auf jede Benachrichtigung geklickt wird, wird das Benachrichtigungsdetail in einer Nachrichtenansicht angezeigt. Ich habe das Problem gelöst, dass dieselben zusätzlichen Parameter in der Ansichtsnachricht absichtlich empfangen werden.

Hier ist der Code, der diesen . Code zum Erstellen der Benachrichtigungsabsicht korrigiert hat.

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

Code zum Anzeigen der Nachrichtenaktivität.

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


}

Vielleicht etwas spät, aber: Stattdessen:

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

Benutze das:

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

Hier ist dasselbe Problem aufgetreten ... Ich löse es mithilfe eines anderen Anforderungscodes und verwende dieselbe ID als Benachrichtigung, während PendingIntent erstellt wird. weiß aber immer noch nicht, warum das getan werden sollte.

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

Nachdem ich einige E-Mail-Listen und andere Foren gelesen hatte, stellte ich fest, dass der Trick der Absicht einige einzigartige Daten hinzufügt.

so was: 

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

Ich verstehe nicht, warum dies getan werden muss. Es hat etwas mit der Absicht zu tun, kann nicht nur durch seine Extras identifiziert werden ...

13
Vidar Vestnes

Ich habe alles versucht, aber nichts hat funktioniert.

schließlich kam folgende Lösung.

1- in Manifest hinzufügen für die Aktivität Android: launchMode = "singleTop"

2- Während Sie ausstehende Absichten ausüben, führen Sie die folgenden Schritte aus, verwenden Sie ein Bündel, anstatt direkt eine Verwendung von intent.putString () oder

                    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); 
9
Dheeraj Sachan

AndroidManifest.xml

Include launchMode = "singleTop"

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

SMSReceiver.Java

Legen Sie die Flags für Intent und PendingIntent fest

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 () - wird jedes Mal aufgerufen, laden Sie die Extras.

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

Ich hoffe, es hilft, es basierte auf anderen Antworten hier auf stackoverflow, aber dies ist das aktuellste, das für mich funktionierte.

2
Miguel Jesus

Es ist einfach, das ist meine Lösung mit Objekten!

Mein POJO

public class Person implements Serializable{

    private String name;
    private int age;

    //get & set

}

Methodenbenachrichtigung

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

Neue Aktivität

 private Person person;

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

Viel Glück!!

2
David Hackro

Nach einiger Suche bekam ich eine Lösung von 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);

Um einen zusätzlichen Wert in der Testaktivitätsklasse zu erhalten, müssen Sie den folgenden Code schreiben:

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

für Dienste verwenden Sie PendingIntent.FLAG_UPDATE_CURRENT

für mich arbeiten.

0
Ali Bagheri

Wenn du benutzt 

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

in Ihrer AndroidManifest.xml-Datei müssen Sie für die zu startende Aktivität Folgendes verwenden:

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

Wichtig ist, eindeutige Daten festzulegen, z. Verwenden einer eindeutigen ID wie:

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

Verwenden Sie in Ihrer Benachrichtigungsimplementierung einen Code wie den folgenden:

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

Verwenden Sie den folgenden Code, um zusätzliche Werte für Intent in ExampleActivity abzurufen:

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

SEHR WICHTIGER HINWEIS: Die Methode Intent :: putExtra () ist überladen. Um den zusätzlichen Schlüssel zu erhalten, müssen Sie die Methode Intent :: get [Type] Extra () verwenden.

Hinweis: NOTIFICATION_ID und NOTIFICATION_CHANNEL_ID sind in ExampleActivity deklarierte Konstanten

0
Carlos Espinoza

G'day, ich kann auch sagen, dass ich alles ausprobiert habe, was in diesen Posts erwähnt wird, und ein paar mehr von woanders. Das größte Problem für mich war, dass der neue Intent immer ein Null-Bundle hatte. Mein Problem bestand darin, mich zu sehr auf die Details von "Habe ich .dieses oder .dieses" zu konzentrieren. Meine Lösung bestand darin, einen Schritt zurück vom Detail zu gehen und die Gesamtstruktur der Meldung zu betrachten. Als ich das tat, gelang es mir, die wichtigsten Teile des Codes in der richtigen Reihenfolge zu platzieren. Wenn Sie ähnliche Probleme haben, überprüfen Sie, ob:

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

2a. Bundle bundle = new Bundle();

// Ich mag es, den Datentyp viel besser anzugeben. zB 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());

Mit diesem Sequenz bekomme ich ein gültiges Bundle.

0
Peter Suter

Bitte verwenden Sie als PendingIntent, während die Benachrichtigung angezeigt wird, da sie aufgelöst wird.

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

Fügen Sie als letztes Feld PendingIntent.FLAG_UPDATE_CURRENT hinzu.

0
M.Noman