LoginSignup
1
0

More than 5 years have passed since last update.

adbとpythonでAndroidの時計を精確に補正する

Posted at

まえがき

Androidの時計をadbコマンドから補正する場合,root化した上で下記のようなコマンドをシェル等から打ち込めば補正できる.

$ adb shell "su -c 'date `date +%s`'"

しかし,この方法では秒数単位でしか指定できないため,最悪の場合1秒の誤差が発生してしまう.
通常の使用であれば問題ないが,例えばログ出力の解析時に秒単位のズレが致命的になるような場合,この手法は使えない.
NTPのアプリを使用する方法もあるが,画面操作が必要なアプリしか見つからなかったため,自動化させるためにPythonを使ったスクリプトを作成して補正した.

戦略

至ってシンプルに,○時○分○秒.000000のときにadbコマンドを実行する.

Pythonによる実装

シェルスクリプトでも出来そうだけれど,面倒(というか分からない)だったのでPythonで実装.2系で書いているので適宜3系にしてください.

ソース

import sys
import subprocess
import time
from contextlib import closing

m = 8

def loop():
    while True:
        t = time.time()
        it = int(t*10**m)
        if it == int(t)*10**m:
            subprocess.call("adb shell \"su -c 'date %d'\"" % int(t), shell=True)
            break

if __name__=='__main__':
    loop()
    print "Done"

解説

loop()メソッドを呼び出して時刻合わせが出来るようになるまで無限ループに入る.
time.time()で時刻を取得するが,得られる値はfloatなので小数点以下の値も入っている.
mで指定した桁数まで引き上げてから丸めた値:int(t×$10^m$)と,丸めてから引き上げた値:int(t)×$10^m$を比較して,同じならコマンド実行,違うなら再度時刻取得を繰り返す.
自分の環境では8桁まで指定しても問題無く時刻合わせが出来たけれど,この辺は環境に応じて変えた方がいいかもしれない.

書いてて思ったけれど引数にmを与えて,精度を指定するメソッドの方が綺麗ですね.後,タイムアウトも出来る方が親切かもしれない.そのうち暇があれば実装します.

コマンド実行遅延の影響

実際にはadbのコマンドを実行してから反映されるまで遅延が発生するため,8桁の精度どころか10msec程度の誤差は余裕で発生してしまう.
そこで,どのくらい遅延するかを測定(方法については後日,記事を上げます)し,それをあらかじめずらしてコマンドを実行する.
具体的には

padding = 0.07
...
    t = time.time() + padding

といった形で時間をずらしておく.自分の環境では0.07=70msecほどズレていたし,あまり安定しないのでこの方法では100msec程度のズレは許容せざるを得ない.

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0