ArtyomovAnton
@ArtyomovAnton
PHP и всё что рядом

Как передать данные из Service в running Activity?

Здравствуйте. Порыл интернеты, но так и не смог найти ответ. Может формулировал вопрос не так.
Суть в следующем. В PasswordActivity пользователь вводит номер телефона, нажимает кнопку "получить код по СМС". При этом показывается поле ввода кода из СМС. В это время при имеющихся разрешениях, class SMSMonitor extends BroadcastReceiver ждет СМС. Получает. Парсит и передает в class SmsService extends Service. SmsService обрабатывает тело СМС извлекает нужные данные, решает какой активити их передать. Передает, например, в PasswordActivity так:
Intent intent = new Intent(this, PasswordActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("sms_code", code);
startActivity(intent);

Таким образом запускается еще одна PasswordActivity в новом таске. Затем пользователь вводит новый пароль и он, вместе с кодом проверки из СМС отправляется на сервер. При успехе смены пароля я делаю finish() для активити. Текущая PasswordActivity закрывается, а под ней отображается всё ещё та старая PasswordActivity с полем ввода кода из СМС.
При этом я в манифесте для PasswordActivity выставлял свойства android:launchMode= "singleInstance" и что то еще... Играл с флагами Intent.FLAG_ACTIVITY_...
Есть флаги, которые вроде как и не создают новый таск, но при этом в PasswordActivity не отрабатывают ни onCreate, ни onResume.
После перехвата СМС, мне обязательно нужно продолжить работу с активностью, т.к. требуются дальнейшие действия пользователя.
Одним словом, как мне передать данные из сервиса в уже запущенную активность, которая даже не в паузе?
  • Вопрос задан
  • 852 просмотра
Решения вопроса 1
ArtyomovAnton
@ArtyomovAnton Автор вопроса
PHP и всё что рядом
Решил задачу следующим образом: SMSMonitor более не вызывает SmsService, который стартовал активити. SMSMonitor теперь шлет широковещательное сообщение:
Intent mIntent = new Intent("SmsMessage.intent.MAIN");
mIntent.putExtra("sms_code", code);
context.sendBroadcast(mIntent);

А в методе onResume класса PasswordActivity я регистрирую BroadcastReceiver:
IntentFilter intentFilter = new IntentFilter("SmsMessage.intent.MAIN");
        mIntentReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                sms_code = intent.getIntExtra("sms_code",0);
                if (sms_code > 0) {
                    // Необходимые операции с элементами view и методами активити
                }
            }
        };
        registerReceiver(mIntentReceiver, intentFilter);
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Подозреваю, что дело тут во флаге FLAG_ACTIVITY_NEW_TASK. У вас создается не просто новая активити, а новый процесс, а старый остается висеть в фоне. В документации, кстати, говорят, что "singleTask and singleInstance — are not appropriate for most applications" - как раз потому, что при неосторожном использовании они могут приводить к странным результатам.

У меня в похожей ситуации прекрасно работает флаг FLAG_ACTIVITY_CLEAR_TOP. У вызываемой активити в манифесте стоит singleTop. Правда, я вызываю ее не из сервиса, а из другой активити, но не думаю, что это принципиально. Нужно иметь в виду еще одну вещь: если ваша PasswordActivity уже существует, то вместо onCreate() может быть вызван onNewIntent(). Его тоже нужно переопределить, чтобы правильно обработать данные от сервиса. Возможно, именно поэтому у вас не получилось, когда вы пробовали "поиграть с флагами".
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы