我有一个信息小部件,每 60 秒更新一次。在 OREO 之前,我使用服务来完成它,但现在,你不能这样做,因为当应用程序在后台时你不能使用该服务,所以我关注了这里的一些帖子并使用警报和 AlarmManager 来更新小部件.
问题是它工作了几个小时,但是一两天后,警报的onReceive方法就不再被调用了。发生了一些事情,因为警报在用户没有删除小部件的情况下停止了,所以 wiget 停止更新。
AlarmManager 似乎不是执行此操作的最佳方法,或者我做错了什么。
这是我的小部件警报接收器:
public class WidgetAlarmReceiver extends BroadcastReceiver {
private final static String TAG = "WidgetAlarmReceiver";
@Override
public void onReceive(final Context context, Intent intent) {
Log.d(TAG,"onReceive");
ComponentName componentName = new ComponentName(context, AppWidget.class);
RemoteViews remoteViews = WidgetHelper.getInstance().generateRemoteViews(context);
AppWidgetManager.getInstance(context).updateAppWidget(componentName, remoteViews);
}
}
这是我启动闹钟的小部件的源代码:
public class AppWidget extends AppWidgetProvider {
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
RemoteViews remoteViews = WidgetHelper.getInstance().generateRemoteViews(context);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
private void startWidgetAlarm(Context context){
alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, WidgetAlarmReceiver.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmMgr.setInexactRepeating(AlarmManager.RTC, System.currentTimeMillis(), 60000, alarmIntent);
}
private void stopWidgetAlarm(Context context){
alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, WidgetAlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmMgr.cancel(sender);
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
startWidgetAlarm(context);
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
stopWidgetAlarm(context);
}
}
我的 list 的一部分:
<receiver android:name=".AppWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/new_app_widget_info" />
</receiver>
<receiver android:name=".WidgetAlarmReceiver" android:exported="false"/>
最佳答案
根据我的经验,最好使用一次性警报并在触发后重新注册它,因为对于重复警报,Android 可能会认为您在滥用 AlarmManager..所以这就是我正在使用的方法:
void registerOneTimeAlarm(PendingIntent alarmIntent, long delayMillis, boolean triggerNow) {
int SDK_INT = Build.VERSION.SDK_INT;
long timeInMillis = (System.currentTimeMillis() + (triggerNow ? 0 : delayMillis));
if (SDK_INT < Build.VERSION_CODES.KITKAT) {
alarmManager.set(AlarmManager.RTC_WAKEUP, timeInMillis, alarmIntent);
} else if (Build.VERSION_CODES.KITKAT <= SDK_INT && SDK_INT < Build.VERSION_CODES.M) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeInMillis, alarmIntent);
} else if (SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeInMillis, alarmIntent);
}
}
也许它对你也有用。
关于android - 如何更新 OREO 中的 Widget(AlarmManager 在数小时/数天后停止),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49383379/