編輯:關於Android編程
簡單介紹下這個需求的緣由,這段時間因公司業務需要,其中有一項“設置系統語言”功能,就是在使用APP的過程中,動態的去切換整個Android機器的語言,具體參照手機設置頁面有語言切換功能。起初想來是很簡單的事情嘛,不就是個簡單的資源國際化嘛,strings.xml資源文件一整還不給OK?真正動起手來就真不是這麼一回事了,國際化是沒問題,但是怎樣能更改所有頁面的文字資源呢,這是一個問題。下面介紹下網上找的幾個方案。
一、API欺騙
燒制到手機中的android.jar包含了Android所需的各種類與方法;而供開發者使用的android.jar只是其中的一部分。API欺騙是指在應用中去模擬未公開的類和方法讓應用編譯通過並生成APK,然而在應用實際運行中調用的卻仍是燒制到手機中真實的android.jar。
二、使用Java反射機制
IActivityManager與ActivityManagerNative都是非公開類,使用Java反射去調用其中的方法。
但是這個弊端是顯而易見的,上述兩種方法都是去更改系統的語言的類型,功能和你去設置頁面去設置語言類型的效果一樣。發現對當前系統設置了新的Locale後,不單自己的應用語系改變了,系統所有的應用語系都改變了,這正是我們所需要的。
核心代碼如下:
/** * TODO<更新系統語言> * * @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); // 此處需要聲明權限:android.permission.CHANGE_CONFIGURATION // 會重新調用 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的反射機制,調用那些隱藏的方法就可以實現了。
需要注意的是調用此方法:
// objIActMag.updateConfiguration(config); mtdIActMag$updateConfiguration.invoke(objIActMag, config);
需要加上權限:
android.permission.CHANGE_CONFIGURATION
並且此處會重新調用onCreate方法,我就在這個地方處被坑了一把。(如果調用此方法的時候做了一些邏輯,就注意下)。
最後聲明:
既然是更改系統的配置當然你的簽名也應該是系統簽名和sharedUserId。不然會類似以下的錯誤!
error:
java.lang.SecurityException: Permission Denial: updateConfiguration() from pid=31594, uid=10099 requires android.permission.CHANGE_CONFIGURATION
各位都注意下吧~
目錄:1.SeekBar的應用場景2.SeekBar的簡單使用與事件監聽3.圖片資源自定義SeekBar+手機音量調節4.xml繪制自定義SeekBar1.SeekBar
這篇博客的目標是摸清楚默認編譯整個android系統時代碼的流程。當我們執行make的時候,會查找當前的Makefie文件或者makefile文件並且執行,在androi
安卓系統手機的通知欄可以顯示QQ圖標,但沒有退出QQ的狀態下,手機qq不顯示圖標怎麼回事?手機qq不顯示圖標怎麼辦?下面我們就一起來看看吧!手機qq不顯示圖
第一步、先爆項目demo照片,代碼不多,不要怕 第二步、應該知道Java反射相關知識如果不知道或者忘記的小伙伴請猛搓這裡,Android插件化開發基礎之Java