【问题标题】:Updating a Widget at short intervals using API 19+使用 API 19+ 在短时间内更新小部件
【发布时间】:2015-12-17 01:57:08
【问题描述】:

在 API 19 之前,比updatePeriodMillis 30 分钟的最短时间更快更新 Widget 的首选方法是使用 AlarmManagerBroadcastReceiver 在设置时使用的指定间隔后接收 Intent启动警报管理器。

目前,使用以下代码更新 Widget,但从 Android 5.1 开始,使用 .setRepeating() 重复间隔小于 60000ms 将自动将其间隔设置为至少 60000ms。

在小部件 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 会更容易、更高效

那么您将如何使用 Handler 更新 Widgets Remoteviews?当设备进入睡眠状态以节省电量时,如何让它停止?

还有其他更新小部件的建议方法吗?

【问题讨论】:

  • 我的回答有问题吗?你试过了吗?

标签: android android-widget android-handler


【解决方案1】:

从 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" />

安排工作 e. G。在一个活动中:

 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 上,JobSchedulerCompatGCM Network Manager 可以用作替代方案,它们的工作方式与上面显示的几乎相同。

+还有一个

为了处理获取唤醒锁的广播接收器,支持库中有一个“帮助器”类,WakefulBroadcastReceiver

【讨论】:

  • 不接受 3 秒:W/JobInfo: Requested interval +3s0ms for job 179 is too small; raising to +15m0s0ms Requested flex +3s0ms for job 179 is too small; raising to +5m0s0ms。有没有办法消除这个限制,至少为了测试目的?
  • 不,在这种情况下,这些被不可更改的值覆盖:android.googlesource.com/platform/frameworks/base/+/…
猜你喜欢
  • 1970-01-01
  • 2013-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-19
  • 2021-07-10
  • 2017-05-23
  • 1970-01-01
相关资源
最近更新 更多