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?
android
android-intent
Mars
źródło
źródło
Odpowiedzi:
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:
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.
źródło
setIntent(new Intent())
i teraz działa dobrze.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
boolean
w swoim,Activity
aby wskazać, czyIntent
został już zużyty:Następnie bezpiecznie zapisz i przywróć tę wartość przy użyciu metod
onSaveInstanceState
ionCreate
, aby obsłużyć zmiany konfiguracji i przypadki, które system może zabić,Activity
gdy przejdzie w tło.Teraz sprawdź, czy możesz uruchomić kod w
onResume
metodzie.Ponadto, jeśli masz
Activity
skonfigurowaną opcjęsingleTop
, powinieneś zresetować flagę, gdyIntent
zostanie dostarczona nowa .źródło
(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.boolean shouldThisIntentTriggerMyCode = [...];
z odpowiedzi (do czego służy?)consumedIntent
któryString
zawiera identyfikator powiadomienia. Ten identyfikator UID można po prostu dodać do powiadomienia na zapleczu jako bieżący znacznik czasu. Powinieneś także zapisać ten UidonSaveInstanceState
tylko wtedy, gdy zamiar się pojawiałonCreate
. Oznacza to, że nie powinieneś ratować Uid przedonNewIntent
.Odpowiedź Maks działa, aby usunąć dodatkowe:
Kolejnym przydatnym poleceniem jest:
Możesz również oznaczyć intencję, dzwoniąc:
a następnie po prostu sprawdź wartość.
źródło
Kiedy uruchamiamy aplikacje na Androida z Historii (ostatnie aplikacje), aplikacja może być uruchamiana przede wszystkim z trzema różnymi flagami intencji.
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)
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)
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
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()
lubonResume()
metod.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.źródło
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).Czyszczenie obiektu intencji :
źródło
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
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:
Mam nadzieję, że komuś to pomoże, bo nie znalazłem odpowiedzi w internecie.
źródło
Upewnij się, że używasz PendingIntent.FLAG_UPDATE_CURRENT flagę PendingIntent .
Gdzie
mPutIntent
jest twójIntent
.Mam nadzieję, że to ci pomoże.
źródło
Niedawno miałem ten problem i rozwiązałem go, dodając znacznik czasu jako dodatkowy parametr do celu:
Następnie zapisz sygnaturę czasową we wspólnych preferencjach:
źródło
Mam dokładnie ten sam problem. Moje rozwiązanie polegało na dodaniu
boolean
zmiennej, która była ustawiona, kiedyIntent
była „używana” iif
opartej na niej instrukcji,boolean
aby sprawdzić, czy należy jej użyć,Intent
czy nie.źródło
Po zakończeniu przetwarzania intencji wykonaj następujące czynności:
Nie zobaczysz ponownie przetworzonej intencji i nie będziesz maskować problemu, edytując zawartość przetworzonej intencji.
źródło
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 :
źródło
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:
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.
źródło
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.
źródło
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ł.
źródło
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 ?:
źródło
Co powiesz na to? Ustawia newIntent jako zamiar.
źródło
A co, jeśli chcesz wyczyścić zamiar - zastąpić go pustym?
na przykład.
źródło
Miejmy nadzieję, że pomoże to wszystkim. Więc najpierw mamy zamiar
Umieść to gdzieś na Create
Teraz ustawmy to tak, aby za każdym razem, gdy nasza aplikacja zostanie zniszczona lub zamknięta, usuniemy dane
Masz pomysł, jeśli to nie wystarczy, po prostu znajdź więcej połączeń zwrotnych „na”
źródło
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ślinull
zostanie przekazana jako parametr.Z dokumentów:
Ponieważ metody putXXX () inicjalizują dodatki nowym pakietem, jeśli jego wartość jest pusta, nie stanowi to problemu.
źródło
źródło