Мое приложение для Android вызывается намерением, которое передает информацию (ожидающее намерения в строке состояния).
Когда я нажимаю кнопку «Домой» и снова открываю свое приложение, удерживая кнопку «Домой», оно снова вызывает намерение, и те же дополнительные функции все еще присутствуют.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
это код, который работает не так, как предполагалось
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
}
}
И мое намерение:
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);
}
Есть ли способ очистить намерение или проверить, использовалось ли оно раньше?
Ответы:
ОБНОВИТЬ:
Я не понимал, что этот ответ будет так много упоминаться, когда впервые написал его более 5 лет назад!
Я поясню, чтобы указать, что в соответствии с ответом @ tato-rodrigo это не поможет вам обнаружить уже обработанное намерение в некоторых ситуациях.
Также я должен указать, что я поставил "clear" в кавычки по какой-то причине - вы на самом деле не очищаете намерение, делая это, вы просто используете удаление лишнего в качестве флага того, что это намерение уже было замечено действием. .
У меня была точно такая же проблема.
Приведенный выше ответ направил меня на правильный путь, и я нашел еще более простое решение, используйте:
вызов метода, чтобы «очистить» намерение.
Немного поздно ответить, так как об этом спросили год назад, но, надеюсь, это поможет другим в будущем.
источник
setIntent(new Intent())
и теперь работает нормально.РЕДАКТИРОВАТЬ: я редактирую, чтобы опубликовать полное решение, которое я использую.
Это решение будет работать, если возникнет проблема «Не выполнить некоторый код при запуске действия из истории (недавние приложения)» .
Прежде всего, объявите
boolean
в своем,Activity
чтобы указать,Intent
был ли уже использован:Затем, безопасно хранить и восстанавливать это значение , используя
onSaveInstanceState
иonCreate
методы для обработки изменений конфигурации и случаи , что система может убивать ваших ,Activity
когда она идет в фоновом режиме.Теперь проверьте, можете ли вы запустить свой код под
onResume
методом.Кроме того, если вы
Activity
настроены наsingleTop
, вы должны сбросить свой флаг приIntent
доставке нового .источник
(intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)
поэтому теперь я могу понять, когда начало активности находится в истории, и могу игнорировать свои дополнения.boolean shouldThisIntentTriggerMyCode = [...];
из ответа (для чего используется?)consumedIntent
какString
содержащий Uid уведомления. Этот Uid можно просто добавить к уведомлению на бэкэнде как текущую отметку времени. Также вы должны сохранять этот UidonSaveInstanceState
только в том случае, если намерение было сформированоonCreate
. Это означает, что вам не следует сохранять Uid из файловonNewIntent
.Ответ Макс работает для очистки лишнего:
Еще одна полезная команда:
Вы также можете пометить намерение, позвонив:
а затем просто проверьте значение.
источник
Когда мы запускаем приложения для Android из истории (последние приложения), приложение может запускаться в основном с тремя разными флагами намерений.
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
Это когда активность запускается из истории приложения, которое было свернуто (долгое нажатие клавиши возврата домой).
Постоянное значение: 1048576 (0x00100000)
FLAG_ACTIVITY_NEW_TASK
Это когда действие запускается через «щелчок по значку приложения» или через « фильтры намерений ». Здесь действие станет началом новой задачи в этом стеке истории.
Постоянное значение: 268435456 ( 0x10000000 )
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY | FLAG_ACTIVITY_NEW_TASK
Это когда приложение было закрыто нажатием кнопки «Назад», а затем возобновилось из истории (последние приложения).
Постоянное значение: 269484032 (0x10100000)
Постоянное значение можно получить через
getIntent().getFlags()
В третьем случае Android перезагружает последние значения Intent из своей памяти. Таким образом, intent (
getIntent
) вашего приложения будет иметь значения из последнего намерения, запустившего приложение.Фактически, приложение должно вести себя так, как будто это новый запуск, со значениями намерений для нового запуска, а не значениями намерений предыдущего запуска. Это поведение можно увидеть, если вы запустите приложение, щелкнув значок приложения, оно никогда не будет иметь старых значений намерений. Это потому, что Android использует следующий фильтр намерений для этого сценария
Но в третьем случае (приложение, которое было закрыто, запускается из истории последних приложений), ОС Android использует последнее намерение, которое запустило приложение до его выхода (путем нажатия кнопки возврата). Таким образом, у вас останутся старые значения намерений, и поток приложения будет неправильным.
Удаление намерения - это один из способов ее решения, но это не решит проблему полностью! Поскольку ОС Android перезагружает намерение из последнего запуска приложений, а не из последнего экземпляра намерения запуска.
Чистый способ избежать этого - справиться с этим, получив тип Intent для определения типа запуска.
Так что в вашем LaunchActivity (тот , который имеет намерение фильтра , определенный в манифесте), вы можете использовать следующий код в
onCreate()
,onStart()
илиonResume()
методах.Я полагаю
normalLaunch()
, не следует использовать параметры из Intent; в противном случае вам нужно будет отделить и оптимизировать метод запуска по умолчанию, чтобы не использовать параметры Intent.источник
getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
не имеет значения, начинаю ли я действие из другого действия (метод startActivity) или повторно открываю его из стека истории (недавние приложения).Очистка намеренного объекта :
источник
Короткий ответ: нет
Длинный ответ. Не существует такой вещи, как одноразовое намерение. Экспериментально показывает, что недавняя история активности современных Android-устройств - это не что иное, как «история намерений». Последнее намерение, переданное активности, просто регистрируется в системе, и в этом дело. Люди выше предлагают использовать
Но это не работает, потому что намерение уже зарегистрировано до того момента, когда вы получите его внутри метода onNewIntent () или onStart ().
Я решил проблему, отказавшись от намерений. Моя проблема была похожа на проблему, опубликованную автором. Я попытался реализовать глобальный выход из приложения через элемент управления в области уведомлений. Он должен остановить базовую службу и закрыть все действия приложения. Вы можете найти такое же поведение в приложении Waze.
Алгоритм:
Надеюсь, это кому-то поможет, потому что я не нашел ответа в Интернете.
источник
Убедитесь , что вы используете PendingIntent.FLAG_UPDATE_CURRENT флаг PendingIntent .
Где
mPutIntent
твойIntent
.Надеюсь, что это поможет вам.
источник
Недавно у меня была эта проблема, и я решил ее, добавив метку времени в качестве дополнительного параметра к намерению:
После этого сохраните метку времени в общих настройках:
источник
У меня точно такая же проблема. Мое решение заключалось в том, чтобы добавить
boolean
переменную, которая была установлена, когда онаIntent
была «использована», иif
утверждение на основе этого,boolean
чтобы проверить, следует ли вам использоватьIntent
или нет.источник
Когда вы закончите обработку намерения, сделайте следующее:
Вы больше не увидите это обработанное намерение и не будете маскировать проблему, редактируя содержимое обработанного намерения.
источник
Я не смог найти способ удалить Intent Extra . Ни один из ответов об удалении лишнего из намерения не работает, если вы включите «Не сохранять действия » в параметрах разработчика (таким образом вы можете уничтожить действие и вернуться, чтобы проверить, есть ли еще дополнительные действия).
В качестве решения проблемы я сохранил логическое значение в SharedPreferences после обработки Intent Extras. Когда то же намерение повторно доставляется в действие, я проверяю значение SharedPreference и решаю обработать дополнительное намерение. Если вы отправляете другое новое Intent Extra в то же действие, вы устанавливаете значение SharedPreference false, и Activity обработает его. Пример :
источник
Даже после ручной очистки дополнительных компонентов Intent и Intent после их анализа кажется, что Activity.getIntent () всегда будет возвращать исходное намерение, которое запустило действие.
Чтобы обойти это, я рекомендую что-то вроде этого:
Таким образом, существует механизм для сброса исходного Intent, сохраняя при этом возможность явно сохранять определенные части исходных Intent / Intent дополнений.
Обратите внимание, что я не тестировал все режимы запуска Activity.
источник
Самый простой способ - избежать вызова getIntent () из других методов, кроме onCreate (). Но это вызовет проблемы при следующем запуске, если пользователь покинул нашу Activity, нажав кнопку «Домой». Думаю, у этой проблемы нет полнофункционального решения.
источник
Я сталкиваюсь с той же проблемой и пытаюсь использовать вышеуказанные методы, но это не работает.
Думаю, это может быть причиной режима запуска acitvity, который я использовал в режиме singleTop.
Когда я использую приложение в фоновом режиме и использую RamEater для имитации проблемы, у намерения всегда есть лишнее, даже если я устанавливаю его на ноль или удаляю ключ.
Проблема исчезла, если использовать хранилище предпочтений на Android, чтобы проверить, что прошло.
источник
Не рекомендуется добавлять еще одну добавку, чтобы знать, были ли израсходованы дополнительные продукты или нет, почему бы не сделать это ?:
источник
Как насчет этого? Устанавливает newIntent как намерение.
источник
Как насчет того, чтобы очистить намерение - заменить его пустым?
например.
источник
Надеюсь, это поможет всем. Итак, сначала мы понимаем намерение
Поместите это где-нибудь на Create
Теперь давайте установим это так, что каждый раз, когда наше приложение будет уничтожено или завершено, мы будем удалять данные.
Вы понимаете, если этого недостаточно, просто найдите больше обратных вызовов
источник
Хотя
Intent.removeExtra("key")
он удалит один конкретный ключ из дополнений, существует также метод Intent.replaceExtras (Bundle) , который можно использовать для удаления всего дополнения из Intent, еслиnull
он передается в качестве параметра.Из документов:
Поскольку методы putXXX () инициализируют дополнительные функции свежим Bundle, если он равен нулю, это не проблема.
источник
источник