我制作了一个数字时钟小部件,它使用AlarmManager
每60秒更新一次。
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
Log.d("onEnabled","Widget Provider enabled. Starting timer to update widget every minute");
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), 60000, createClockTickIntent(context));
}
问题是,每隔60秒轮询系统时间不会将我的窗口小部件时间与系统时间同步。假设用户在6:00:20添加小部件,我的小部件显示时间6:00并且睡眠60秒,所以当系统时间变为6:01:00时,我的小部件需要另外20秒才能赶上。
有没有办法做到以下几点?
第1步:获取系统时间并在小部件上显示。
第2步:设置第一个更新间隔=(60 - 当前秒数值)。
第3步:首次更新后,将后续更新间隔设置为60秒。
答案 0 :(得分:3)
拦截ACTION_TIME_TICK
广播。此广播操作将在本地时区时钟的每分钟更改时发送。
private BroadcastReceiver receiver;
@Override
public void onEnabled(Context context)
{
super.onEnabled();
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context ctx, Intent intent)
{
if (intent.getAction().compareTo(Intent.ACTION_TIME_TICK) == 0) {
// update widget time here using System.currentTimeMillis()
}
}
};
context.getApplicationContext().registerReceiver(receiver, new IntentFilter(Intent.ACTION_TIME_TICK));
}
@Override
public void onDisabled(Context context)
{
super.onDisabled();
if (receiver != null)
context.getApplicationContext().unregisterReceiver(receiver);
}
进一步考虑:
ACTION_TIME_TICK
类'AppWidgetProvider
方法中捕获onReceive()
广播(将动作添加到清单中的intent-filter
之后)但文档说明了此广播操作只能由以编程方式注册的BroadcastReceiver
拦截。不过,这可能值得一试。BroadcastReceiver
并不比使用AlarmManager
“更好”。在不同的情况下需要不同的方法,并且由于系统发送ACTION_TIME_TICK
广播,为什么不利用它?答案 1 :(得分:3)
这是一个古老的问题,但是在Android Oreo及更高版本上无法将BroadcastReceiver与ACTION_TIME_TICK
一起使用。 API级别17 + 的更好替代方法是使用TextClock
支持的RemoteViews
。只需在您的时钟小部件布局中添加以下内容即可:
<TextClock
android:id="@+id/widget_clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="56sp"
tools:text="12:45"
<!-- You can also easily add custom typefaces -->
android:fontFamily="@font/quicksand_regular"
android:textColor="@color/white"/>
时钟应自动与系统时钟同步。