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

Сохранять широковещательный приемник после закрытия приложения

Мне нужно поддерживать широковещательный приемник все время после запуска приложения.

Вот код, который регистрирует этот ресивер в приложении

    IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
    filter.addAction(Intent.ACTION_SCREEN_OFF);
    BroadcastReceiver mReceiver = new ScreenEventsReceiver();
    registerReceiver(mReceiver, filter);

И код для приемника

public class ScreenEventsReceiver extends BroadcastReceiver {
     public static boolean wasScreenOn = true;

     @Override
     public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            wasScreenOn = false;
            Log.d("ScreenEventReceiver", "ON");
        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            wasScreenOn = true;
            Log.d("ScreenEventReceiver", "ON");
        }
     }
}
4b9b3361

Ответ 1

Вы можете использовать сервис

В главном приложении запуск/остановка службы

Intent service = new Intent(context, MyService.class);
context.startService(service);
...
Intent service = new Intent(context, MyService.class);
context.stopService(service);

услуги

public class MyService extends Service
{
 private static BroadcastReceiver m_ScreenOffReceiver;

 @Override
 public IBinder onBind(Intent arg0)
 {
  return null;
 }

 @Override
 public void onCreate()
 {
  registerScreenOffReceiver();
 }

 @Override
 public void onDestroy()
 {
  unregisterReceiver(m_ScreenOffReceiver);
  m_ScreenOffReceiver = null;
 }

 private void registerScreenOffReceiver()
 {
  m_ScreenOffReceiver = new BroadcastReceiver()
  {
   @Override
   public void onReceive(Context context, Intent intent)
   {
     Log.d(TAG, "ACTION_SCREEN_OFF");
     // do something, e.g. send Intent to main app
   }
  };
  IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
  registerReceiver(m_ScreenOffReceiver, filter);
 }
}

Ответ 2

Я считаю, что принятый ответ не является реальным. Я объясню, в чем проблема. Я думаю, что вы тестируете свое приложение на Huawie, Oppo, Vivo, Xiomi, asus....... или на некоторых устройствах. С этими устройствами, если мы закроем приложение, они также закроют наши широковещательные приемники. Так вот в чем проблема. (Для проверки используйте эмулятор пикселей). Я объясню, как решить эту проблему.

  • мы добавили бы наше приложение в список защищенных приложений. ОС только позволяет им продолжать вещательную деятельность приемника. (Скопируйте эту декларацию массива в ваш код)

    private static final Intent[] POWERMANAGER_INTENTS = {
        new Intent().setComponent(new ComponentName("com.miui.securitycenter", "com.miui.permcenter.autostart.AutoStartManagementActivity")),
        new Intent().setComponent(new ComponentName("com.letv.android.letvsafe", "com.letv.android.letvsafe.AutobootManageActivity")),
        new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity")),
        new Intent().setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity")),
        new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.permission.startup.StartupAppListActivity")),
        new Intent().setComponent(new ComponentName("com.coloros.safecenter", "com.coloros.safecenter.startupapp.StartupAppListActivity")),
        new Intent().setComponent(new ComponentName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity")),
        new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity")),
        new Intent().setComponent(new ComponentName("com.iqoo.secure", "com.iqoo.secure.ui.phoneoptimize.BgStartUpManager")),
        new Intent().setComponent(new ComponentName("com.vivo.permissionmanager", "com.vivo.permissionmanager.activity.BgStartUpManagerActivity")),
        new Intent().setComponent(new ComponentName("com.samsung.android.lool", "com.samsung.android.sm.ui.battery.BatteryActivity")),
        new Intent().setComponent(new ComponentName("com.htc.pitroad", "com.htc.pitroad.landingpage.activity.LandingPageActivity")),
        new Intent().setComponent(new ComponentName("com.asus.mobilemanager", "com.asus.mobilemanager.MainActivity"))};
    
  • Поместите этот код в ваш метод onCreate. Здесь я использовал общие настройки для проверки только в первый раз, когда приложение открыто.

final SharedPreferences.Editor pref = getSharedPreferences("allow_notify", MODE_PRIVATE).edit(); pref.apply(); final SharedPreferences sp = getSharedPreferences("allow_notify", MODE_PRIVATE) final SharedPreferences.Editor pref = getSharedPreferences("allow_notify", MODE_PRIVATE).edit(); pref.apply(); final SharedPreferences sp = getSharedPreferences("allow_notify", MODE_PRIVATE);

if(!sp.getBoolean("protected",false)) {
    for (final Intent intent : POWERMANAGER_INTENTS)
        if (getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {

        AlertDialog.Builder builder  = new AlertDialog.Builder(this);
        builder.setTitle("Alert Title").setMessage("Alert Body")
                .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        startActivity(intent);
                        sp.edit().putBoolean("protected",true).apply();

                    }
                })
                .setCancelable(false)
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    }
                })
                .create().show();
        break;

Ответ 3

Если вы объявите BroadcastReceiver в манифесте, он всегда будет активным и будет вызываться, даже если приложение закрыто/остановлено

Ответ 4

Будьте осторожны, если вы используете Android 4.4.x, так как есть ошибка, которая убивает фоновые службы при закрытии приложения. Я тестировал свое приложение в Android 4.4.2, и у меня была такая же проблема. Здесь есть подробное объяснение:

http://www.androidpolice.com/2014/03/07/bug-watch-stopping-apps-on-android-4-4-2-can-silently-kill-related-background-services-a-fix-is-on-the-way/

Ответ 5

Вы можете запустить службу, запущенную на переднем плане. Это единственный способ обеспечить (в основном) то, что ваше приложение получит события. Есть еще вероятность того, что ваше обслуживание переднего плана может быть убито во время сумасшедшего давления памяти из ОС (так что это не безупречно). Если вы запустите службу на переднем плане, пользователь увидит постоянное уведомление, чтобы знать, что оно всегда работает.

Итак, мораль этой истории, действительно ли вам нужно постоянно следить за экранами/событиями? Причина, по которой они заставляют вас регистрировать приемник не в манифесте, заключается в том, что они не хотят, чтобы люди всегда следили за этими событиями и замедляли работу устройства. Что вы пытаетесь выполнить?

Ответ 6

Вы не можете получать некоторые события трансляции через компоненты, объявленные в манифесте.

Эти события

  • ACTION_BATTERY_CHANGED
  • ACTION_CONFIGURATION_CHANGED
  • ACTION_SCREEN_OFF (Вы играете с этим событием)
  • ACTION_SCREEN_ON (Вы играете с этим событием)
  • ACTION_TIME_TICK

Ссылка https://developer.android.com/reference/android/content/Intent.html#ACTION_SCREEN_ON

Итак, в ваших конкретных событиях вам нужно будет создать Сервис, и вам придется регистрировать свое событие явно в службе onCreate() с помощью Context.registerReceiver().

Для других событий запись в манифесте достаточна.