System.exit(0) 在 Android 佩戴 Watchface?

System.exit(0) in Android Wear Watchface?

我读到 Java 和 Android 时不赞成使用 System.exit(0),但到目前为止我找不到替代方案完成。 需要说明的是,这是针对 Watchface 的,它只是一项扩展 CanvasWatchFaceService 的服务。在这种情况下,我不能调用 finish()。我也试过 stopServicestartService 但没有成功。

我要解决的问题:众所周知,除非重新启动设备,否则更改设备上的时区不会反映在表盘上。在我的测试中,我发现 System.currentTimeMillis() 完全不响应 Android Wear 中的时区变化。必须重新启动表盘才能在时区更改后显示正确的时间。

所以我用下面的代码搭建了一个系统:

private final BroadcastReceiver timeChangeReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

        if (!restarting) {
            if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
                if (upSeconds >= 15) {
                    System.exit(0);
                } else {
                    restarting = true;
                    int delay = ((15 - upSeconds) * 1000);

                    new CountDownTimer(delay, delay) {
                        @Override
                        public void onTick(long millisUntilFinished) { }
                        @Override
                        public void onFinish() {
                            System.exit(0);
                        }
                    }.start();
                }
            }
        }
    }
};

延迟是为了防止用户一次触发时区更改的频率超过 15 秒。 Android Wear 似乎检测到过于频繁的系统退出,并将表盘替换为 "Simple" 表盘。

它似乎工作得很好,Android Wear 会在退出时自动启动表盘。但我最终想把这个应用放在 Google Play 商店,所以我想我应该确保我不是在玩火。

当正确的解决方案如此简单时,我不敢相信我完成了所有这些工作。感谢 ianhanniballake 的 link!

看了Analog Watchface Sample后,我发现我需要做的就是使用mCalendar.setTimeZone(TimeZone.getDefault());。在很多地方,我直接将获取的时间(以毫秒为单位)与 long now = System.currentTimeMillis(); 进行比较,所以我只是做了一个 now = mCalendar.getTimeInMillis() 来处理这个问题。

现在当时区改变时表盘会正确改变时间。我猜我下载的其他表盘没有正确处理这个问题!