如何像KWGT(Kustom widget)一样每分钟更新一次时间小部件



更新

我放弃了使用ACTION_TIME_TICK,因为当点击锁定手机的物理按钮时,即使手机仍然锁定,它也会发送ACTION_TIME_TICK。如果我一直按这个键来唤醒电话,那可能会有麻烦。

编辑

这个问题的最初目的是:每60秒更新一次小部件文本(不是TextClock(?我可以使用ACTION_TIME_TICK更新android时间小工具吗?

我发现一个名为KWGT(Kustom Widget(的应用程序,似乎在使用后台?前台服务每分钟更新一次。它的服务(显示通知,所以我确信它是服务(比我的(警报+前台服务(寿命更长。

KWGT是如何做到这一点的?它的帮助网站上写着:Kustom was using close to 0 resources when it was allowed to ignore battery optimization (because targeting old releases) and new version acts like the same.这意味着使用AlarmManager.RTC模式报警吗?

我有一个Android AppWidget,它显示HH:mm,每60秒更新一次,它可以工作,但仍然有一些问题。这是我得到的:

  1. 我试过TextClock,它看起来很好,但当时间流逝时,我仍然需要更新一些其他文本,比如"倒计时:3分钟"、"倒计数:2分钟"。

  2. 我使用AlarmManager,每分钟发送一次广播来更新我的小部件。我有点担心我的设备的电池。另一个问题是,当我更改设备的时间时,TextClock会立即获得新的时间,但我的小部件文本不会。

  3. 我知道TextClock是如何做到这一点的:系统发送的意向ACTION_TIME_TICK、ACTION_TIME_CHANGED、ACTION_TIMEZONE_CHANGE。注释说:"你不能通过清单中声明的组件来接收它,只能通过Context.registerReceiver((显式注册它"。

  4. 那么,我应该在服务中注册那个接收者吗?我认为它不会工作很长时间,因为我的流程不可能永远运行。这些系统时间小部件是如何做到这一点的?2021年最好的方式是什么?我的minSdk是API 26,如果之后有更好的方法,我可以改到更高的版本。

我的警报:

fun startAlarm() {
val calendar: Calendar = Calendar.getInstance()
calendar.set(Calendar.MILLISECOND, 0)
calendar.set(Calendar.SECOND, 0)
calendar.add(Calendar.MINUTE, 1)
val alarmIntent = Intent(context, MyWidget::class.java)
alarmIntent.action = MyWidget.ACTION_AUTO_UPDATE
val pendingIntent = PendingIntent.getBroadcast(
context,
ALARM_ID,
alarmIntent,
PendingIntent.FLAG_CANCEL_CURRENT
)
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
// RTC does not wake the device up
alarmManager.setRepeating(
AlarmManager.RTC,
calendar.timeInMillis,
INTERVAL_MILLIS.toLong(), // Value will be forced up to 60000 as of Android 5.1
pendingIntent
)
}

有趣的寄存器接收器说:

注意:此方法不能从BroadcastReceiver组件调用;即来自在应用程序的清单中声明的BroadcastReceiver。但是,可以从另一个BroadcastReceiver调用此方法,该方法本身在运行时已在registerReceiver中注册,因为这样一个注册的BroadcastReceive的生存期与注册它的对象绑定

这是什么意思?我可以在类MyWidget:AppWidgetProvider((中重新注册它吗?什么是正确的上下文?

这是TextClock:中的接收器寄存器

// OK, this is gross but needed. This class is supported by the
// remote views mechanism and as a part of that the remote views
// can be inflated by a context for another user without the app
// having interact users permission - just for loading resources.
// For example, when adding widgets from a managed profile to the
// home screen. Therefore, we register the receiver as the user
// the app is running as not the one the context is for.
getContext().registerReceiverAsUser(
mIntentReceiver,
android.os.Process.myUserHandle(),
filter,
null,
getHandler()
);

registerReceiverAsUser@UnsupportedAppUsage的函数,所以我认为它对我没有帮助

非常感谢

如果可以的话,最好的方法是使用TextClock或AnalogClock。这些更新每分钟(或安卓12上的AnalogClock每秒钟(,而无需运行应用程序的进程。

ACTION_TIME_TICK只发送给已注册的接收者,这意味着在应用程序未运行时您不会收到它。保持应用程序运行的唯一可行方法是使用前台服务,要求向用户显示通知。

您可以覆盖从AppWidgetProvider扩展的类中列出的方法,如下所示:

@Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);        
Log.d("TAG", "mythou--------->onReceive Reason: " + intent.getAction());

}
@Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
context.getApplicationContext().registerReceiver(this, filter);
}

最新更新