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

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

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

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

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

Спасибо

6 ответов

Вам необходимо определить получателя в манифесте с именем действия 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"/>

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

Код для запуска службы при загрузке. Заставь Сервис делать твою работу по проверке смс или что хочешь. Вы должны сделать свою работу в 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);
    }
}

Обслуживание или загрузка завершена не является обязательной

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

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

Однако, в случае 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,

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

Добавить широковещательный приемник в манифест:

  <receiver android:name=".BootReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </receiver>

Создать класс BootReciever.java

public class BootReceiver extends BroadcastReceiver {
   @Override
   public void onReceive(Context context, Intent intent) {
       if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){

           // +++ Do Operation Here +++

       }
   }
}

Рядом @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));
  }

Используйте этот код, а также укажите трансляцию в Manifest:

public class BootService extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){
            Toast.makeText(context, "Boot Completed", Toast.LENGTH_SHORT).show();
            //write code here
        }
    }
}

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

В противном случае функция оптимизации батареи отключит ваш сервис в фоновом режиме, и приемник бортового вещания не будет работать.

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

Хорошего дня,

Другие вопросы по тегам