ACTION_BATTERY_CHANGED像疯了一样开火

时间:2011-10-02 06:04:02

标签: android broadcastreceiver android-appwidget battery

好的,所以我正在开发一个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。这不应该只为每减少百分比广播吗?它实际上导致我的整个发射器滞后,我不得不卸载它。这不可能是正确的。

2 个答案:

答案 0 :(得分:23)

  

我的代码如下所示:

您无法从其他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 ,因为这会在最后{{}返回给您为该操作广播的1}}(注意:您仍然需要使用Intent
  • 使用getApplicationContext()更新您的应用小部件实例,并将电池电量拉出您在上一步中检索到的AppWidgetManager(注意:如果您将它们全部设置为相同,则执行此操作不需要迭代ID - 使用Intent作为参数的updateAppWidget()

这有几个好处:

  1. 您不关心ComponentName广播的频率
  2. 用户可以通过执行这些检查来控制您消耗的电量(如果将轮询周期保持在一分钟或更长时间,则应该可以忽略不计)
  3. 您的流程可以在民意调查之间安全终止,从而减少用户使用任务杀手攻击您并且半永久性地搞乱您的应用的可能性

答案 1 :(得分:0)

好吧,你的onUpdate正在注册自己的类作为batteryinfo intent的接收器。然后立即触发第一个信息的意图。 你的onReceive再次调用你的onUpdate。我们称之为循环。因此每秒100记录......