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

ACTION_BATTERY_CHANGED стрельба как сумасшедший

Хорошо, поэтому я работаю над AppWidget, который проверяет уровень заряда батареи и отображает его на TextView. Мой код выглядит следующим образом:

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

И меня беспокоит, потому что, как только я отбрасываю виджет на свой рабочий стол, он начинает отстреливать около 100 из этих журнальных звонков секунду, говоря, что он получает ACTION_BATTERY_CHANGED. Разве это не должно быть передано только для каждого снижения процента? Это на самом деле заставило мою пусковую установку остановиться, мне пришлось удалить ее. Это не может быть правильно.

4b9b3361

Ответ 1

Мой код выглядит следующим образом:

Вы не можете зарегистрировать BroadcastReceiver из другого BroadcastReceiver и получить надежные результаты. Android завершит ваш процесс, потому что он не считает, что что-то работает. Единственным способом прослушивания ACTION_BATTERY_CHANGED будет регистрация этого получателя из активности или службы.

Разве это не должно быть передано только для каждого процента?

Где вы видите, что документировано? AFAIK, ACTION_BATTERY_CHANGED будет транслироваться всякий раз, когда аппарат чувствует себя так. Кроме того, имейте в виду, что другие данные изменяются в пределах Intent, например, температуры.

Если вы хотите реализовать этот виджет приложения, не регистрируйтесь на ACTION_BATTERY_CHANGED так, как вы. Вместо этого:

  • Разрешить пользователю выбирать период опроса через SharedPreference (например, один раз в минуту, один раз каждые 15 минут).
  • Используйте AlarmManager, чтобы дать вам контроль над этим периодом опроса с помощью getBroadcast() PendingIntent
  • В этом BroadcastReceiver вызовите registerReceiver() для ACTION_BATTERY_CHANGED , но с null BroadcastReceiver, так как это вернет вам последний Intent, который был передан для этого действия ( Примечание: для этого вам все равно нужно использовать getApplicationContext()
  • Используйте AppWidgetManager, чтобы обновить экземпляры виджета приложения с уровнем заряда аккумулятора, вытащенным из Intent, который вы извлекли на предыдущем шаге (обратите внимание: если вы настроите их все одинаковыми, вам не нужно итерации над идентификаторами - используйте updateAppWidget(), который принимает ComponentName как параметр)

Это имеет ряд преимуществ:

  • Вам все равно, как часто ACTION_BATTERY_CHANGED транслируется
  • Пользователь получает контроль над количеством потребляемой вами батареи, выполняя эти проверки (должно быть пренебрежимо мало, если вы сохраняете период опроса на минуту или более).
  • Ваш процесс можно безопасно прекратить между опросами, тем самым делая его менее вероятным, чтобы пользователи нападали на вас с убийцами задач и наполовину испортили ваше приложение.

Ответ 2

Ну, ваш onUpdate регистрирует свой собственный класс в качестве получателя для намерения batteryinfo. Это намерение сразу же запускается для первой информации. Ваш onReceive снова вызывает ваш onUpdate. Мы называем это циклом. Следовательно, 100 логов в секунду...