0

我想做的是Android上的基本警报应用程序。当我通过 UI 设置日期和时间时(比如 2012 年 9 月 26 日 14:37),无论时区如何,我都希望闹钟在那个时候响起。该设置被序列化为两个单独的值 - 日期值和从一天开始的偏移量(以毫秒为单位)。

我在使用 Joda 库进行日期/时间操作时也犯了一个错误。该 API 看起来与 .NET 的 DateTime API 非常相似,让我感到困惑,但仍然遇到与默认 Java 框架 API 相同的二元性问题,其中对象值是 UTC,但它的属性是本地时间(顺便说一句,这个概念让我大吃一惊) )。它似乎也无法自动获取 Android 的时区更改。

这是我所拥有的摘要:

// part of reminder class
public DateTime getNextAlarm()
{
    DateTime now = DateTime.now();
    DateTime next = date.withMillisOfDay(time);
    while (next.compareTo(now) <= 0)
        next = next.plusDays(repeat);
    return next;
}

// inside worker thread
workerEnabled = true;
while (workerEnabled)
{
    try
    {
        Thread.sleep(10000);
    }
    catch (InterruptedException e)
    {
        workerEnabled = false;
        return;
    }

    DateTimeZone tz = DateTimeZone.forTimeZone(TimeZone.getDefault());
    if (nextAlarm != null && nextAlarm.withZoneRetainFields(tz).compareTo(new DateTime(tz)) < 0)
    {
        nextAlarm = reminder.getNextAlarm();

        // perform alarm action
    }
}

一切都很好,直到我尝试在应用程序运行时切换时区(在设置完成之后)。这就是奇怪的事情开始的地方。我什至无法描述究竟是什么错误,除了那不管我做什么它都不能正常工作。

我想我正在寻找的是关于如何在 Java/Android 中使用 Joda 或标准 API 进行与时区无关的数学的一般方向。

4

2 回答 2

2

AlarmManager习惯在一天中的特定时间下载文件。我有一个助手类的示例代码......

public void createDownloadAlarm() {
    Intent i = new Intent(MyApp.ACTION_DOWNLOAD_FILES);
    PendingIntent operation = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);

    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.HOUR_OF_DAY, 1);
    cal.set(Calendar.MINUTE, 30);
    cal.set(Calendar.SECOND, 0);

    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, operation);
}

使用Calendar.getInstance()然后使用该set(...)方法会创建一个警报,该警报将在任何时区的确切时间触发。

要按照您的描述进行操作,我会将上面的代码与BroadcastReceiver侦听的代码结合起来ACTION_TIMEZONE_CHANGED- 在清单中将其注册为android.intent.action.TIMEZONE_CHANGED.

BroadcastReceiver我让它调用我上面显示的方法中,它应该(理论上)取消上一个警报并在时区更改时为当地时间设置一个新警报。

于 2012-09-26T20:23:24.680 回答
0

事实证明,Jodatime 不处理 Android 上的时区更改。重新启动应用程序会有所帮助,但该解决方案不适用于一直运行的后台服务。我最终使用 Calendar/Date API 重写了代码,尽管它丑陋而痛苦。

于 2012-09-27T23:18:00.550 回答