如何在 Android 中将时钟应用小部件与系统时钟完美同步?
Posted
技术标签:
【中文标题】如何在 Android 中将时钟应用小部件与系统时钟完美同步?【英文标题】:How to perfectly sync clock app widget with system clock in Android? 【发布时间】:2015-06-03 10:30:06 【问题描述】:我制作了一个数字时钟小部件,它使用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 步:获取系统时间并在小部件上显示。
第二步:设置第一次更新间隔=(60 - 当前秒值)。
第 3 步:第一次更新后,将后续更新间隔设置为 60 秒。
【问题讨论】:
【参考方案1】:这是一个老问题,但在 android Oreo 及更高版本上使用带有 ACTION_TIME_TICK
的 BroadcastReceiver 将不再适用。 API 级别 17+ 的更好替代方案是使用 RemoteViews
支持的 TextClock
。只需在您的时钟小部件布局中添加类似这样的内容:
<TextClock
android:id="@+id/widget_clock"
android:layout_
android:layout_
android:textSize="56sp"
tools:text="12:45"
<!-- You can also easily add custom typefaces -->
android:fontFamily="@font/quicksand_regular"
android:textColor="@color/white"/>
时钟应自动与系统时钟同步。
【讨论】:
它适用于日历吗?或者对于日历只需使用 textview? 如果我想分隔小时和分钟怎么办?例如小时有较大的字体,分钟有较小的字体? 对于日历,您需要将 set24HourFormat() 和 set12HourFormat() 设置为所需的日期格式。如果你想有不同的小时和分钟大小,你需要两个文本时钟,一个是 HH 格式,另一个是 mm(24 小时:分钟),并分别设置 textsize。【参考方案2】:拦截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);
进一步考虑:
我们本可以尝试在AppWidgetProvider
类的onReceive()
方法中捕获ACTION_TIME_TICK
广播(在清单中将操作添加到intent-filter
之后),但文档指出此广播操作只能被拦截由BroadcastReceiver
以编程方式注册。不过,这可能值得一试。
并不是说使用BroadcastReceiver
比使用AlarmManager
“更好”。在不同的情况下需要不同的方法,既然ACTION_TIME_TICK
广播是系统发送的,为什么不利用呢?
【讨论】:
感谢 ZygoteInit,BradcastReceiver 是否比 AlarmManager 更适合时钟小部件? 我试过了——它运行了大约 10 分钟——但随后系统关闭了我的进程并停止工作...... :-( @DeNitE:这在我之前从事的应用小部件项目中非常适合我。如果你能详细解释你的问题,最好是在另一个问题中,我很乐意提供帮助...... :) @Y.S.我想我明白了——我做了一个服务来更新 START_STICKY 的小部件,以确保它不会被关闭。现在效果很好! :-) @SaharPournasseh 当您拦截动作时间滴答广播时,从 onReceive() 启动一个服务并更新小部件。以上是关于如何在 Android 中将时钟应用小部件与系统时钟完美同步?的主要内容,如果未能解决你的问题,请参考以下文章