Mantenga el receptor de difusión en funcionamiento después de cerrar la aplicación

Necesito mantener el receptor de difusión en funcionamiento todo el tiempo después de que se haya iniciado la aplicación.

Aquí está el código que registra este receptor en la aplicación

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

Y código para el receptor

 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"); } } } 

Puedes usar un servicio

En la aplicación principal, iniciar / detener el servicio

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

Servicio

 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, eg send Intent to main app } }; IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); registerReceiver(m_ScreenOffReceiver, filter); } } 

Si declara BroadcastReceiver en el Manifiesto, siempre estará activo y será llamado incluso si la aplicación está cerrada / detenida.

Puede iniciar un servicio que se ejecuta en primer plano. Esa es la única forma de garantizar (principalmente) que su aplicación reciba los eventos. Todavía hay una posibilidad de que su servicio en primer plano pueda ser asesinado en momentos de loca presión de memoria del sistema operativo (por lo que no es infalible). Si comienza un servicio en primer plano, el usuario verá una notificación persistente para saber que siempre se está ejecutando.

Entonces, la moraleja de la historia es, ¿realmente necesita monitorear la pantalla de eventos todo el tiempo? La razón por la que te fuerzan a registrar un receptor que no está en el manifiesto es que no quieren que la gente esté siempre supervisando estos eventos y ralentizando el dispositivo. ¿Qué está tratando de lograr?

Tenga cuidado si está usando Android 4.4.x ya que hay un error que mata los servicios en segundo plano al cerrar la aplicación. Estaba probando mi aplicación en Android 4.4.2 y tuve el mismo problema. Aquí hay una explicación detallada:

http://www.androidpolice.com/2014/03/07/bug-watch-stopping-apps-on-android-4-4-2-can-silently-kill-related-background-services-a-fix- Está en el camino/

No puede recibir algunos eventos de difusión a través de componentes declarados en manifiesto.

Estos eventos son

  • ACTION_BATTERY_CHANGED
  • ACTION_CONFIGURATION_CHANGED
  • ACTION_SCREEN_OFF (Estás jugando con este evento)
  • ACTION_SCREEN_ON (Estás jugando con este evento)
  • ACTION_TIME_TICK

Referencia https://developer.android.com/reference/android/content/Intent.html#ACTION_SCREEN_ON

Entonces, en sus eventos específicos , tendrá que crear un Servicio y deberá registrar su evento explícitamente en el servicio onCreate () con Context.registerReceiver ().

Para otros eventos , la entrada en manifiesto es suficiente.