0

私がやろうとしているのは、Android の基本的なアラーム アプリです。UI を介して日付と時刻を設定すると (たとえば、2012-09-26 の 14:37)、タイムゾーンに関係なく、その時刻にアラームが鳴ります。その設定は、日付値とミリ秒単位の日の始まりからのオフセットの 2 つの個別の値としてシリアル化されます。

また、日付/時刻操作に Joda ライブラリを使用するというミスもありました。この API は .NET の DateTime API と非常によく似ているため、私を混乱させましたが、オブジェクトの値が UTC であり、そのプロパティがローカル時間であるという、デフォルトの Java フレームワーク API と同じ二重性の問題に悩まされていました (この概念は私の心を吹き飛ばします) )。また、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
    }
}

アプリの実行中に(設定が行われた後)タイムゾーンを切り替えようとするまで、すべてがうまくいきます。ここから奇妙なことが始まります。何をしてもうまくいかないということ以外に、何が間違っているのかを正確に説明することさえできません。

私が探しているのは、Joda または標準 API のいずれかで Java/Android でタイムゾーンに依存しない計算を行う方法に関する一般的な方向性だと思います。

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をリッスンするaと結合します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 に答える