Android實現(xiàn)系統(tǒng)語言切換功能
簡單介紹下這個需求的緣由,這段時間因公司業(yè)務(wù)需要,其中有一項“設(shè)置系統(tǒng)語言”功能,就是在使用APP的過程中,動態(tài)的去切換整個Android機(jī)器的語言,具體參照手機(jī)設(shè)置頁面有語言切換功能。起初想來是很簡單的事情嘛,不就是個簡單的資源國際化嘛,strings.xml資源文件一整還不給OK?真正動起手來就真不是這么一回事了,國際化是沒問題,但是怎樣能更改所有頁面的文字資源呢,這是一個問題。下面介紹下網(wǎng)上找的幾個方案。
一、API欺騙
燒制到手機(jī)中的android.jar包含了Android所需的各種類與方法;而供開發(fā)者使用的android.jar只是其中的一部分。API欺騙是指在應(yīng)用中去模擬未公開的類和方法讓應(yīng)用編譯通過并生成APK,然而在應(yīng)用實際運(yùn)行中調(diào)用的卻仍是燒制到手機(jī)中真實的android.jar。
二、使用Java反射機(jī)制
IActivityManager與ActivityManagerNative都是非公開類,使用Java反射去調(diào)用其中的方法。
但是這個弊端是顯而易見的,上述兩種方法都是去更改系統(tǒng)的語言的類型,功能和你去設(shè)置頁面去設(shè)置語言類型的效果一樣。發(fā)現(xiàn)對當(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
// 會重新調(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)用那些隱藏的方法就可以實現(xiàn)了。
需要注意的是調(diào)用此方法:
// objIActMag.updateConfiguration(config); mtdIActMag$updateConfiguration.invoke(objIActMag, config);
需要加上權(quán)限:
android.permission.CHANGE_CONFIGURATION
并且此處會重新調(diào)用onCreate方法,我就在這個地方處被坑了一把。(如果調(diào)用此方法的時候做了一些邏輯,就注意下)。
最后聲明:
既然是更改系統(tǒng)的配置當(dāng)然你的簽名也應(yīng)該是系統(tǒng)簽名和sharedUserId。不然會類似以下的錯誤!
error:
java.lang.SecurityException: Permission Denial: updateConfiguration() from pid=31594, uid=10099 requires android.permission.CHANGE_CONFIGURATION
各位都注意下吧~
- Android實現(xiàn)app應(yīng)用多語言切換功能
- Android app應(yīng)用多語言切換功能實現(xiàn)
- android動態(tài)設(shè)置app當(dāng)前運(yùn)行語言的方法
- 詳解Android更改APP語言模式的實現(xiàn)過程
- android 使用kotlin 實現(xiàn)點擊更換全局語言(中日英切換)
- Android 7.0以上版本實現(xiàn)應(yīng)用內(nèi)語言切換的方法
- Android 系統(tǒng)語言切換監(jiān)聽和設(shè)置實例代碼
- Android實現(xiàn)應(yīng)用內(nèi)置語言切換功能
- Android App中進(jìn)行語言的切換
相關(guān)文章
activity全屏實現(xiàn)沉浸式效果,并且單獨觸摸不會彈出虛擬按鍵的方法
今天小編就為大家分享一篇activity全屏實現(xiàn)沉浸式效果,并且單獨觸摸不會彈出虛擬按鍵的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-07-07
Android開發(fā)實現(xiàn)控件雙擊事件的監(jiān)聽接口封裝類
這篇文章主要介紹了Android開發(fā)實現(xiàn)控件雙擊事件的監(jiān)聽接口封裝類,需要的朋友可以參考下2020-03-03
Android?studio實現(xiàn)動態(tài)背景頁面
這篇文章主要為大家詳細(xì)介紹了Android?studio實現(xiàn)動態(tài)背景頁面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04
Android RecyclerView的卡頓問題的解決方法
本篇文章主要介紹了Android RecyclerView的卡頓問題的解決方法,具有一定的參考價值,有興趣的可以了解一下。2017-04-04

