Clearing-Absicht

110

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?

Mars
quelle
Können Sie Ihre Codes posten?
Xandy
Ich habe den Code zu meiner Frage hinzugefügt
Mars
Anstatt Intent zu löschen, können Sie den Starttyp bestimmen und den App-Flow entsprechend behandeln. Erhalten Sie die Extras nur, wenn sie für die Benachrichtigung gestartet wurden und nicht aus dem Hintergrund. stackoverflow.com/questions/4116110/clearing-intent/…
BB

Antworten:

168

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:

getIntent().removeExtra("key"); 

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.

Maks
quelle
4
Nimmt die Methode removeExtra () keinen String-Parameter an? wie dieses getIntent (). removeExtra ("String");
Tony9099
25
@Maks Ich könnte mich irren, aber ich denke, dass dies im folgenden Szenario nicht funktioniert: 1) Öffnen Sie die Aktivität über die Benachrichtigung. 2) Beenden Sie die Aktivität durch Drücken der Zurück-Taste. 3) Öffnen Sie die Aktivität erneut über den Verlauf (Letzte Apps). Ein anderer Fall ist, wenn das System die App aufgrund fehlender Ressourcen beendet (aktivieren Sie "Keine Aktivitäten beibehalten" unter den Entwickleroptionen und drücken Sie danach einfach auf "Home" und öffnen Sie die Aktivität erneut im Verlauf). Ich habe die Lösung, die ich verwende, unten veröffentlicht. Wenn Sie dies kommentieren könnten, wäre schön.
tato.rodrigo
2
Leider funktioniert es bei uns nicht. Wir stellen fest, dass das Starten einer neuen Aktivität, die wiederum die anfängliche Aktivität startet, dazu führt, dass OnNewIntent mit derselben Absicht erneut ausgelöst wird.
Le-roy Staines
2
Anstatt Intent zu löschen, können Sie den Starttyp bestimmen und den App-Flow entsprechend behandeln. Erhalten Sie die Extras nur, wenn sie für die Benachrichtigung gestartet wurden und nicht aus dem Hintergrund. stackoverflow.com/questions/4116110/clearing-intent/…
BB
2
Hat bei mir nicht funktioniert. Ich hatte das gleiche Problem wie @ tato.rodrigo, bei dem die Absicht nicht gelöscht wurde, wenn die Aktivität durch Benachrichtigung oder aus dem Verlauf oder aus anderen von ihm genannten Gründen geöffnet wurde. Nachdem ich die Absichtsinformationen verbraucht hatte, setzte ich die Absicht wie folgt zurück Dies setIntent(new Intent())und es funktioniert jetzt gut.
Shubhral
42

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 booleanin Ihrem Activityan, um anzugeben, ob das Intentbereits verbraucht wurde:

    private boolean consumedIntent;

Speichern Sie diesen Wert dann sicher und stellen Sie ihn mithilfe der Methoden onSaveInstanceStateund wieder her onCreate, um Konfigurationsänderungen und Fälle zu behandeln, in denen das System Sie möglicherweise Activityim Hintergrund tötet .

    private final String SAVED_INSTANCE_STATE_CONSUMED_INTENT = "SAVED_INSTANCE_STATE_CONSUMED_INTENT";

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(SAVED_INSTANCE_STATE_CONSUMED_INTENT, consumedIntent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //set content view ...

        if( savedInstanceState != null ) {
            consumedIntent = savedInstanceState.getBoolean(SAVED_INSTANCE_STATE_CONSUMED_INTENT);
        }

        //other initializations
    }

Überprüfen Sie nun, ob Sie Ihren Code unter onResumemethod ausführen können .

    @Override
    protected void onResume() {
        super.onResume();

        //check if this intent should run your code
        //for example, check the Intent action
        boolean shouldThisIntentTriggerMyCode = [...];
        Intent intent = getIntent();
        boolean launchedFromHistory = intent != null ? (intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0 : false;
        if( !launchedFromHistory && shouldThisIntentTriggerMyCode && !consumedIntent ) {
            consumedIntent = true;
            //execute the code that should be executed if the activity was not launched from history
        }
    }

Wenn Sie Activityfür konfiguriert sind singleTop, sollten Sie außerdem Ihr Flag zurücksetzen, wenn ein neues Intentausgeliefert wird.

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        consumedIntent = false;
    }
tato.rodrigo
quelle
12
Vielen Dank! Ich habe diesem Code geholfen, (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.
Roman Nazarevych
1
@Lemberg Ich habe das gleiche Problem und habe es genau wie Sie gelöst. Wenn Sie einige Extras verwenden, die aus Push-Benachrichtigungen stammen, besteht das Risiko, dass Sie Ihre Aktivität aus dem Verlauf starten und Ihre Extras immer verbrauchen und zu derselben Aktion wie Ihrer umleiten Push-Benachrichtigung. Die Flagge aus der Geschichte kann Ihnen helfen, dies zu wissen
Stoycho Andreev
Wird es funktionieren, auch wenn die Aktivität zerstört wurde und wir sie erneut aus dem Verlaufsstapel öffnen?
Benutzer25
großartig! es scheint zu funktionieren, auch wenn die App zerstört wurde ... aber bitte @ tato.rodrigo boolean shouldThisIntentTriggerMyCode = [...];aus der Antwort entfernen (wofür wird verwendet?)
user25
In meinem Fall mit Mehrfachbenachrichtigungen für bestimmte Benutzer ist es besser, consumedIntentwenn Stringder 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 Uid onSaveInstanceStatenur speichern, wenn die Absicht vorliegt onCreate. Dies bedeutet, dass Sie Uid nicht vor speichern sollten onNewIntent.
Konstantin Konopko
22

Maks Antwort funktioniert zum Löschen eines Extra:

    getIntent().removeExtra("key"); 

Ein weiterer nützlicher Befehl ist:

    getIntent().setAction("");

Sie können eine Absicht auch markieren, indem Sie Folgendes aufrufen:

    getIntent().putExtra("used", true);

und dann einfach auf den Wert prüfen.

Slynk
quelle
21

Wenn wir Android-Apps aus dem Verlauf (Aktuelle Apps) starten, kann die App hauptsächlich mit drei verschiedenen Intent-Flags gestartet werden.

  1. 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)
  2. 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)
  3. 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

 <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER"/>
 </intent-filter>

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()oder onResume()Methoden.

if(getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)) {
    //app is launched from recent apps after it was closed
        normalLaunch();
    } else {
        String intentAction = getIntent().getAction();
        String scheme = getIntent().getScheme();
        //app is launched via other means
        // URL intent scheme, Intent action etc
        if("https".equalsIgnoreCase(scheme)) {
            // URL intent for browser
        } else if("com.example.bb".equalsIgnoreCase(intentAction)) {
            // App launched via package name
        } else {
            // App was launched via Click on App Icon, or other means
            normalLaunch();
        }
    }

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.

BB
quelle
1
Nicht alle Helden tragen Mützen!
Sdghasemi
Ich weiß es nicht, aber es gibt immer true zurück, getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORYegal ob ich eine Aktivität von einer anderen Aktivität aus starte (startActivity-Methode) oder sie vom Verlaufsstapel (aktuelle Apps) erneut öffne.
Benutzer25
Sie müssten es in Kombination mit anderen Flags verwenden, vielleicht FLAG_ACTIVITY_NEW_TASK
BB
1
Dies funktioniert nicht, wenn die Aktivität im Hintergrund aufgrund der Dev-Einstellungen "Aktivitäten nicht beibehalten" beendet wurde. In diesem Fall ist getIntent () getFlags () identisch mit dem Zeitpunkt, zu dem die Aktivität zum ersten Mal gestartet wurde.
Malachiasz
schätzen die Erklärung, aber es ist nicht wie beabsichtigt
Azlan Jamal
18

Löscht einen Vorsatz Objekt :

intent.replaceExtras(new Bundle());
intent.setAction("");
intent.setData(null);
intent.setFlags(0);
Mickey Tin
quelle
2
Dies sollte die akzeptierte Antwort sein. Funktioniert wirklich gut!
Martin Erlic
2
Funktioniert nicht, wenn "Aktivitäten nicht
beibehalten
8

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

setAction("")

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:

  1. Erstellen Sie PendingIntent für die Benachrichtigungssteuerung, die die Aktion "Beenden" an die Aktivität übergibt. Aber zu der besonderen Aktivität, die ein einfacher Proxy ist.
  2. Die Proxy-Aktivität onStart () analysiert die Absicht, überprüft die Aktion und setzt den Status eines Modells auf "Beendet".
  3. Der Code für die Proxy-Aktivität onStart () löscht die ursprüngliche Absicht mit setIntent ("") und leitet sie dann durch Aufrufen von startActivity (intent) an die Zielaktivität "Root" weiter.
  4. Proxy-Aktivität onStart () Code ruft finish () auf.
  5. Überprüfen Sie in onStart () und onNewIntent () der Zielaktivität den Modellstatus und rufen Sie finish () auf, wenn es "Beendet" ist (und rufen Sie in meinem Fall auch stopService () auf).

Ich hoffe, das hilft jemandem, weil ich die Antwort im Internet nicht gefunden habe.

Eugene Wechsler
quelle
Ich finde dies die genaueste Antwort, da "Löschen der Absicht" nicht unbedingt "bestimmte zusätzliche entfernen" bedeutet. Ich glaube auch nicht, dass es einen einfachen Weg gibt, das zu tun.
Mdelolmo
5

Stellen Sie sicher, dass Sie das PendingIntent.FLAG_UPDATE_CURRENT- Flag für PendingIntent verwenden .

PendingIntent pendingIntent = PendingIntent.getActivity(this, 100, mPutIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Wo mPutIntentist Ihr Intent.

Hoffe das wird dir helfen.

Hiren Patel
quelle
1
hat mein Leben gerettet !!
eren130
1
Ich verstehe nicht, dass dies nicht die akzeptierte Antwort ist. Ich bedaure nur eins: eine einzige Gegenstimme. Prost.
Andy
2

Ich hatte kürzlich dieses Problem und habe es gelöst, indem ich der Absicht einen Zeitstempel als zusätzlichen Parameter hinzugefügt habe:

private void launchActivity(Context context) {
    Intent intent = new Intent(context, MainActivity.class);
    intent.putExtra("KEY_EXTRA_TIMESTAMP", System.currentTimeMillis());
    context.startActivity(intent);
}

Speichern Sie danach den Zeitstempel in den freigegebenen Einstellungen:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    long time = getIntent().getLongExtra("KEY_EXTRA_TIMESTAMP", -1);
    long previousTime = getPreferences(MODE_PRIVATE).getLong("timestamp", -1);

    //ignore if the timestamp is the same as the previous one  
    if (time != previousTime) {
        handleIntent(getIntent());
        if (time != -1) {
            //save the timestamp
            getPreferences(MODE_PRIVATE).edit().putLong("timestamp", time).apply();
        }
    }
}
Antonio Martínez Guerola
quelle
1

Ich habe genau das gleiche Problem. Meine Lösung bestand darin, eine booleanVariable hinzuzufügen , die festgelegt wurde, als sie Intentverwendet wurde, und eine darauf ifbasierende Anweisung, um booleanzu überprüfen, ob Sie sie verwenden sollten Intentoder nicht.

Pixel
quelle
3
Dies funktioniert möglicherweise nicht, da die booleschen Werte neu erstellt werden (wenn sie in der Aktivität als global deklariert sind), wenn die Aktivität gestoppt und dann neu gestartet wird. (Klicken Sie zum Beispiel auf die Home-Schaltfläche)
Tony9099
1

Wenn Sie mit der Verarbeitung der Absicht fertig sind, gehen Sie folgendermaßen vor:

setIntent(null);

Sie werden diese verarbeitete Absicht nicht wieder sehen und das Problem nicht maskieren, indem Sie den Inhalt der verarbeiteten Absicht bearbeiten.

streunend
quelle
1

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 :

// Start Activity with Intent Extras
Intent intent = new Intent(context, MyActivity.class);
intent.putExtra("someData", "my Data");
// Set data as not processed
context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE).edit().putBoolean("myActivityExtraProccessed", false).commit();
context.startActivity(intent);

...

public class MyActivity{

    ...
    public void someMethod(){
        boolean isExtrasProcessed = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE).getBoolean("myActivityExtraProccessed", false);  
         if (!isExtrasProcessed) {
              // Use Extras

              //Set data as processed
              context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE).edit().putBoolean("myActivityExtraProccessed", true).commit();
         }
    }

}
Jemshit Iskenderov
quelle
Präferenz macht keinen Sinn, da Sie nicht wissen, ob Sie die Aktivität mit startActivity gestartet oder vom Verlaufsstapel aus wieder geöffnet haben ...
user25
@ user25 Ich denke, es gab eine Möglichkeit zu erkennen, ob es von den letzten Apps gestartet wird. Aber spielt es eine Rolle, ob Intention Extra entweder konsumiert wird oder nicht, wenn es konsumiert wird und Sie es aus gemeinsamen Einstellungen kennen. Ich habe dies verwendet, um zusätzliche Push-Benachrichtigungen zu konsumieren, und es spielt keine Rolle, wie die Aktivität für meinen Fall geöffnet wird.
Jemshit Iskenderov
0

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:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // The Intent provided by getIntent() (and its extras) will persist through a restore
    // via savedInstance.  Because of this, restoring this activity from a
    // an instance that was originally started with extras (deep-link or 
    // pre-defined destination) may cause un-desired behavior
    // (ie...infinite loop of sending the user directly to somewhere else because of a
    // pre-defined alternate destination in the Intent's extras).
    //
    // To get around this, if restoring from savedInstanceState, we explicitly
    // set a new Intent *** to override the original Intent that started the activity.***
    // Note...it is still possible to re-use the original Intent values...simply
    // set them in the savedInstanceState Bundle in onSavedInstanceState.
    if (savedInstanceState != null) {
        // Place savedInstanceState Bundle as the Intent "extras"
        setIntent(new Intent().putExtras(savedInstanceState));
    }

    processIntent(getIntent())
}

private void processIntent(Intent intent) {
    if (getIntent().getExtras() == null) {
        // Protection condition
        return;
    }

    doSomething(intent.getExtras.getString("SOMETHING_I_REALLY_NEED_TO_PERSIST"));

    final String somethingIDontWantToPersist = 
        intent.getExtras.getString("SOMETHING_I_DONT_WANT_TO_PERSIST");

    if(somethingIDontWantToPersist != null) {
        doSomething(somethingIDontWantToPersist);
    }
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save selective extras from original Intent...
    savedInstanceState.putString("SOMETHING_I_REALLY_NEED_TO_PERSIST", "persistedValued");
    super.onSaveInstanceState(savedInstanceState);
}

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.

dell116
quelle
0

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.

mifthi
quelle
0

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.

Thanawat Masileerungsri
quelle
0

Es ist keine gute Praxis, ein weiteres Extra hinzuzufügen, nur um zu wissen, ob die Extras verbraucht wurden oder nicht. Warum nicht?:

if (intent.hasExtra(EXTRA_NAME) && intent.getBooleanExtra(EXTRA_NAME, false)) {
    // consume extra here after that set it to false
    putExtra(EXTRA_NAME, false)
}   
Gilbert Parreno
quelle
-1

Wie wäre es damit? Legt newIntent als Absicht fest.

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}
coolcool1994
quelle
1
Ich denke nicht, dass das funktioniert. Wenn die Aktivität aus der Geschichte neu erstellt wird, bleibt die Absicht unberührt.
Mdelolmo
-1

Wie wäre es, wenn Sie die Absicht löschen möchten - ersetzen Sie sie durch eine leere?

z.B.

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}

@Override 
public void onResume() {
    super.onResume();

    Intent theIntent = getIntent();
    if ("myaction".equals(theIntent.getAction()) {
         handleIntent();
         onNewIntent(new Intent());  // <--- "clear" the intent by setting empty one
    }
}
Iftah
quelle
-1

Dies wird hoffentlich allen helfen. Also bekommen wir zuerst die Absicht

//globally
Intent myIntent;

Platziere dies irgendwo auf Create

myIntent = getIntent();
String data = myIntent.getStringExtra("yourdata");
//Your process here

Stellen Sie dies jetzt so ein, dass jedes Mal, wenn unsere App zerstört oder beendet wird, die Daten entfernt werden

@Override
protected void onDestroy() {
    //TODO: Clear intents
    super.onDestroy();
    myIntent.removeExtra("data");
}
@Override
protected void onBackPressed() {
    //TODO: Clear intents
    super.onBackPressed();
    myIntent.removeExtra("data");
}

Sie haben die Idee, wenn dies nicht ausreicht, finden Sie einfach weitere "on" -Rückrufe

Pixeldroid Modding
quelle
Die Absicht wird erst gelöscht, wenn Sie die App beenden, z. Wischen Sie die letzten.
Pixeldroid Modding
-2

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 sie nullals Parameter übergeben werden.

Aus den Dokumenten:

Ersetzen Sie die Extras in der Absicht vollständig durch das angegebene Paket von Extras.

Parameter
Extras Der neue Satz von Extras in der Absicht oder null, um alle Extras zu löschen.

Da die putXXX () -Methoden die Extras mit einem neuen Bundle initialisieren, wenn es null ist, ist dies kein Problem.

Steve Benett
quelle
-3
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
intent.addCategory(Intent.CATEGORY_HOME);  
startActivity(intent);
Ramkumar
quelle
2
Sie sollten erwägen, Ihre Antwort näher zu erläutern, indem Sie einige Details darüber angeben, was Sie tun und wie die Frage des OP beantwortet wird.
Forsvarir
1
@ Ramkumar Dies bringt den Benutzer nach Hause. Dies ist eindeutig nur ein Einzelfall von 10000 Fällen, die dazu führen können, dass onPause, onStop oder onDestroy aufgerufen werden.
Tony9099
Dies hat nicht einmal im Zusammenhang mit der Frage
Hossein Shahdoost