Android Locale.getDefault().getCountry()為空


最近實際項目中,需要獲取手機系統國家地區來做一些特殊邏輯。

很簡單嘛,

 public static String getCountry(Context context) {
        TelephonyManager tm = (TelephonyManager) BaseInfo.getSystemService(context, Context.TELEPHONY_SERVICE);
        String country = tm.getSimCountryIso();
        if (TextUtils.isEmpty(country)) {
            country = Locale.getDefault().getCountry();
        }
        if (TextUtils.isEmpty(country)) {
            country = "";
        }
        return country.toUpperCase(Locale.US);
    }

但是最近發現7.0以上部分手機獲取為空,發現問題出在Locale.getDefault().getCountry()。

系統API怎么會有這種錯誤,翻開了API文檔和google也沒有任何有用信息。仔細思索后覺還是自己的問題,我們app支持18種語言,在啟動時會根據系統默認和用戶設置來重置語言。仔細翻看這部分代碼發現,果然是在切換語言時重新設置了app resource的Locale信息,並在構造Locale時沒有填入countryCode。

再通過debug來驗證自己的想法,果然Resource中的Locale和Locale#getDefault是一樣的。

那么如何去獲取到正確的系統國家呢? 一個方法是在設置語言時傳入正確的countryCode,但這個也受限於如何判定正確的國家。此外在翻看Resources的api文檔發現一個getSystem的靜態方法。

注釋如下:a global shared Resources object that provides access to only system resources (no application resources), and is not configured for the current screen (can not use dimension units, does not change based on orientation, etc).

我們知道android在啟動app進程時,都是從zoyge進程中fork出來。其中為了節約資源,也會將系統的資源"copy"一份,這部分資源就可以通過Resources#getSystem來獲取到。那么這里獲取到的Locale就是系統中設置的信息。

7.0以上適配

在android 7.0以上,google改變了locale的規則。之前只存在一個locale,而后面是可以支持一個locale list。

在support包中,還有一個幫助類根據Resource獲取到Locale信息,避免的N以上的List判斷。

ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration())

此外需要注意的是,在8.0 版本如果設置單個Locale可能會導致ActivityThread中NPE crash,需要將單個Locale變成一個List。

Tips: 如何修改手機國家地區? Android中並沒有直接設置國家地區的選項,實際可以通過修改顯示中語言來完成,N以上辦法可以選擇多個語言,規則是按照語言排序。

為了保證與以前的Android版本的兼容性,可能的解決方案是一個簡單的檢查:

 public static String getCountry(Context context) {
        TelephonyManager tm = (TelephonyManager) BaseInfo.getSystemService(context, Context.TELEPHONY_SERVICE);
        String country = tm.getSimCountryIso();
        if (TextUtils.isEmpty(country)) {
            country = getLocale().getCountry();
        }
        if (TextUtils.isEmpty(country)) {
            country = "";
        }
        return country.toUpperCase(Locale.US);
    }

    public static Locale getLocale() {
        Locale locale;
        try {
            LocaleListCompat listCompat= ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration());
            locale= listCompat.get(0);
        }catch (Exception e){
            locale=Locale.getDefault();
        }
        return locale;
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM