Zamiar rozliczeń

111

Moja aplikacja na Androida jest wywoływana z powodu zamiaru przekazywania informacji (oczekiwanie na pasku stanu).

Kiedy naciskam przycisk home i ponownie otwieram aplikację, przytrzymując przycisk home, ponownie wywołuje intencję i nadal są tam te same dodatki.

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
      super.onSaveInstanceState(savedInstanceState);
    }
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
      super.onRestoreInstanceState(savedInstanceState);
    }

to jest kod, który nie działa tak, jak powinien

    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

        }

    }

I mój zamiar:

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

Czy istnieje sposób, aby wyczyścić zamiar lub sprawdzić, czy był używany wcześniej?

Mars
źródło
Czy możesz wysłać swoje kody?
xandy,
Dodałem kod do mojego pytania
Mars
Zamiast czyścić zamiar, możesz określić typ uruchomienia i odpowiednio obsłużyć przepływ aplikacji. Pobierz dodatki tylko wtedy, gdy jest uruchamiany w celu powiadomienia, a nie w tle. stackoverflow.com/questions/4116110/clearing-intent/ ...
BB

Odpowiedzi:

168

AKTUALIZACJA:

Nie zdawałem sobie sprawy, że ta odpowiedź będzie tak często wymieniana, kiedy po raz pierwszy ją napisałem ponad 5 lat temu!

Wyjaśnię, aby wskazać, że zgodnie z odpowiedzią @ tato-rodrigo nie pomoże to wykryć już obsłużonej intencji w niektórych sytuacjach.

Powinienem również zwrócić uwagę, że umieściłem „jasne” w cudzysłowie z jakiegoś powodu - tak naprawdę nie oczyszczasz intencji, robiąc to, po prostu używasz usunięcia tego dodatku jako flagi, że ten zamiar został już zauważony przez działanie .


Miałem dokładnie ten sam problem.

Powyższa odpowiedź postawiła mnie na właściwej drodze i znalazłem jeszcze prostsze rozwiązanie, użyj:

getIntent().removeExtra("key"); 

wywołanie metody, aby „wyczyścić” intencję.

Trochę za późno udzielam odpowiedzi, ponieważ zadano to rok temu, ale mam nadzieję, że pomoże to innym w przyszłości.

Maks
źródło
4
czy metoda removeExtra () nie przyjmuje parametru typu String? w ten sposób getIntent (). removeExtra ("String");
tony9099,
25
@Maks Mogę się mylić, ale myślę, że to nie zadziała w następującym scenariuszu: 1) Otwórz działanie poprzez powiadomienie; 2) Zakończ czynność, naciskając przycisk Wstecz; 3) Ponownie otwórz aktywność w Historii (ostatnie aplikacje). Innym przypadkiem jest sytuacja, gdy system zabija aplikację z powodu braku zasobów (włącz opcję „Nie przechowuj działań” w opcjach programisty, a następnie po prostu naciśnij przycisk ekranu głównego i ponownie otwórz aktywność z Historii). Poniżej zamieściłem rozwiązanie, którego używam. Byłoby miło, gdybyś mógł to skomentować.
tato.rodrigo
2
Niestety u nas to nie działa. Odkrywamy, że rozpoczęcie nowego działania, które z kolei rozpoczyna działanie początkowe, powoduje ponowne uruchomienie OnNewIntent z tym samym zamiarem.
Le-roy Staines
2
Zamiast czyścić zamiar, możesz określić typ uruchomienia i odpowiednio obsłużyć przepływ aplikacji. Pobierz dodatki tylko wtedy, gdy jest uruchamiany w celu powiadomienia, a nie w tle. stackoverflow.com/questions/4116110/clearing-intent/…
BB
2
Nie działa dla mnie. Miałem do czynienia z tym samym problemem, o którym wspomniał @ tato.rodrigo, w którym zamiar nie został wyczyszczony, jeśli aktywność została otwarta przez powiadomienie lub z historii lub z innych powodów, o których wspomniał, więc po zużyciu informacji o zamiarze zresetowałem zamiar to setIntent(new Intent())i teraz działa dobrze.
Shubhral
43

EDYCJA: Edytuję, aby opublikować kompletne rozwiązanie, którego używam.

To rozwiązanie zadziała, jeśli problemem jest „Nie wykonuj kodu, gdy aktywność zaczyna się od Historii (ostatnie aplikacje)” .

Przede wszystkim zadeklaruj booleanw swoim, Activityaby wskazać, czy Intentzostał już zużyty:

    private boolean consumedIntent;

Następnie bezpiecznie zapisz i przywróć tę wartość przy użyciu metod onSaveInstanceStatei onCreate, aby obsłużyć zmiany konfiguracji i przypadki, które system może zabić, Activitygdy przejdzie w tło.

    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
    }

Teraz sprawdź, czy możesz uruchomić kod w onResumemetodzie.

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

Ponadto, jeśli masz Activityskonfigurowaną opcję singleTop, powinieneś zresetować flagę, gdy Intentzostanie dostarczona nowa .

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        consumedIntent = false;
    }
tato.rodrigo
źródło
12
Wielkie dzięki! Pomogłem w tym kodzie, (intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)więc teraz mogę dowiedzieć się, kiedy początek działania jest z historii i mogę zignorować moje dodatki.
Roman Nazarevych
1
@Lemberg Mam ten sam problem i rozwiązałem tak jak Ty, jeśli korzystasz z jakichś dodatków, które pochodziły z powiadomień push, istnieje ryzyko, że zaczniesz swoją aktywność od historii, a poza tym zużyjesz swoje dodatki i przekierujesz do tej samej akcji, co Twoja aktywne powiadomienie. Flaga uruchomionaFromHistory może pomóc ci to wiedzieć
Stoycho Andreev
czy to zadziała, nawet jeśli aktywność zostanie zniszczona i ponownie otworzymy ją ze stosu historii?
user25
świetny! wygląda na to, że działa, nawet jeśli aplikacja została zniszczona ... ale proszę @ tato.rodrigo usuń boolean shouldThisIntentTriggerMyCode = [...];z odpowiedzi (do czego służy?)
user25
W moim przypadku z wieloma powiadomieniami dla określonego użytkownika jest to lepszy użytkownik, consumedIntentktóry Stringzawiera identyfikator powiadomienia. Ten identyfikator UID można po prostu dodać do powiadomienia na zapleczu jako bieżący znacznik czasu. Powinieneś także zapisać ten Uid onSaveInstanceStatetylko wtedy, gdy zamiar się pojawiał onCreate. Oznacza to, że nie powinieneś ratować Uid przed onNewIntent.
Konstantin Konopko,
22

Odpowiedź Maks działa, aby usunąć dodatkowe:

    getIntent().removeExtra("key"); 

Kolejnym przydatnym poleceniem jest:

    getIntent().setAction("");

Możesz również oznaczyć intencję, dzwoniąc:

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

a następnie po prostu sprawdź wartość.

Slynk
źródło
21

Kiedy uruchamiamy aplikacje na Androida z Historii (ostatnie aplikacje), aplikacja może być uruchamiana przede wszystkim z trzema różnymi flagami intencji.

  1. FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
    Dzieje się tak, gdy aktywność jest uruchamiana z historii aplikacji, która została zminimalizowana (długie naciśnięcie klawisza Home).
    Wartość stała: 1048576 (0x00100000)
  2. FLAG_ACTIVITY_NEW_TASK
    Dzieje się tak, gdy aktywność jest uruchamiana poprzez „kliknięcie ikony aplikacji” lub za pomocą „ filtrów intencji ”. Tutaj aktywność stanie się początkiem nowego zadania na tym stosie historii.
    Stała wartość: 268435456 (0x10000000)
  3. FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY | FLAG_ACTIVITY_NEW_TASK
    To wtedy aplikacja została zamknięta przez naciśnięcie przycisku Wstecz, a następnie wznowiona z Historii (ostatnie aplikacje).
    Wartość stała: 269484032 (0x10100000)

Stałą wartość można pobrać za pomocą getIntent().getFlags()

W trzecim przypadku Android przeładowuje ostatnie wartości Intent ze swojej pamięci. Tak więc intencja Twojej aplikacji ( getIntent) będzie miała wartości z ostatniej intencji, która uruchomiła aplikację.

W rzeczywistości aplikacja powinna zachowywać się tak, jakby była nowym uruchomieniem, z wartościami intencji dla nowego uruchomienia zamiast wartości intencji z poprzedniego uruchomienia. To zachowanie można zobaczyć, jeśli uruchomisz aplikację, klikając ikonę aplikacji, nigdy nie będzie ona miała starych wartości intencji. Dzieje się tak, ponieważ system Android używa następującego filtru intencji w tym scenariuszu

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

Ale w trzecim przypadku (aplikacja, która została zamknięta, jest uruchamiana z Historii ostatnich aplikacji), system operacyjny Android wykorzystuje tę ostatnią intencję, która uruchomiła aplikację przed jej zamknięciem (poprzez naciśnięcie przycisku Wstecz). W rezultacie otrzymujesz stare wartości intencji, a przepływ aplikacji nie jest właściwy.

Usunięcie zamiaru jest jednym ze sposobów rozwiązania tego problemu, ale nie rozwiązałoby problemu całkowicie! Ponieważ system operacyjny Android ponownie ładuje intencję z ostatniego uruchomienia aplikacji, a nie ostatnią instancję zamiaru uruchomienia.

Prostym sposobem uniknięcia tego jest radzenie sobie z tym poprzez uzyskanie typu intencji w celu określenia typu uruchomienia.

Więc w LaunchActivity (ten, który ma filtr zamiaru zdefiniowane w manifeście), można użyć następującego kodu w onCreate(), onStart()lub onResume()metod.

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

Zakładam normalLaunch(), że nie powinienem używać parametrów z Intencji; w przeciwnym razie musiałbyś posegregować i zoptymalizować domyślną metodę uruchamiania, aby nie używać parametrów Intent.

nocleg ze śniadaniem
źródło
1
Nie wszyscy bohaterowie noszą czapki!
Sdghasemi
Nie wiem, ale zawsze zwraca wartość true getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY, niezależnie od tego, czy rozpocznę aktywność od innej czynności (metoda startActivity), czy ponownie ją otworzę ze stosu historii (ostatnie aplikacje).
user25
musiałbyś użyć go w połączeniu z innymi flagami, być może FLAG_ACTIVITY_NEW_TASK
BB
1
To nie działa, gdy aktywność została zabita w tle z powodu ustawień Dev „Nie zachowuj aktywności”. W tym przypadku getIntent () getFlags () działa tak samo, jak wtedy, gdy działanie zostało uruchomione po raz pierwszy.
Malachiasz
doceniam wyjaśnienie, ale nie jest zgodne z zamierzeniem
Azlan Jamal
18

Czyszczenie obiektu intencji :

intent.replaceExtras(new Bundle());
intent.setAction("");
intent.setData(null);
intent.setFlags(0);
Mickey Tin
źródło
2
To powinna być akceptowana odpowiedź. Działa naprawdę dobrze!
Martin Erlic
2
Nie działa, gdy w opcjach programisty zaznaczono opcję „nie zachowuj aktywności”
Jemshit Iskenderov
8

Krótka odpowiedź brzmi: nie ma mowy

Długa odpowiedź. Nie ma czegoś takiego jak zamiar „jednorazowy”. Z eksperymentu można zaobserwować, że najnowsza historia aktywności we współczesnych Androidach to nic innego jak „Historia intencji”. Ostatni zamiar przekazany do działania jest po prostu zalogowany do systemu i to jest umowa. Osoby powyżej sugerują użycie

setAction("")

Ale to nie działa, ponieważ intencja jest już zarejestrowana do momentu, gdy ją otrzymasz w metodzie onNewIntent () lub onStart ().

Rozwiązałem problem unikając używania intencji. Mój problem był podobny do tego, który opublikował autor. Próbowałem zaimplementować Global Exit z aplikacji poprzez kontrolę w obszarze powiadomień. Powinien zatrzymać usługę bazową i zamknąć wszystkie działania aplikacji. Możesz znaleźć to samo zachowanie w aplikacji Waze.

Algorytm:

  1. Utwórz PendingIntent dla kontroli powiadomień, która przekazuje akcję „Exit” do działania. Ale do specjalnej działalności, która jest prostym proxy.
  2. Aktywność proxy w kodzie Start () analizuje intencję, sprawdza działanie i ustawia stan modelu na „Wyjście”.
  3. Aktywność proxy onStart () czyści pierwotną intencję za pomocą metody setIntent („”), a następnie przekazuje ją do docelowego działania „Root”, wywołując startActivity (intent).
  4. Aktywność proxy onStart () kod invoke finish ().
  5. Wewnątrz onStart () i onNewIntent () aktywności docelowej sprawdź stan modelu i wywołaj finish (), jeśli jest to „Exited” (aw moim przypadku także wywołanie stopService ()).

Mam nadzieję, że komuś to pomoże, bo nie znalazłem odpowiedzi w internecie.

Eugene Wechsler
źródło
Uważam, że jest to najdokładniejsza odpowiedź, ponieważ „oczyszczenie zamiaru” niekoniecznie oznacza „usunięcie pewnych dodatkowych elementów”. Myślę też, że nie ma na to prostego sposobu.
mdelolmo
5

Upewnij się, że używasz PendingIntent.FLAG_UPDATE_CURRENT flagę PendingIntent .

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

Gdzie mPutIntentjest twój Intent.

Mam nadzieję, że to ci pomoże.

Hiren Patel
źródło
1
uratował mi życie !!
eren130
1
Nie rozumiem, dlaczego to nie jest akceptowana odpowiedź. Żałuję tylko jednego: jednego głosu za. Twoje zdrowie.
Andy
2

Niedawno miałem ten problem i rozwiązałem go, dodając znacznik czasu jako dodatkowy parametr do celu:

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

Następnie zapisz sygnaturę czasową we wspólnych preferencjach:

@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
źródło
1

Mam dokładnie ten sam problem. Moje rozwiązanie polegało na dodaniu booleanzmiennej, która była ustawiona, kiedy Intentbyła „używana” i ifopartej na niej instrukcji, booleanaby sprawdzić, czy należy jej użyć, Intentczy nie.

piksel
źródło
3
to może nie zadziałać, ponieważ wartości logiczne zostaną odtworzone (jeśli zostaną zadeklarowane jako globalne w działaniu), gdy działanie zostanie zatrzymane, a następnie ponownie uruchomione. (na przykład kliknięcie przycisku strony głównej)
tony9099
1

Po zakończeniu przetwarzania intencji wykonaj następujące czynności:

setIntent(null);

Nie zobaczysz ponownie przetworzonej intencji i nie będziesz maskować problemu, edytując zawartość przetworzonej intencji.

straya
źródło
1

Nie mogłem znaleźć sposobu na usunięcie Intent Extra . Żadna z odpowiedzi na temat usuwania dodatkowych z zamiaru nie działa, jeśli włączysz „Nie zachowuj działań ” w Opcjach programisty (w ten sposób możesz zniszczyć aktywność i wrócić, aby sprawdzić, czy dodatki nadal tam są).

Jako rozwiązanie problemu zapisałem wartość logiczną w SharedPreferences po przetworzeniu Intent Extras. Kiedy ta sama intencja jest ponownie dostarczana do działania, sprawdzam wartość SharedPreference i decyduję się przetworzyć Intent Extra. W przypadku, gdy wyślesz kolejny nowy dodatek intencyjny do tego samego działania, ustaw wartość SharedPreference na false, a Activity przetworzy ją. Przykład :

// 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
źródło
preferencja nie ma sensu, ponieważ nie wiesz, czy zacząłeś aktywność za pomocą startActivity, czy też otwierasz ją ponownie ze stosu historii ...
user25
@ user25 Myślę, że był sposób na wykrycie, czy jest uruchamiany z ostatnich aplikacji. Ale czy to ma znaczenie, dodatkowa intencja jest albo konsumowana, albo nie, jeśli jest konsumowana, znasz to ze wspólnego pref. Użyłem tego do korzystania z dodatkowych powiadomień push i nie ma znaczenia, w jaki sposób zostanie otwarta aktywność dla mojej sprawy.
Jemshit Iskenderov
0

Nawet po ręcznym wyczyszczeniu intencji i dodatków Intent po ich przeanalizowaniu wydaje się, że Activity.getIntent () zawsze zwróci pierwotną intencję, która rozpoczęła działanie.

Aby to obejść, polecam coś takiego:

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

W ten sposób istnieje mechanizm umożliwiający zrzucenie pierwotnej intencji, zachowując jednocześnie możliwość wyraźnego zachowania niektórych części oryginalnych intencji / dodatków.

Zwróć uwagę, że nie przetestowałem wszystkich trybów uruchamiania Aktywności.

dell116
źródło
0

Prostym sposobem jest uniknięcie wywoływania getIntent () z metod innych niż onCreate (). Ale spowoduje to problem podczas następnego uruchomienia, jeśli użytkownik opuści naszą aktywność, dotykając przycisku Strona główna. Myślę, że ten problem nie ma w pełni funkcjonalnego rozwiązania.

mifthi
źródło
0

Stoję przed tym samym problemem i próbuję zastosować powyższe metody, ale to nie działa.

Myślę, że może to być spowodowane trybem uruchamiania aktywności, w którym użyłem trybu singleTop.

Kiedy używam aplikacji w tle i używam RamEater do symulacji problemu, że intencja zawsze ma dodatkowe, nawet jeśli ustawiam go na zero lub usuwam klucz.

Problem zniknął, używając magazynu preferencji w systemie Android, aby sprawdzić, czy przeszedł.

Thanawat Masileerungsri
źródło
0

Nie jest dobrą praktyką dodawanie kolejnych dodatków tylko po to, aby wiedzieć, czy dodatki zostały zużyte, czy nie, dlaczego nie zrobić tego ?:

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
źródło
-1

Co powiesz na to? Ustawia newIntent jako zamiar.

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}
coolcool1994
źródło
1
Myślę, że to nie działa. Kiedy czynność jest odtwarzana z historii, zamiar pozostaje niezmieniony.
mdelolmo
-1

A co, jeśli chcesz wyczyścić zamiar - zastąpić go pustym?

na przykład.

@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
źródło
-1

Miejmy nadzieję, że pomoże to wszystkim. Więc najpierw mamy zamiar

//globally
Intent myIntent;

Umieść to gdzieś na Create

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

Teraz ustawmy to tak, aby za każdym razem, gdy nasza aplikacja zostanie zniszczona lub zamknięta, usuniemy dane

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

Masz pomysł, jeśli to nie wystarczy, po prostu znajdź więcej połączeń zwrotnych „na”

Pixeldroid Modding
źródło
Zamiar zostaje wyczyszczony dopiero po wyjściu z aplikacji, np. Przesuwając ostatnie.
Pixeldroid Modding
-2

Chociaż Intent.removeExtra("key")spowoduje to usunięcie jednego określonego klucza z dodatków, istnieje również metoda Intent.replaceExtras (Bundle) , której można użyć do usunięcia całych dodatków z intencji, jeśli nullzostanie przekazana jako parametr.

Z dokumentów:

Całkowicie zamień dodatki w Zamiarze na dany Pakiet dodatków.

Parametry
dodatki Nowy zestaw dodatków w Intencji lub null, aby usunąć wszystkie dodatki.

Ponieważ metody putXXX () inicjalizują dodatki nowym pakietem, jeśli jego wartość jest pusta, nie stanowi to problemu.

Steve Benett
źródło
-3
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
intent.addCategory(Intent.CATEGORY_HOME);  
startActivity(intent);
Ramkumar
źródło
2
Powinieneś rozważyć rozwinięcie swojej odpowiedzi, podając kilka szczegółów na temat tego, co robisz i jak odpowiada ona na pytanie PO.
forsvarir
1
@Ramkumar przenosi użytkownika do domu. Jest to oczywiście tylko jeden przypadek na 10000 przypadków, które mogą spowodować wywołanie onPause, onStop lub onDestroy.
tony9099
Nie ma to nawet
najmniejszego