在API 19之前,更新Widget的最短时间(30分钟)要比updatePeriodMillis
快的方法是在设置AlarmManager时使用的指定间隔后使用AlarmManager
和BroadcastReceiver
接收Intent。
目前,使用以下代码,Widget已经更新,但从Android 5.1开始,使用重复间隔小于60000ms的.setReating()将自动将其间隔设置为至少60000ms。
在Widgets onEnabled()中设置警报:
AlarmManager am= (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
//After after 3 seconds
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+ 3000, 1000 , pi);
然后在AlarmManagerBroadcastReceiver的onReceive()中:
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TAG");
//Acquire the lock
wl.acquire();
/*
* ......
* Update Widgets RemoteViews
*/
wl.release();
在setRepeating()的文档中,它显示:
注:自API 19起,所有重复报警均不准确。如果您的应用程序需要精确的交付时间,那么它必须使用一次性精确警报,并如上所述重新安排每次时间。targetSdkVersion早于API 19的旧应用程序将继续将其所有警报(包括重复警报)视为准确警报。
它现在还指出:
安排重复报警。注意:对于定时操作(滴答声、超时等),使用
Handler
更容易、更高效
那么,如何使用处理程序更新Widgets Remoteview呢?当设备进入睡眠状态以节省电池时,你如何让它停止?
有没有其他建议的方法来更新Widget?
建议从API 21级JobScheduler处理此类定期更新。
在JobService:中定义作业
public class UpdateJob extends JobService {
public static int JOB_ID=9;
@Override
public boolean onStartJob(JobParameters params) {
Toast.makeText(getApplicationContext(),"update",Toast.LENGTH_SHORT).show();
//call handler, create thread, asynctask etc
return false;
}
@Override
public boolean onStopJob(JobParameters params) {
return false;
}
}
在清单中注册:
<service android:name=".UpdateJob"
android:permission="android.permission.BIND_JOB_SERVICE" />
安排作业,例如在活动中:
JobScheduler mJobScheduler = (JobScheduler)
getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo.Builder builder = new JobInfo.Builder( UpdateJob.JOB_ID,
new ComponentName( getApplicationContext(), UpdateJob.class ) );
builder.setPeriodic(60 * 60 * 1000); // every hour
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); // only when network is available
if( mJobScheduler.schedule( builder.build() ) <= 0 )
{
//error, cant be scheduled
}
//later e.g. when update is disabled
mJobScheduler.cancel(UpdateJob.JOB_ID);
当你的作业被触发时,JobInfo.Builder有很多选项可以自定义,例如它可能取决于网络和设备状态。
在较低的API上,JobSchedulerCompat或GCM Network Manager可以用作替代方案,它们的工作方式与上面所示的几乎相同。
+一个
为了处理获取唤醒锁定的BroadcastReceiver;"助手";类,WakefulBroadcastReceiver。