Meine Android-App wird von einer Absicht aufgerufen, die Informationen weitergibt (in der Statusleiste ausstehend).
Wenn ich auf die Home-Taste drücke und meine App erneut öffne, indem ich die Home-Taste gedrückt halte, wird die Absicht erneut aufgerufen, und die gleichen Extras sind noch vorhanden.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
Dies ist der Code, der nicht so läuft, wie er soll
String imgUrl;
Bundle extras = this.getIntent().getExtras();
if(extras != null){
imgUrl = extras.getString("imgUrl");
if( !imgUrl.equals(textView01.getText().toString()) ){
imageView.setImageDrawable( getImageFromUrl( imgUrl ) );
layout1.setVisibility(0);
textView01.setText(imgUrl);//textview to hold the url
}
}
Und meine Absicht:
public void showNotification(String ticker, String title, String message,
String imgUrl){
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(ns);
int icon = R.drawable.icon; // icon from resources
long when = System.currentTimeMillis(); // notification time
CharSequence tickerText = ticker; // ticker-text
//make intent
Intent notificationIntent = new Intent(this, activity.class);
notificationIntent.putExtra("imgUrl", imgUrl);
notificationIntent.setFlags(
PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_ONE_SHOT);
PendingIntent contentIntent =
PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_ONE_SHOT);
//make notification
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(this, title, message, contentIntent);
//flags
notification.flags = Notification.FLAG_SHOW_LIGHTS |
Notification.FLAG_ONGOING_EVENT |
Notification.FLAG_ONLY_ALERT_ONCE |
Notification.FLAG_AUTO_CANCEL;
//sounds
notification.defaults |= Notification.DEFAULT_SOUND;
//notify
mNotificationManager.notify(1, notification);
}
Gibt es eine Möglichkeit, die Absicht zu löschen oder zu überprüfen, ob sie zuvor verwendet wurde?
android
android-intent
Mars
quelle
quelle
Antworten:
AKTUALISIEREN:
Ich wusste nicht, dass auf diese Antwort so viel Bezug genommen werden würde, als ich sie vor mehr als 5 Jahren zum ersten Mal schrieb!
Ich werde klarstellen, dass dies gemäß der Antwort von @ tato-rodrigo in einigen Situationen nicht dazu beiträgt, eine bereits behandelte Absicht zu erkennen.
Ich sollte auch darauf hinweisen, dass ich aus einem bestimmten Grund "klar" in Anführungszeichen setze - Sie löschen die Absicht nicht wirklich, indem Sie dies tun. Sie verwenden lediglich das Entfernen des Extra als Flag, dass diese Absicht von der Aktivität bereits gesehen wurde .
Ich hatte genau das gleiche Problem.
Die obige Antwort hat mich auf den richtigen Weg gebracht und ich habe eine noch einfachere Lösung gefunden. Verwenden Sie Folgendes:
Methodenaufruf zum "Löschen" der Absicht.
Es ist etwas spät zu antworten, da dies vor einem Jahr gefragt wurde, aber hoffentlich hilft dies anderen in der Zukunft.
quelle
setIntent(new Intent())
und es funktioniert jetzt gut.BEARBEITEN: Ich bearbeite, um die vollständige Lösung zu veröffentlichen, die ich verwende.
Diese Lösung funktioniert, wenn das Problem lautet: "Führen Sie keinen Code aus, wenn die Aktivität im Verlauf (Letzte Apps) beginnt" .
Geben Sie zunächst ein
boolean
in IhremActivity
an, um anzugeben, ob dasIntent
bereits verbraucht wurde:Speichern Sie diesen Wert dann sicher und stellen Sie ihn mithilfe der Methoden
onSaveInstanceState
und wieder heronCreate
, um Konfigurationsänderungen und Fälle zu behandeln, in denen das System Sie möglicherweiseActivity
im Hintergrund tötet .Überprüfen Sie nun, ob Sie Ihren Code unter
onResume
method ausführen können .Wenn Sie
Activity
für konfiguriert sindsingleTop
, sollten Sie außerdem Ihr Flag zurücksetzen, wenn ein neuesIntent
ausgeliefert wird.quelle
(intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)
damit ich jetzt herausfinden kann, wann der Beginn der Aktivität aus der Geschichte stammt, und meine Extras ignorieren kann.boolean shouldThisIntentTriggerMyCode = [...];
aus der Antwort entfernen (wofür wird verwendet?)consumedIntent
wennString
der Benutzer eine Benachrichtigungs-Uid enthält. Diese Uid kann einfach als aktueller Zeitstempel zur Benachrichtigung im Backend hinzugefügt werden. Außerdem sollten Sie diese UidonSaveInstanceState
nur speichern, wenn die Absicht vorliegtonCreate
. Dies bedeutet, dass Sie Uid nicht vor speichern solltenonNewIntent
.Maks Antwort funktioniert zum Löschen eines Extra:
Ein weiterer nützlicher Befehl ist:
Sie können eine Absicht auch markieren, indem Sie Folgendes aufrufen:
und dann einfach auf den Wert prüfen.
quelle
Wenn wir Android-Apps aus dem Verlauf (Aktuelle Apps) starten, kann die App hauptsächlich mit drei verschiedenen Intent-Flags gestartet werden.
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
Dies ist der Zeitpunkt, an dem die Aktivität aus dem Verlauf einer minimierten App gestartet wird (lange Home-Taste drücken).
Konstanter Wert: 1048576 (0x00100000)
FLAG_ACTIVITY_NEW_TASK
Dies ist der Fall, wenn die Aktivität über "Klicken auf das Anwendungssymbol" oder über " Absichtsfilter " gestartet wird . Hier wird die Aktivität zum Beginn einer neuen Aufgabe auf diesem Verlaufsstapel.
Konstanter Wert: 268435456 (0x10000000)
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY | FLAG_ACTIVITY_NEW_TASK
In diesem Fall wurde die App durch Drücken der Zurück-Taste beendet und dann aus dem Verlauf (aktuelle Apps) fortgesetzt.
Konstanter Wert: 269484032 (0x10100000)
Konstante Werte können über abgerufen werden
getIntent().getFlags()
Im dritten Fall lädt Android die letzten Intent-Werte aus seinem Speicher neu. Die Absicht (
getIntent
) Ihrer App enthält also Werte aus der letzten Absicht, mit der die App gestartet wurde.Tatsächlich sollte sich die App so verhalten, als wäre es ein Neustart, mit Absichtswerten für einen Neustart anstelle der Absichtswerte des vorherigen Starts. Dieses Verhalten tritt auf, wenn Sie die App durch Klicken auf das App-Symbol starten. Es werden niemals alte Absichtswerte angezeigt. Dies liegt daran, dass Android für dieses Szenario den folgenden Absichtsfilter verwendet
Im dritten Fall (App, die beendet wurde, wird über den Verlauf der letzten Apps gestartet) verwendet Android OS die letzte Absicht, mit der die App vor dem Beenden gestartet wurde (durch Drücken der Zurück-Taste). Sie haben also alte Absichtswerte und der App-Fluss ist nicht richtig.
Das Entfernen von Absichten ist eine Möglichkeit, dies zu lösen, aber es würde das Problem nicht vollständig lösen! Wenn Android OS die Absicht aus dem letzten Start der Apps neu lädt und nicht die letzte Instanz der Startabsicht.
Ein sauberer Weg, um dies zu vermeiden, besteht darin, die Art der Absicht zu ermitteln , um den zu bestimmen.
Also in Ihrem LaunchActivity (Derjenige, der die Absicht Filter hat im Manifest definiert ist ), können Sie den folgenden Code in der Anwendung
onCreate()
,onStart()
oderonResume()
Methoden.Ich nehme an
normalLaunch()
, sollte keine Parameter aus der Absicht verwenden; Andernfalls müssten Sie Ihre Standardstartmethode trennen und optimieren, um keine Intent-Parameter zu verwenden.quelle
getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
egal ob ich eine Aktivität von einer anderen Aktivität aus starte (startActivity-Methode) oder sie vom Verlaufsstapel (aktuelle Apps) erneut öffne.Löscht einen Vorsatz Objekt :
quelle
Kurze Antwort ist auf keinen Fall
Lange Antwort. Es gibt keine "One-Shot" -Absicht. Aus Experimenten geht hervor, dass die jüngste Aktivitätsgeschichte in modernen Androiden nichts anderes als "Absichtsgeschichte" ist. Die letzte Absicht, die an die Aktivität übergeben wurde, wird einfach im System angemeldet, und das ist der Deal. Die oben genannten Personen empfehlen die Verwendung
Dies funktioniert jedoch nicht, da die Absicht bereits protokolliert ist, bis Sie sie in der Methode onNewIntent () oder onStart () erhalten.
Ich habe das Problem gelöst, indem ich die Verwendung von Absichten vermieden habe. Mein Problem war dem des Autors ähnlich. Ich habe versucht, Global Exit aus der Anwendung über die Steuerung im Benachrichtigungsbereich zu implementieren. Es sollte den zugrunde liegenden Dienst stoppen und alle Aktivitäten der App schließen. Sie können das gleiche Verhalten in der Waze-Anwendung finden.
Der Algorithmus:
Ich hoffe, das hilft jemandem, weil ich die Antwort im Internet nicht gefunden habe.
quelle
Stellen Sie sicher, dass Sie das PendingIntent.FLAG_UPDATE_CURRENT- Flag für PendingIntent verwenden .
Wo
mPutIntent
ist IhrIntent
.Hoffe das wird dir helfen.
quelle
Ich hatte kürzlich dieses Problem und habe es gelöst, indem ich der Absicht einen Zeitstempel als zusätzlichen Parameter hinzugefügt habe:
Speichern Sie danach den Zeitstempel in den freigegebenen Einstellungen:
quelle
Ich habe genau das gleiche Problem. Meine Lösung bestand darin, eine
boolean
Variable hinzuzufügen , die festgelegt wurde, als sieIntent
verwendet wurde, und eine daraufif
basierende Anweisung, umboolean
zu überprüfen, ob Sie sie verwenden solltenIntent
oder nicht.quelle
Wenn Sie mit der Verarbeitung der Absicht fertig sind, gehen Sie folgendermaßen vor:
Sie werden diese verarbeitete Absicht nicht wieder sehen und das Problem nicht maskieren, indem Sie den Inhalt der verarbeiteten Absicht bearbeiten.
quelle
Ich konnte Intent Extra nicht entfernen . Keine der Antworten zum Entfernen von Extra aus der Absicht funktioniert, wenn Sie "Aktivitäten nicht beibehalten " in den Entwickleroptionen aktivieren (auf diese Weise können Sie die Aktivität zerstören und erneut testen, ob noch Extras vorhanden sind).
Als Lösung für das Problem habe ich einen booleschen Wert in SharedPreferences gespeichert, nachdem Intent Extras verarbeitet wurden. Wenn dieselbe Absicht erneut an die Aktivität gesendet wird, überprüfe ich den SharedPreference-Wert und entscheide mich, die Absichts-Extra zu verarbeiten. Wenn Sie ein weiteres neues Intent Extra an dieselbe Aktivität senden, setzen Sie den SharedPreference-Wert auf false und Activity verarbeitet ihn. Beispiel :
quelle
Selbst nachdem die Extras Intent und Intent nach dem Analysieren manuell gelöscht wurden, scheint es, als würde Activity.getIntent () immer die ursprüngliche Absicht zurückgeben, mit der die Aktivität gestartet wurde.
Um dies zu umgehen, empfehle ich Folgendes:
Auf diese Weise gibt es einen Mechanismus zum Speichern der ursprünglichen Absicht, während die Möglichkeit erhalten bleibt, bestimmte Teile der ursprünglichen Absicht / Absicht-Extras explizit beizubehalten.
Beachten Sie, dass ich nicht alle Aktivitätsstartmodi getestet habe.
quelle
Der einfache Weg besteht darin, zu vermeiden, dass getIntent () von anderen Methoden als onCreate () aufgerufen wird. Dies führt jedoch beim nächsten Start zu Problemen, wenn der Benutzer unsere Aktivität durch Tippen auf die Home-Schaltfläche verlassen hat. Ich denke, dieses Problem hat keine voll funktionsfähige Lösung.
quelle
Ich stelle mich dem gleichen Problem und versuche, die oben genannten Methoden zu verwenden, aber es funktioniert nicht.
Ich denke, es könnte an dem Startmodus von acitvity liegen, den ich im singleTop-Modus verwendet habe.
Wenn ich eine Hintergrund-App verwende und RamEater verwende, um ein Problem zu simulieren, hat diese Absicht immer ein Extra, auch wenn ich sie auf Null setze oder den Schlüssel entferne.
Das Problem ist behoben, indem der Voreinstellungsspeicher auf Android verwendet wird, um zu überprüfen, ob der Durchgang erfolgt ist.
quelle
Es ist keine gute Praxis, ein weiteres Extra hinzuzufügen, nur um zu wissen, ob die Extras verbraucht wurden oder nicht. Warum nicht?:
quelle
Wie wäre es damit? Legt newIntent als Absicht fest.
quelle
Wie wäre es, wenn Sie die Absicht löschen möchten - ersetzen Sie sie durch eine leere?
z.B.
quelle
Dies wird hoffentlich allen helfen. Also bekommen wir zuerst die Absicht
Platziere dies irgendwo auf Create
Stellen Sie dies jetzt so ein, dass jedes Mal, wenn unsere App zerstört oder beendet wird, die Daten entfernt werden
Sie haben die Idee, wenn dies nicht ausreicht, finden Sie einfach weitere "on" -Rückrufe
quelle
Während das
Intent.removeExtra("key")
einen bestimmten Schlüssel aus den Extras entfernt, gibt es auch die Methode Intent.replaceExtras (Bundle) , mit der die gesamten Extras aus dem Intent gelöscht werden können, wenn sienull
als Parameter übergeben werden.Aus den Dokumenten:
Da die putXXX () -Methoden die Extras mit einem neuen Bundle initialisieren, wenn es null ist, ist dies kein Problem.
quelle
quelle