ACTION_BATTERY_CHANGED disparando como loco

Bueno, estoy trabajando en un AppWidget que comprueba el nivel de la batería y lo muestra en un TextView. Mi código se ve así:

public class BattWidget extends AppWidgetProvider { private RemoteViews views = new RemoteViews("com.nickavv.cleanwidgets", R.layout.battlayout); @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int appWidgetIds[]) { final int N = appWidgetIds.length; context.getApplicationContext().registerReceiver(this,new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); for (int i = 0; i < N; i++) { int appWidgetId = appWidgetIds[i]; appWidgetManager.updateAppWidget(appWidgetId, views); } } @Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); Log.d("onReceive", "Received intent " + intent); if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) { Integer level = intent.getIntExtra("level", -1); views.setTextViewText(R.id.batteryText, level+"%"); AppWidgetManager myAWM = AppWidgetManager.getInstance(context); ComponentName cn = new ComponentName(context, AirWidget.class); onUpdate(context, myAWM, myAWM.getAppWidgetIds(cn)); } } } 

Y me estoy preocupando porque tan pronto como suelte el widget en mi pantalla de inicio, comienza a disparar cerca de 100 de esas llamadas de registro por segundo, diciendo que está recibiendo ACTION_BATTERY_CHANGED. ¿No se supone que esto sólo se difundirá por cada porcentaje de disminución? Realmente causó que mi lanzador entero se retrasara, tuve que desinstalarlo. Eso no puede estar bien.

Mi código se ve así:

No puede registrar un BroadcastReceiver de otro BroadcastReceiver y obtener resultados confiables. Android finalizará el proceso, ya que no cree que se esté ejecutando nada. La única manera de escuchar ACTION_BATTERY_CHANGED será registrar ese receptor de una actividad o un servicio.

¿No se supone que esto sólo se difundirá por cada porcentaje de disminución?

¿Dónde ves eso documentado? AFAIK, ACTION_BATTERY_CHANGED será transmitido siempre que el hardware se sienta como él. Además, tenga en cuenta que otros datos cambian dentro de esa Intent , como la temperatura.

Si desea implementar este widget de aplicación, no se registre en ACTION_BATTERY_CHANGED la forma en que está. En lugar:

  • Permitir que el usuario elija un período de votación a través de una SharedPreference (por ejemplo, una vez por minuto, una vez cada 15 minutos)
  • Use AlarmManager para darle control sobre ese período de sondeo a través de un getBroadcast() PendingIntent
  • En ese BroadcastReceiver , llame a registerReceiver() para ACTION_BATTERY_CHANGED pero con un BroadcastReceiver null , ya que esto le devolverá el último Intent que fue difundido para esa acción (nota: seguirá necesitando usar getApplicationContext() para esto)
  • Utilice AppWidgetManager para actualizar las instancias de los widgets de la aplicación con el nivel de batería extraído de la Intent que recuperó en el paso anterior (nota: si está configurando que todos sean iguales, no necesitará iterar sobre los ID. updateAppWidget() que toma un ComponentName como un parámetro)

Esto tiene varias ventajas:

  1. No importa cuantas veces se transmite ACTION_BATTERY_CHANGED
  2. El usuario consigue controlar cuánta batería usted consume haciendo estas comprobaciones (debe ser insignificante si usted guarda el período de la encuesta a un minuto o más)
  3. Su proceso puede terminar de forma segura entre las encuestas, por lo que es menos probable que los usuarios lo ataquen con asesinos de tareas y de forma semipermanente estropear su aplicación

Bueno, tu onUpdate está registrando su propia clase como receptor para la información de batteryinfo. Esta intención se activa inmediatamente para la primera información. Su onReceive está llamando a su onUpdate de nuevo. Llamamos a esto un bucle. Por lo tanto, los 100 registros por segundo …

  • Android: ¿Hay alguna manera de obtener la capacidad de la batería de un dispositivo en mah?
  • Desactivar pop-up de "batería baja" de Android
  • ¿Cómo determina Android si una aplicación tiene "Uso de batería alta" en "Solicitudes de ubicación recientes"?
  • Context.registerReceiver devuelve una intención nula al intentar comprobar si la fuente de alimentación está conectada
  • ¿Cómo quitar el icono de la batería en la barra de estado de android?
  • Cómo averiguar el uso de la batería en mi aplicación en android
  • En Android, ¿hay una manera de obtener la batería actual?
  • Obtenga nivel y estado de la batería en Android
  • ¿Por qué podría mi aplicación para Android ocasionalmente agotar la batería extremadamente rápido?
  • ¿El proveedor de localización es realmente un drenaje de la batería?
  • ¿Se demorará un Handler postDelayed a no ser disparado cuando la CPU duerme?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.