Android實(shí)現(xiàn)系統(tǒng)語言切換功能
簡(jiǎn)單介紹下這個(gè)需求的緣由,這段時(shí)間因公司業(yè)務(wù)需要,其中有一項(xiàng)“設(shè)置系統(tǒng)語言”功能,就是在使用APP的過程中,動(dòng)態(tài)的去切換整個(gè)Android機(jī)器的語言,具體參照手機(jī)設(shè)置頁面有語言切換功能。起初想來是很簡(jiǎn)單的事情嘛,不就是個(gè)簡(jiǎn)單的資源國際化嘛,strings.xml資源文件一整還不給OK?真正動(dòng)起手來就真不是這么一回事了,國際化是沒問題,但是怎樣能更改所有頁面的文字資源呢,這是一個(gè)問題。下面介紹下網(wǎng)上找的幾個(gè)方案。
一、API欺騙
燒制到手機(jī)中的android.jar包含了Android所需的各種類與方法;而供開發(fā)者使用的android.jar只是其中的一部分。API欺騙是指在應(yīng)用中去模擬未公開的類和方法讓應(yīng)用編譯通過并生成APK,然而在應(yīng)用實(shí)際運(yùn)行中調(diào)用的卻仍是燒制到手機(jī)中真實(shí)的android.jar。
二、使用Java反射機(jī)制
IActivityManager與ActivityManagerNative都是非公開類,使用Java反射去調(diào)用其中的方法。
但是這個(gè)弊端是顯而易見的,上述兩種方法都是去更改系統(tǒng)的語言的類型,功能和你去設(shè)置頁面去設(shè)置語言類型的效果一樣。發(fā)現(xiàn)對(duì)當(dāng)前系統(tǒng)設(shè)置了新的Locale后,不單自己的應(yīng)用語系改變了,系統(tǒng)所有的應(yīng)用語系都改變了,這正是我們所需要的。
核心代碼如下:
/** * TODO<更新系統(tǒng)語言> * * @author Xiho * @versionCode 1 <每次修改提交前+1> */ @SuppressWarnings("unchecked") public class LanguageUtils { public static void updateLanguage(Locale locale) { try { Object objIActMag, objActMagNative; Class clzIActMag = Class.forName("android.app.IActivityManager"); Class clzActMagNative = Class .forName("android.app.ActivityManagerNative"); //amn = ActivityManagerNative.getDefault(); Method mtdActMagNative$getDefault = clzActMagNative .getDeclaredMethod("getDefault"); objIActMag = mtdActMagNative$getDefault.invoke(clzActMagNative); // objIActMag = amn.getConfiguration(); Method mtdIActMag$getConfiguration = clzIActMag .getDeclaredMethod("getConfiguration"); Configuration config = (Configuration) mtdIActMag$getConfiguration .invoke(objIActMag); // set the locale to the new value config.locale = locale; //持久化 config.userSetLocale = true; Class clzConfig = Class .forName("android.content.res.Configuration"); java.lang.reflect.Field userSetLocale = clzConfig .getField("userSetLocale"); userSetLocale.set(config, true); // 此處需要聲明權(quán)限:android.permission.CHANGE_CONFIGURATION // 會(huì)重新調(diào)用 onCreate(); Class[] clzParams = { Configuration.class }; // objIActMag.updateConfiguration(config); Method mtdIActMag$updateConfiguration = clzIActMag .getDeclaredMethod("updateConfiguration", clzParams); mtdIActMag$updateConfiguration.invoke(objIActMag, config); BackupManager.dataChanged("com.android.providers.settings"); } catch (Exception e) { e.printStackTrace(); } } }
這樣我們利用JAVA的反射機(jī)制,調(diào)用那些隱藏的方法就可以實(shí)現(xiàn)了。
需要注意的是調(diào)用此方法:
// objIActMag.updateConfiguration(config); mtdIActMag$updateConfiguration.invoke(objIActMag, config);
需要加上權(quán)限:
android.permission.CHANGE_CONFIGURATION
并且此處會(huì)重新調(diào)用onCreate方法,我就在這個(gè)地方處被坑了一把。(如果調(diào)用此方法的時(shí)候做了一些邏輯,就注意下)。
最后聲明:
既然是更改系統(tǒng)的配置當(dāng)然你的簽名也應(yīng)該是系統(tǒng)簽名和sharedUserId。不然會(huì)類似以下的錯(cuò)誤!
error:
java.lang.SecurityException: Permission Denial: updateConfiguration() from pid=31594, uid=10099 requires android.permission.CHANGE_CONFIGURATION
各位都注意下吧~
- Android實(shí)現(xiàn)app應(yīng)用多語言切換功能
- Android app應(yīng)用多語言切換功能實(shí)現(xiàn)
- android動(dòng)態(tài)設(shè)置app當(dāng)前運(yùn)行語言的方法
- 詳解Android更改APP語言模式的實(shí)現(xiàn)過程
- android 使用kotlin 實(shí)現(xiàn)點(diǎn)擊更換全局語言(中日英切換)
- Android 7.0以上版本實(shí)現(xiàn)應(yīng)用內(nèi)語言切換的方法
- Android 系統(tǒng)語言切換監(jiān)聽和設(shè)置實(shí)例代碼
- Android實(shí)現(xiàn)應(yīng)用內(nèi)置語言切換功能
- Android App中進(jìn)行語言的切換
相關(guān)文章
listview 選中高亮顯示實(shí)現(xiàn)方法
當(dāng)點(diǎn)擊左側(cè)ListView后,選中的一行就會(huì)一直呈高亮狀態(tài)顯示,圖中選中行字的顏色顯示為藍(lán)色(注意:是選中行后一直高亮,而不是只是點(diǎn)擊時(shí)高亮),如果再次點(diǎn)擊另外的一行, 則新的那一行就高亮,下面就來實(shí)現(xiàn)這個(gè)高亮效果的顯示2012-11-11Flutter?將Dio請(qǐng)求轉(zhuǎn)發(fā)原生網(wǎng)絡(luò)庫的實(shí)現(xiàn)方案
這篇文章主要介紹了Flutter?將Dio請(qǐng)求轉(zhuǎn)發(fā)原生網(wǎng)絡(luò)庫,需要注意添加NativeNetInterceptor,如果有多個(gè)攔截器,例如LogInterceptors等等,需要將NativeNetInterceptor放到最后,需要的朋友可以參考下2022-05-05Android開發(fā)之ListView的head消失頁面導(dǎo)航欄的漸變出現(xiàn)和隱藏
這篇文章主要介紹了Android開發(fā)之ListView的head消失頁面導(dǎo)航欄的漸變出現(xiàn)和隱藏的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11Android 實(shí)現(xiàn)按兩次返回鍵退出程序(兩種方法)
這篇文章主要介紹了Android 實(shí)現(xiàn)按兩次返回鍵退出程序(兩種方法)的相關(guān)資料,這里不僅實(shí)現(xiàn)還對(duì)原理進(jìn)行了分析,需要的朋友可以參考下2017-07-07Flutter在項(xiàng)目中使用動(dòng)畫不使用包實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了Flutter在項(xiàng)目中使用動(dòng)畫不使用包實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11如何在Android中實(shí)現(xiàn)漸顯按鈕的左右滑動(dòng)效果
本篇文章是對(duì)在Android中實(shí)現(xiàn)漸顯按鈕的左右滑動(dòng)效果進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06Android開發(fā)筆記之:AsyncTask的應(yīng)用詳解
本篇文章是對(duì)Android中AsyncTask的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05功能強(qiáng)大的登錄界面Android實(shí)現(xiàn)代碼
這篇文章主要為大家分享了功能強(qiáng)大的登錄界面Android實(shí)現(xiàn)代碼,驗(yàn)證碼制作方法,自帶一鍵刪除功能,用戶名密碼為空時(shí)抖動(dòng)提示效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10Android ContentProvider實(shí)現(xiàn)獲取手機(jī)聯(lián)系人功能
這篇文章主要為大家詳細(xì)介紹了Android ContentProvider實(shí)現(xiàn)獲取手機(jī)聯(lián)系人功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07