Это правильное поведение actully. Каждый раз, когда вы получаете сообщение, система отправляет SMS-трансляцию. Поскольку ваше приложение заявляет в своем манифесте, что оно хочет получать такие трансляции, каждый экземпляр вашего BroadcastReceiver будет создан и исполняется каждый раз.
Если вы хотите выполнить приемник только в определенное время (в данном случае, когда приложение находится на переднем плане), вы должны зарегистрироваться и отменить его динамически в коде вместо манифеста с помощью Context.registerReceiver()
и Context.unregisterReceiver()
.
Как это сделать?
Вот краткий пример. Я предполагаю, что вы написали свой собственный класс, который расширяет BroadcastReceiver и обрабатывает материал в onReceive()
. Имя этого класса в этом примере: SmsReceiver
, как в связанном учебнике.
Наша цель - получать трансляции только в том случае, если на первом плане находится одно действие, что означает, что вы также должны иметь один класс, который расширяет действие и отображает интерфейс, как обычное приложение.
Прежде всего нам нужен фактический экземпляр приемника в качестве члена класса. Добавить что-то вроде этого в классе деятельности:
private SmsReceiver smsReceiver = new SmsReceiver();
Sidenote: Это на самом деле одно из основных различий между регистрацией в проявленном и в коде:
- В коде вы создаете приемник экземпляра по сами
- После регистрации в манифесте, система генерирует экземпляры для вас в фоновом режиме
Хорошо, отлично. Теперь нам просто нужно зарегистрировать и отменить регистрацию этого приемника, когда деятельность выходит на передний план и выходит из него. Посмотрите на диаграмму в Activity class doc, методы структуры, называемые в этих событиях, - onResume()
и onPause()
.
Добавьте следующие строки в ваш метод onResume()
:
@Override
public void onResume() {
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
registerReceiver(smsReceiver, filter);
}
То, что мы сделали здесь на самом деле довольно просто. Это кодовый эквивалент ярлыков <receiver />
. Мы создали фильтр намерений с трансляцией, которую мы хотели бы получить и зарегистрировать у нашего получателя.
Следующий шаг - отменить регистрацию в onPause()
. Опять же, добавьте эту строку или создайте onPause()
, если вы еще этого не сделали.
@Override
public void onPause() {
unregisterReceiver(smsReceiver);
}
Довольно просто - примите наш экземпляр приемника и отмените его регистрацию, когда приложение вот-вот выйдет на задний план. И это все волшебство, все должно работать по назначению. Не забудьте удалить весь тег <receiver />
в вашем манифесте, хотя, когда вы работаете с существующим кодом. В противном случае вы зарегистрируете приемник двумя способами.
Так что я пытаюсь реализовать то, что вы предложили, но я немного смущен. Где я могу поместить registerReceiver, как его правильно использовать, то есть, что такое пример кода. Есть ли пример, на который вы можете связать меня? У меня это есть, но это приводит к сбою BroadcastReceiver BR = null; Фильтр IntentFilter = null; registerReceiver (BR, фильтр); –
@ChrisSippel Вы не можете зарегистрироваться с помощью таких объектов. Я добавил короткий ответ на мой ответ. –
Итак, я, наконец, обойдусь, чтобы правильно заняться, с праздниками и учебой, я был занят. Поэтому я очень рад сказать, что он работает, и что я благодарен вам! –