テレフォニータイムゾーン検出

Android 11以下を実行しているデバイスの場合、AOSPでの自動タイムゾーン検出は、テレフォニーサブシステムからの信号に依存します。テレフォニーサブシステムに依存しているため、Android11以下での自動タイムゾーン検出はテレフォニーデバイスに限定されています。

テレフォニータイムゾーン検出が利用可能な場合、モバイル国コード(MCC)およびネットワークIDおよびタイムゾーン(NITZ)信号を使用して機能します。

たとえば、フランスのデバイスは、近くのセルタワーから報告されたMCCのみに基づいてタイムゾーンを識別できます。これが可能なのは、フランスが単一のタイムゾーンを使用することが知られているためです。

国が複数のタイムゾーンを使用している場合、MCCだけではタイムゾーンを特定するのに十分ではありません。これらの国では、デバイスはNITZ信号を使用して正しいタイムゾーンを識別します。これは世界中の多くの場所でうまく機能しますが、NITZ信号が利用可能で正しいことが必要であるため、キャリアに依存します。

テレフォニータイムゾーン検出はパッシブ検出器です。これは常に実行されるため、 time_zone_detectorの発信元が現在テレフォニーでない場合でも、テレフォニーの提案が行われることがよくあります。

テレフォニータイムゾーン検出の制限

正しいNITZ信号が利用可能であっても、テレフォニータイムゾーン検出はすべての国で常にうまく機能するとは限りません。これは、NITZにはオフセットと夏時間の情報しか含まれていないためです。これらの情報は、タイムゾーンを一意に識別するのに必ずしも十分ではありません。

このタイムゾーンの問題が発生する可能性のある場所は、世界中にたくさんあります。たとえば、米国のコロラド州デンバーとアリゾナ州フェニックスは、冬の間はNITZ信号を使用して区別できませんが、他の季節には区別できます。同様にタイムゾーンが重複している場所では、この種の問題が発生する可能性があります。

次の表は、例としてデンバーとフェニックスの季節に応じたデバイスの動作を示しています。

場所と季節MCCまたはNITZからの情報検出されたタイムゾーンと動作
コロラド州デンバー
時間:2021年1月1日12:00:00
国:米国
オフセット:UTC-7、夏時間なし
2つのゾーンIDが一致します:
  • アメリカ/デンバー
  • アメリカ/フェニックス

デバイスはAmerica / Denverに正しく設定されています。
アリゾナ州フェニックス
時間:2021年1月1日12:00:00
国:米国
オフセット:UTC-7、夏時間なし
2つのゾーンIDが一致します:
  • アメリカ/デンバー
  • アメリカ/フェニックス

デバイスが誤ってAmerica / Denverに設定されています。
コロラド州デンバー
時間:2021年7月1日12:00:00
国:米国
オフセット:UTC-6、夏時間
1つのゾーンIDが一致します:
  • アメリカ/デンバー

デバイスはAmerica / Denverに正しく設定されています。
アリゾナ州フェニックス
時間:2021年7月1日12:00:00
国:米国
オフセット:UTC-7、夏時間なし
1つのゾーンIDが一致します:
  • アメリカ/フェニックス

デバイスはAmerica / Phoenixに正しく設定されています。

上記の例は、冬の間、デンバーまたはアリゾナのAndroidデバイスが2つの一致するタイムゾーンIDのいずれかを選択する必要があることを示しています。これは、一部のデバイスでは正しくない可能性がありますが、明らかに正しい現地時間を表示します。両方のタイムゾーンIDが冬の間同じ現地時間を計算するため、タイムゾーンIDが正しくない場合でも、デバイスクロック、カレンダー、およびその他のアプリは予想現地時間を表示します。

ただし、春にデンバーが夏時間を採用し、フェニックスが夏時間を採用しない場合、一部のデバイスは、ユーザーの場所に対して間違ったタイムゾーンIDに設定されていると、一時的に誤った現地時間を表示する場合があります。これは、デバイスが新しいNITZ信号(具体的には、「UTC-7、夏時間なし」のオフセット情報を含む信号)を受信するとすぐに修正されますが、これには時間がかかる場合があり、通信事業者によって異なります。

その結果、冬から春にタイムゾーンIDを保存または引き継ぐカレンダーやその他のアプリは、関連するアプリがタイムゾーンIDを更新するまで、間違った現地時間を表示して使用する可能性があります。

デバッグとテスト

次のセクションでは、テレフォニータイムゾーン検出機能をデバッグおよびテストするためのシェルコマンドについて説明します。

テスト環境のセットアップ

テスターは通常、テストまたはシミュレートされたテレフォニーセルを備えたテスト環境を使用して、テレフォニータイムゾーンの検出動作をチェックします。テストセルを使用して、さまざまなMCCを使用するネットワークをシミュレートし、NITZ信号をデバイスに送信して、その影響を監視できます。

デバイスがタイムゾーンを検出するには、NITZ信号情報が正しく、MCCと一致し、デバイスのIANA TZDB(タイムゾーンルール)のコピーと一致している必要があります。 MCCと矛盾するNITZ信号により、テレフォニーの発信元が不確実になります。

たとえば、テストセルで使用されるMCCが米国用である場合、NITZ信号には、米国のどこかで正しい「ユニバーサルタイム」、オフセット、および夏時間の情報が含まれている必要があります。

com.android.phoneサービスとのやり取り

デバイスが正しいテレフォニータイムゾーンの提案を受信して​​いることを確認するには、次を使用します。

adb shell dumpsys activity service \
    com.android.phone/com.android.phone.TelephonyDebugService

これにより、テレフォニー情報がダンプされます。これは、Androidのバグレポートにも記載されています。複数のSIMを搭載したデバイスでは、SIM無線ごとに情報があります。

タイムゾーンログには、テレフォニープロセスがtime_zone_detectorに送信した提案と、提案を送信する理由が表示されます。

TimeServiceHelperImpl:
          SystemClock.elapsedRealtime()=11864061
          System.currentTimeMillis()=1620652067178
          Time Logs:
...

Time zone Logs:
    18602 / 2021-05-10T09:50:21.718Z - Suggesting time zone update:
    TelephonyTimeZoneSuggestion{mSlotIndex=0, mZoneId='null', mMatchType=0, mQuality=0,
    mDebugInfo=[getTimeZoneSuggestion: nitzSignal=TimestampedValue{mReferenceTimeMillis=14098,
    mValue=NitzData{mOriginalString=21/05/10,09:50:18+04,01, mZoneOffset=3600000,
    mDstOffset=3600000, mCurrentTimeMillis=1620640218000, mEmulatorHostTimeZone=null}},
    countryIsoCode=null, Detection
    reason=handleNitzReceived(TimestampedValue{mReferenceTimeMillis=14098,
    mValue=NitzData{mOriginalString=21/05/10,09:50:18+04,01, mZoneOffset=3600000,
    mDstOffset=3600000, mCurrentTimeMillis=1620640218000, mEmulatorHostTimeZone=null}})]}
    18831 / 2021-05-10T09:50:21.948Z - Suggesting time zone update:
    TelephonyTimeZoneSuggestion{mSlotIndex=0, mZoneId='Europe/London', mMatchType=3, mQuality=1,
    mDebugInfo=[findTimeZoneFromCountryAndNitz: countryIsoCode=gb,
    nitzSignal=TimestampedValue{mReferenceTimeMillis=14098,
    mValue=NitzData{mOriginalString=21/05/10,09:50:18+04,01, mZoneOffset=3600000,
    mDstOffset=3600000, mCurrentTimeMillis=1620640218000, mEmulatorHostTimeZone=null}},
    findTimeZoneFromCountryAndNitz: lookupResult=OffsetResult{mTimeZone(ID)=Europe/London,
    mIsOnlyMatch=true}, Detection reason=handleCountryDetected("gb")]}