欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android實(shí)現(xiàn)系統(tǒng)語言切換功能

 更新時(shí)間:2016年03月04日 15:09:18   投稿:lijiao  
這篇文章主要為大家詳細(xì)介紹了Android系統(tǒng)語言切換功能的實(shí)現(xiàn)方法,感興趣的小伙伴們可以參考一下

簡(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

各位都注意下吧~

相關(guān)文章

最新評(píng)論