Intereting Posts
Как запретить Gson выражать целые числа как float База данных не удаляется при удалении приложения Android Ошибка Android Studio 3.0. Перенастройка конфигураций зависимостей для локальных модулей Android – Как установить уведомление на определенную дату в будущем? Жизненный цикл фрагментов – какой метод вызывается для show / hide? Ресурсы и платформы для мобильных разработок (iphone, android) с использованием HTML5 AutocompleteTextView с асинхронными предложениями не показывает выпадающее меню Как сделать изменения пользовательского интерфейса активности из Android AsyncTask? Что такое libcore и его роль в android? Почему нет тестера для BroadcastReceiver? SQLite "INSERT OR REPLACE INTO" не работает Как рисовать класс Button в libgdx Android: отображение пунктов меню панели действий в зависимости от ViewPager Как воспроизводить мелодию звонка / сигнала тревоги в Android Показать и скрыть представление с помощью анимации слайдов вверх / вниз

Удаление записи из пакета (например, дополнительные функции) не работает в сочетании с кнопкой «Назад»

У меня есть BroadcastReceiver, который прослушивает входящие SMS. Если сообщение от определенного отправителя, BroadcastReceiver запускает мое приложение со следующим кодом:

final Intent activityIntent = new Intent(context, MainActivity.class); activityIntent.putExtra("smsChallenge", smsText); activityIntent.putExtra("smsSenderNumber", senderMobilNumber); activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); activityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(activityIntent); 

В MainActivity моего приложения (т. onCreate() ) я извлекаю значение smsChallenge из намерения и УДАЛЯЮТ ЭТО ПОСЛЕ ЭКСТРАКЦИИ следующим кодом:

 Bundle extras = getIntent().getExtras(); if (extras != null) { smsChallenge = extras.getString("smsChallenge"); extras.remove("smsChallenge"); } 

Таким образом, мое приложение запускается из SMS и отлично работает … Но если я нажму кнопку BACK и перезапустил приложение (то есть через Taskmanager), значение smsChallenge все еще находится в extras пакета. Это означает, что мое перезапущенное приложение думает, что оно перезапущено из-за нового SMS, которое не соответствует действительности …

Любые идеи, почему удаление ключевого значения из пакета, похоже, не работает при использовании кнопки BACK и перезапуска приложения снова?

Solutions Collecting From Web of "Удаление записи из пакета (например, дополнительные функции) не работает в сочетании с кнопкой «Назад»"

Я думаю, что вы не можете исправить это поведение, потому что к тому времени, когда вы получите доступ к намерению, os уже сохранили намерение для последующего запуска через последние приложения.

  1. Вы можете добавить флаг для удаления из последних приложений, но таким образом приложение не появится в последних приложениях.
  2. Добавьте в постоянное хранилище последние sms, которые были обработаны в вашей MainActivity, и выполните эту проверку в onCreate, отбросив намерение для sms, который уже был обработан.
  3. Окончательным решением было бы не отправлять данные в намерение вообще. Например, сохраните их в «ожидающем» постоянном хранилище. Когда начнется MainActivity, пусть он проверяет наличие ожидающего материала и очищает этот ожидающий элемент.

Например, постоянное хранилище может быть SharedPreferences.

Я бы посоветовал вам использовать 2, но вы должны посчитать полученные sms и использовать этот счетчик как идентификатор для sms. Не полагайтесь на содержимое sms и отправителя как идентификатор для sms.

Потому что getExtras() создает копию дополнительных намерений.

Вы должны сделать так

 getIntent().removeExtra("smsChallenge"); 

Документы: http://developer.android.com/reference/android/content/Intent.html#removeExtra(java.lang.String)

«Намерение всегда является первоначальным намерением, используемым для запуска этой деятельности, и ничего более. Это непреложно». Dianne Hackborn

Чтобы обойти проблему, сначала убедитесь, что вы объявили свой запуск launchMode как singleTop в манифесте.

Затем из следующего разговора попробуйте использовать onSaveInstanceState для записи факта, что вы «заглушили» некоторые из дополнительных функций. Затем в onCreate изучите параметр 'Bundle savedInstanceState'. Если он не является нулевым, это предыдущий пакет, который вы вернули в onSaveInstanceState. Из этого Bundle вы можете отказаться от этих дополнений или нет.

Изменить : в вашем случае использование общих настроек позволит вам сохранить состояние, даже если действие будет уничтожено.

 public YourActivity extends Activity { private boolean extrasClearedOut; private SharedPreferences mPrefs; private static String EXTRA_CLEAR_OUT = "extras_cleared_out"; public void onCreate(Bundle savedInstanceState) { mPrefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); extrasClearedOut = mPrefs.getBoolean(EXTRA_CLEAR_OUT, false); if (savedInstanceState != null && savedInstanceState.getBoolean(EXTRA_CLEAR_OUT, false)) { extrasClearedOut = true; } Intent intent = getIntent(); if (extrasClearedOut) { // ignore the extras in the intent. } else { // Read and use the extras in the intent. } } protected void onNewIntent (Intent intent) { super.onNewIntent(intent); setIntent(intent); if (extrasClearedOut) { // ignore the extras in the intent. } else { // Read and use the extras in the intent. } } public void someMethod(...) { extrasClearedOut = true; } protected void onSaveInstanceState (Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(EXTRA_CLEAR_OUT, extrasClearedOut); } public void onDestroy() { final Editor edit = mPrefs.edit(); edit.putBoolean(EXTRA_CLEAR_OUT, extrasClearedOut); edit.commit(); } } 

Вот еще одно рабочее решение на ваш вопрос

Я думаю, вам нужно явно указать намерение действий для поведения, которое вы хотите. Я не уверен, почему getIntent() похоже, возвращает копию.

Из документов для Activity.setIntent()

Измените намерение, возвращенное getIntent (). В этом содержится ссылка на данное намерение; Он не копирует его. Часто используется в сочетании с onNewIntent (Intent).

http://developer.android.com/reference/android/app/Activity.html#setIntent(android.content.Intent )

 private void removeExtraFromBundle(String key){ Bundle bundle = getArguments(); if(bundle != null){ String value = null; value = bundle.getString(key); if(value != null){ bundle.remove(key); } } } 

Вышеприведенный код поможет вам удалить определенный ключ из объекта bundle.

Мой совет добавляет третье дополнение к намерению с помощью некоторого nonce , например, просто случайный String:

 final Intent activityIntent = new Intent(context, MainActivity.class); activityIntent.putExtra("smsChallenge", smsText); activityIntent.putExtra("smsSenderNumber", senderMobilNumber); activityIntent.putExtra("nonce", UUID.randomUUID().toString); activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); activityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(activityIntent); 

Затем проверьте, есть ли у вас этот nonce before в onCreate() :

 public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent = getIntent(); smsChallenge = intent.getStringExtra("smsChallenge", null); String nonce = intent.getStringExtra("nonce", null); if (nonce == null) { // should not happen, but do something sane here } SharedPreferences sp = PreferenceManager.getDefaultPreferences(this); if (nonce.equals(sp.getString("nonce", null)) { // app was restarted } else { // app was started from a shiny fresh intent sp.edit().putString("nonce", nonce).commit(); } } 

Но имейте в виду, что изменения ориентации и т. Д. Также вызывают onCreate() . Но вы можете легко savedInstanceState это, savedInstanceState является ли savedInstanceState null .

Удаление лишнего не является правильным способом решения этой проблемы. Эта проблема возникает из-за контекста, который используется для запуска указанного действия. Изменить это

 final Intent activityIntent = new Intent(context, MainActivity.class); 

к этому

 final Intent activityIntent = new Intent(context.getApplicationContext(), MainActivity.class); 

Действие будет завершено, когда вы нажмете кнопку «Назад» (при условии, что вы не перегрузили функцию и не изменили ее поведение). Если вы выберете приложение из списка приложений, он не будет содержать никаких дополнительных функций.

Редактировать:

Избегайте запуска действий с приемника. Рассмотрим это: вы находитесь на MainActivity. Вы получаете смс. Теперь вместо обновления ui для отражения нового сообщения вы увидите новое действие, которое будет запущено, что не будет хорошим дизайном пользовательского интерфейса.

Альтернативный подход: обновите свою базу данных или выполните необходимые действия. Затем локально передайте информацию. В своей деятельности зарегистрируйте приемник для этой трансляции и обновите пользовательский интерфейс или сделайте все, что необходимо. Если вы хотите уведомить пользователя, а не запускать его, создайте уведомление.