最近實(shí)際項(xiàng)目中,需要獲取手機(jī)系統(tǒng)國(guó)家地區(qū)來做一些特殊邏輯稼病。很簡(jiǎn)單嘛选侨,Locale#getDefault#getCountryCode,ok完成然走。實(shí)際run起來后援制,發(fā)現(xiàn)結(jié)果竟然返回為空。
What a f**k, 什么鬼芍瑞。系統(tǒng)API怎么會(huì)有這種錯(cuò)誤晨仑,翻開了API文檔和google也沒有任何有用信息。仔細(xì)思索后覺還是自己的問題拆檬,我們app支持18種語言洪己,在啟動(dòng)時(shí)會(huì)根據(jù)系統(tǒng)默認(rèn)和用戶設(shè)置來重置語言。仔細(xì)翻看這部分代碼發(fā)現(xiàn)竟贯,果然是在切換語言時(shí)重新設(shè)置了app resource的Locale信息答捕,并在構(gòu)造Locale時(shí)沒有填入countryCode。
再通過debug來驗(yàn)證自己的想法屑那,果然Resource中的Locale和Locale#getDefault是一樣的拱镐。
那么如何去獲取到正確的系統(tǒng)國(guó)家呢? 一個(gè)方法是在設(shè)置語言時(shí)傳入正確的countryCode持际,但這個(gè)也受限于如何判定正確的國(guó)家沃琅。此外在翻看Resources的api文檔發(fā)現(xiàn)一個(gè)getSystem的靜態(tài)方法。注釋如下:
Return 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在啟動(dòng)app進(jìn)程時(shí)选酗,都是從zoyge進(jìn)程中fork出來阵难。其中為了節(jié)約資源岳枷,也會(huì)將系統(tǒng)的資源"copy"一份芒填,這部分資源就可以通過Resources#getSystem來獲取到呜叫。那么這里獲取到的Locale就是系統(tǒng)中設(shè)置的信息。
8.0適配
在android o上殿衰,google改變了locale的規(guī)則朱庆。之前只存在一個(gè)locale,而后面是可以支持一個(gè)locale list闷祥。
在support包中娱颊,還有一個(gè)幫助類根據(jù)Resource獲取到Locale信息,避免的N以上的List判斷凯砍。
ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration())
此外需要注意的是箱硕,在8.0 版本如果設(shè)置單個(gè)Locale可能會(huì)導(dǎo)致ActivityThread中NPE crash,需要將單個(gè)Locale變成一個(gè)List悟衩。
Tips: 如何修改手機(jī)國(guó)家地區(qū)剧罩? Android中并沒有直接設(shè)置國(guó)家地區(qū)的選項(xiàng),實(shí)際可以通過修改顯示中語言來完成座泳,N以上辦法可以選擇多個(gè)語言惠昔,規(guī)則是按照語言排序。