1

サーバーの現在の時刻を表示する appWidget を作成しました (たとえば、2012-08-29、12:00:08)。修正期間ごとにサーバー時間を要求します (たとえば 1 時間)。サーバー時刻を受け取った場合、appWidget の表示を更新します。期間中、次のように Handler を起動して時間を更新します。

  mTick = new Runnable() {
        public void run() {
            mMillis += 1000;
            long now = SystemClock.uptimeMillis();
            long next = now + (1000 - now % 1000);
            mHandler.postAtTime(mTicker, next);
        }
    }
    mTicker.run();

私の質問: 1 久しぶりに (1 日経過)、AppWidget に表示される時間が実際のサーバー時間よりも遅くなります。上記で使用した方法は、時間を更新するのに十分正確ではないと思います。この問題に関する提案はありますか?

4

1 に答える 1

0

SystemClock.uptimeMillis()は使用しないでください。ディープ スリープで費やされた時間が含まれていないためです。これが、アプリ ウィジェットが同期していない理由です。

代わりにSystemClock.elapsedRealtime()呼び出しを使用する必要があります

Upd: 申し訳ありませんが、ここで問題を誤解していると思います。あなたがやろうとしているのは、postAtTime を使用して、しばらくしてから実行可能なものを投稿することです。postAtTime には、デバイスがディープ スリープ状態にある時間は含まれないことに注意してください。

必要なのは、ウィジェットの再描画間のデルタの正確な量を追跡することです。そのために SystemClock.elapsedRealtime() を使用する必要があります。

アルゴリズムは次のようになります。

long serverTime = getServerTime();
long lastTime = SystemClock.elapsedRealtime();

// Somewhere in updateWidget() or call on timer:
serverTime = serverTime  + SystemClock.elapsedRealtime() - lastTime;
lastTime = SystemClock.elapsedRealtime();
// At this moment in serverTime variable you have "server" time adjusted by the time which passed on device, including time spent in deep sleep
于 2012-08-29T09:49:03.247 に答える