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 个 Log 调用,表示它正在接收 ACTION_BATTERY_CHANGED。这不是应该只在每减少一个百分比时就广播吗?它实际上导致我的整个启动器滞后,我不得不卸载它。那是不对的。
Okay, so I'm working on an AppWidget that checks the battery level and displays it on a TextView. My code looks like this:
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));
}
}
}
And I'm getting concerned because as soon as I drop the widget onto my homescreen it begins firing off about 100 of those Log calls a second, saying it's receiving ACTION_BATTERY_CHANGED. Isn't this only supposed to be broadcast for each percent decrease? It actually caused my entire launcher to lag, I had to uninstall it. That can't be right.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您无法从另一个
BroadcastReceiver
注册BroadcastReceiver
并获得可靠的结果。 Android 将终止您的进程,因为它认为没有任何东西正在运行。侦听ACTION_BATTERY_CHANGED
的唯一方法是从活动或服务注册该接收器。您在哪里看到该记录? AFAIK,只要硬件感觉合适,
ACTION_BATTERY_CHANGED
就会被广播。另外,请记住该Intent
内的其他数据会发生变化,例如温度。如果您想实现此应用小部件,请不要像现在这样注册
ACTION_BATTERY_CHANGED
。相反:SharedPreference
选择轮询周期(例如,每分钟一次、每 15 分钟一次)。AlarmManager
让您通过以下方式控制该轮询周期: agetBroadcast()
PendingIntent
BroadcastReceiver
中,调用registerReceiver()
ACTION_BATTERY_CHANGED
但使用null
BroadcastReceiver,因为这将返回为该操作广播的最后一个Intent
(注意:为此,您仍然需要使用getApplicationContext()
)AppWidgetManager
来更新您的应用小部件实例,并从Intent< 中提取电池电量。 /代码> 你在上一步中检索(注意:如果您将它们设置为相同,则无需迭代 ID - 使用采用
ComponentName< 的
updateAppWidget()
/code> 作为参数)这有几个优点:
ACTION_BATTERY_CHANGED
的广播频率You cannot register a
BroadcastReceiver
from anotherBroadcastReceiver
and get reliable results. Android will terminate your process, because it doesn't think anything is running. The only way to listen forACTION_BATTERY_CHANGED
will be to register that receiver from an activity or a service.Where do you see that documented? AFAIK,
ACTION_BATTERY_CHANGED
will be broadcast whenever the hardware feels like it. Also, bear in mind that other data changes within thatIntent
, such as temperature.If you want to implement this app widget, do not register for
ACTION_BATTERY_CHANGED
the way you are. Instead:SharedPreference
(e.g., once a minute, once every 15 mintues)AlarmManager
to give you control on that polling period via agetBroadcast()
PendingIntent
BroadcastReceiver
, callregisterReceiver()
forACTION_BATTERY_CHANGED
but with anull
BroadcastReceiver, as this will return to you the lastIntent
that was broadcast for that action (note: you will still need to usegetApplicationContext()
for this)AppWidgetManager
to update your app widget instances with the battery level pulled out of theIntent
you retrieved in the preceding step (note: if you are setting them all to be the same, you do not need to iterate over the IDs -- use theupdateAppWidget()
that takes aComponentName
as a parameter)This has several advantages:
ACTION_BATTERY_CHANGED
is broadcast好吧,您的 onUpdate 正在将自己的类注册为 Batteryinfo 意图的接收器。然后,第一个信息会立即触发此意图。
你的 onReceive 再次调用你的 onUpdate 。我们称之为循环。因此每秒 100 个日志......
Well, your onUpdate is registering its own class as receiver for the batteryinfo intent. This intent is then immediately triggered for the first info.
Your onReceive is calling your onUpdate again. We call this a loop. Hence the 100 logs a second ...