Подтвердить что ты не робот

Android BroadcastReceiver при запуске - продолжайте работать, когда Activity находится в фоновом режиме

Я отслеживаю входящие SMS.

Мое приложение отлично работает с BroadcastReceiver. Однако он работает из Activity и хотел бы, чтобы BroadcastReceiver работал все время (и не только во время работы Activity).

Как мне этого добиться? Я просмотрел жизненный цикл BroadcastReceiver, но все, что упоминается в документации, это то, что жизненный цикл ограничен методом onReceive, а не жизненным циклом проверки BroadcastReceiver на наличие входящих SMS.

Как я могу сделать это постоянным?

Спасибо

4b9b3361

Ответ 1

Вам нужно определить манифест приемник с именем действия android.intent.action.BOOT_COMPLETED.

<!-- Start the Service if applicable on boot -->
<receiver android:name="com.prac.test.ServiceStarter">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

Удостоверьтесь, что вы также включили завершенное разрешение на загрузку.

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

Используйте Сервис для этого, чтобы сделать что-либо упорным. И используйте приемники для приема событий загрузки, чтобы перезапустить службу еще раз, если система загрузится.

Код запуска службы при загрузке. Сделайте сервис, выполняйте свою работу по проверке смс или тому, что вы хотите. Вам нужно сделать свою работу в MyPersistingService, чтобы определить ее самостоятельно.

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class ServiceStarter extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i = new Intent("com.prac.test.MyPersistingService");
        i.setClass(context, MyPersistingService.class);
        context.startService(i);
    }
}

Ответ 2

Сервис или загрузка Завершено не обязательно

На самом деле вам не нужно реализовывать Service или зарегистрироваться на android.intent.action.BOOT_COMPLETED

Некоторые примеры показывают, как регистрировать/отменить регистрацию BroadcastReceiver, когда действие создается и уничтожается. Однако это полезно для намерений, которые вы ожидаете только при открытии приложения (например, для внутренней связи между службой/активностью).

Однако в случае SMS вы хотите постоянно слушать намерение (и не только при открытии приложения).

Другой способ

Вы можете создать class, который расширяет BroadcastReceiver и регистрируется по желанию с помощью AndroidManifest.xml. Таким образом, BroadcastReceiver будет недействительным из вашей активности (и не будет зависеть от цикла жизненной активности)

Таким образом, ваш BroadcastReceiver будет автоматически уведомлен Android, как только поступит SMS, даже если ваше приложение будет закрыто.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest>
    ...
    <uses-permission android:name="android.permission.READ_SMS"/>
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>

    <application>
        ....
        <receiver android:name=".MyCustomBroadcastReceiver">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

MyCustomBroadcastReceiver.java

public class MyCustomBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent != null) {
            String action = intent.getAction();
            if(action != null) {
                if(action.equals("android.provider.Telephony.SMS_RECEIVED")) {
                    // DO YOUR STUFF
                } else if (action.equals("ANOTHER ACTION")) {
                    // DO ANOTHER STUFF
                }
            }
        }
    }
}

Примечания

Вы можете добавить другие намеренные фильтры в AndroidManifest и обрабатывать их все в одном и том же BroadcastReceiver.

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

Ответ 3

Помимо ответа @Javanator я хотел бы включить чехол для версии Android (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O). В моем случае это работает для Android SDK 29 (10)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      context.startForegroundService(new Intent(context,FloatingWindow.class));
} else {
      context.startService(new Intent(context, FloatingWindow.class));
  }