Android 如何在OREO中更新小部件(AlarmManager在几小时/几天后停止)
我有一个信息小部件,每60秒更新一次。在OREO之前,我是使用服务完成的,但是现在,你不能这样做,因为当应用程序在后台时,你不能使用服务,所以我在这里发布了一些帖子,并使用alarm and AlarmManager来更新小部件 问题是它工作了几个小时,但在一两天内,不再调用报警的onReceive方法。由于警报停止而用户未删除小部件,因此wiget停止更新,因此发生了一些情况 看来AlarmManager不是最好的方法,或者我做错了什么 这是我的小部件报警接收器:Android 如何在OREO中更新小部件(AlarmManager在几小时/几天后停止),android,widget,android-widget,alarmmanager,android-8.0-oreo,Android,Widget,Android Widget,Alarmmanager,Android 8.0 Oreo,我有一个信息小部件,每60秒更新一次。在OREO之前,我是使用服务完成的,但是现在,你不能这样做,因为当应用程序在后台时,你不能使用服务,所以我在这里发布了一些帖子,并使用alarm and AlarmManager来更新小部件 问题是它工作了几个小时,但在一两天内,不再调用报警的onReceive方法。由于警报停止而用户未删除小部件,因此wiget停止更新,因此发生了一些情况 看来AlarmManager不是最好的方法,或者我做错了什么 这是我的小部件报警接收器: public class W
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);
}
}
我的舱单部分:
<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);
}
}
void registerOneTimeAlarm(PendingEvent alarmIntent、long delayMillis、boolean triggerNow){
int SDK_int=Build.VERSION.SDK_int;
long-timeInMillis=(System.currentTimeMillis()+(triggerNow?0:delayMillis));
如果(SDK_INT
也许它也适用于您。AlarmManager的一个缺点是,您必须在设备重新启动后重新注册,这可能就是您所经历的。您可以尝试使用JobScheduler==>@HedShafran无法使用它,因为我需要在与JobScheduler不兼容的较低设备中执行此操作。此外,设备没有重新启动,因此这不是警报停止的原因。您正在测试什么设备?@earthw0rmjim Nexus 5X更新为8。1@NullPointerException你找到解决办法了吗?我有同样的pb。安卓系统是一个令人头痛的问题。Dev并不真正关心向后兼容性。当设备处于休眠状态时更新小部件是没有意义的。因此,使用“setExact()”,您可以根据需要更改代码。。但方法才是最重要的……难道没有更好的方法来实现这一点吗?如果您想使用AlarmManager,这并不令人沮丧。。它用于报警,而不是每60秒执行一次任务。。我提供的方法应该是一个足够好的解决方案,这就是我在我的应用程序中所做的,以实现代码不多的跨版本重复任务。对于alarmmanager和API 14,我还有哪些不同的方法?