Phát hiện múi giờ của điện thoại

Đối với các thiết bị chạy Android 11 trở xuống, tính năng tự động phát hiện múi giờ trong AOSP dựa vào các tín hiệu từ hệ thống con điện thoại. Do sự phụ thuộc vào hệ thống con của điện thoại, nên tính năng tự động phát hiện múi giờ trên Android 11 trở xuống chỉ giới hạn ở các thiết bị điện thoại.

Khi có tính năng phát hiện múi giờ qua điện thoại, tính năng này sẽ hoạt động bằng cách sử dụng các tín hiệu Mã quốc gia trên thiết bị di động (MCC)Mã nhận dạng mạng và múi giờ (NITZ).

Ví dụ: một thiết bị ở Pháp có thể xác định múi giờ chỉ dựa trên MCC do các trạm di động lân cận báo cáo. Điều này có thể xảy ra vì Pháp được biết là sử dụng một múi giờ duy nhất.

Khi một quốc gia sử dụng nhiều múi giờ, chỉ riêng MCC thì không đủ để xác định múi giờ. Đối với những quốc gia này, thiết bị cũng sử dụng tín hiệu NITZ để xác định múi giờ chính xác. Phương thức này hoạt động tốt ở nhiều nơi trên thế giới nhưng yêu cầu tín hiệu NITZ phải có sẵn và chính xác, do đó, phương thức này phụ thuộc vào nhà mạng.

Tính năng phát hiện múi giờ qua điện thoại là một trình phát hiện thụ động. Mã này luôn chạy và do đó, các đề xuất về điện thoại thường được đưa ra ngay cả khi thuật toán time_zone_detector đang hoạt động hiện không phải là điện thoại.

Giới hạn phát hiện múi giờ của điện thoại

Ngay cả khi có tín hiệu NITZ chính xác, tính năng phát hiện múi giờ qua điện thoại không phải lúc nào cũng hoạt động tốt ở mọi quốc gia. Lý do là NITZ chỉ chứa thông tin chênh lệch giờ và giờ mùa hè, không phải lúc nào cũng đủ để xác định duy nhất một múi giờ.

Có nhiều nơi trên thế giới có thể xảy ra sự cố về múi giờ này. Ví dụ: không thể phân biệt Denver Colorado và Phoenix Arizona ở Hoa Kỳ bằng tín hiệu NITZ vào mùa đông, nhưng có thể phân biệt vào các mùa khác. Mọi vị trí có múi giờ trùng lặp tương tự đều có thể gặp phải vấn đề này.

Bảng sau đây trình bày chi tiết hành vi của thiết bị tuỳ theo mùa, lấy ví dụ về Denver và Phoenix:

Vị trí và mùa Thông tin từ MCC hoặc NITZ Phát hiện hành vi và múi giờ
Denver, Colorado
Mùa đông
Thời gian: 12:00:00 ngày 1 tháng 1 năm 2021
Quốc gia: Hoa Kỳ
Mức chênh lệch: UTC-7, không có giờ mùa hè
Hai mã vùng khớp nhau:
  • Mỹ/Denver
  • America/Phoenix

Thiết bị được đặt chính xác thành America/Denver.
Phoenix, Arizona
Mùa đông
Thời gian: 12:00:00 ngày 1 tháng 1 năm 2021
Quốc gia: Hoa Kỳ
Mức chênh lệch: UTC-7, không có giờ mùa hè
Hai mã vùng khớp nhau:
  • Mỹ/Denver
  • America/Phoenix

Thiết bị được đặt không chính xác thành America/Denver.
Denver, Colorado
Mùa hè
Thời gian: 12:00:00 ngày 1 tháng 7 năm 2021
Quốc gia: Hoa Kỳ
Mức chênh lệch: UTC-6, giờ mùa hè
Một mã vùng khớp:
  • America/Denver

Thiết bị được đặt chính xác thành America/Denver.
Phoenix, Arizona
Mùa hè
Thời gian: 12:00:00 ngày 1 tháng 7 năm 2021
Quốc gia: Hoa Kỳ
Mức chênh lệch: UTC-7, không có giờ tiết kiệm ánh sáng ban ngày
Một mã vùng khớp:
  • America/Phoenix

Thiết bị được đặt chính xác thành America/Phoenix.

Các ví dụ ở trên cho thấy rằng trong mùa đông, các thiết bị Android ở Denver hoặc Arizona phải chọn một trong hai mã múi giờ trùng khớp. Mã này có thể không chính xác đối với một số thiết bị nhưng vẫn hiển thị thời gian địa phương rõ ràng là chính xác. Đồng hồ, lịch và các ứng dụng khác của thiết bị hiển thị thời gian địa phương dự kiến ngay cả khi mã múi giờ không chính xác vì cả hai mã múi giờ đều tính toán cùng một thời gian địa phương trong mùa đông.

Tuy nhiên, vào mùa xuân, khi Denver áp dụng giờ mùa hè và Phoenix không áp dụng, một số thiết bị có thể tạm thời hiển thị giờ địa phương không chính xác nếu được đặt sai mã múi giờ cho vị trí của người dùng. Lỗi này sẽ được khắc phục ngay khi thiết bị nhận được tín hiệu NITZ mới (cụ thể là tín hiệu chứa thông tin chênh lệch "UTC-7, không có giờ mùa hè"), nhưng có thể mất chút thời gian và phụ thuộc vào nhà mạng.

Do đó, lịch hoặc các ứng dụng khác lưu trữ hoặc mang theo mã múi giờ từ mùa đông sang mùa xuân có thể hiển thị và sử dụng không đúng giờ địa phương cho đến khi các ứng dụng liên quan cập nhật mã múi giờ.

Gỡ lỗi và thử nghiệm

Phần sau đây mô tả các lệnh shell để gỡ lỗi và kiểm thử tính năng phát hiện múi giờ của điện thoại.

Thiết lập môi trường kiểm thử

Người kiểm thử thường sử dụng môi trường kiểm thử có một tế bào điện thoại được kiểm thử hoặc mô phỏng để kiểm tra hành vi phát hiện múi giờ điện thoại. Bạn có thể sử dụng ô kiểm thử để mô phỏng các mạng có nhiều MCC, đồng thời gửi tín hiệu NITZ đến các thiết bị rồi theo dõi hiệu ứng của các tín hiệu đó.

Để thiết bị phát hiện được múi giờ, thông tin tín hiệu NITZ phải chính xác, nhất quán với MCC và khớp với bản sao IANA TZDB (quy tắc múi giờ) của thiết bị. Các tín hiệu NITZ không nhất quán với MCC sẽ khiến thuật toán điện thoại trở nên không chắc chắn.

Ví dụ: nếu MCC mà ô kiểm thử sử dụng là dành cho Hoa Kỳ, thì tín hiệu NITZ phải chứa "giờ toàn cầu", thông tin về độ lệch và giờ tiết kiệm ánh sáng ban ngày chính xác cho khu vực nào đó ở Hoa Kỳ.

Tương tác với dịch vụ com.android.phone

Để xác minh rằng thiết bị đang nhận được đề xuất chính xác về múi giờ điện thoại, hãy sử dụng:

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

Thao tác này sẽ kết xuất thông tin điện thoại, bạn cũng có thể tìm thấy thông tin này trong báo cáo lỗi Android. Trên các thiết bị có nhiều SIM, sẽ có thông tin cho từng đài phát SIM.

Nhật ký múi giờ cho thấy các đề xuất mà quy trình điện thoại đã gửi đến time_zone_detector và lý do gửi các đề xuất đó.

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")]}