2016-08-17 6 views
2

私のアプリでは、次のコードを使用して特定の言語を設定しています。言語はアプリ内のSharedPreferencesに保存されます。 これはAPIレベル23まで完全に動作します。 Android N SharedPreferencesも正しく動作しますが、正しい言語コード文字列を返しますが、ロケールは変更されません(電話機のデフォルト言語を設定します)。何が間違っていますか?言語をプログラムで変更する(Android N 7.0 - API 24)

アップデート1:私はそれが正しいロケールを返しますが、アプリの言語が変更されていないLog.v("MyLog", config.locale.toString());すぐres.updateConfiguration(config, dm)後に使用する場合。

アップデート2:はまた、私は活動を再開(古いものに新しい意図と仕上げを使用して)、その後、ロケールと変更した場合、それが適切に言語を変更し、それがさらに回転後の正しい言語が表示されていることを述べました。しかし、私は、アプリケーションを閉じて、再び開いて、私はデフォルトの言語を取得します。それは奇妙だ。

public class ActivityMain extends AppCompatActivity { 

    //... 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     // Set locale 
     SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this); 
     String lang = pref.getString(ActivityMain.LANGUAGE_SAVED, "no_language"); 
     if (!lang.equals("no_language")) { 
      Resources res = context.getResources(); 
      Locale locale = new Locale(lang); 
      Locale.setDefault(locale); 
      DisplayMetrics dm = res.getDisplayMetrics(); 
      Configuration config = res.getConfiguration(); 
      if (Build.VERSION.SDK_INT >= 17) { 
       config.setLocale(locale); 
      } else { 
       config.locale = locale; 
      } 
     } 
     res.updateConfiguration(config, dm); 

     setContentView(R.layout.activity_main); 
     //... 
    } 
    //... 
} 

アップデート3:答えはここにもあります:https://stackoverflow.com/a/40849142/3935063

+0

https://developer.android.com/preview/features/multilingual-support.html – CommonsWare

+0

@CommonsWare再生のためのおかげで、残念ながらこのリンクは役立ちません。今、ロケールを変更して新しい意図を使用してアクティビティを再起動し、古いものを終了すると、言語が適切に変更され、ローテーション(アクティビティの再作成)後に正しい言語が表示されることにも言及しました。しかし、私は、アプリケーションを閉じて、再び開いて、私はデフォルトの言語を取得します。理解できません。それは奇妙だ。 – user35603

+0

@ user35603解決策は見つかりましたか? – Jamal

答えて

7

新しいクラスがContextWrapper

public class MyContextWrapper extends ContextWrapper { 
    public MyContextWrapper(Context base) { 
     super(base); 
    } 

    @TargetApi(Build.VERSION_CODES.N) 
    public static ContextWrapper wrap(Context context, Locale newLocale) { 
     Resources res = context.getResources(); 
     Configuration configuration = res.getConfiguration(); 

     if (VersionUtils.isAfter24()) { 
      configuration.setLocale(newLocale); 

      LocaleList localeList = new LocaleList(newLocale); 
      LocaleList.setDefault(localeList); 
      configuration.setLocales(localeList); 

      context = context.createConfigurationContext(configuration); 

     } else if (VersionUtils.isAfter17()) { 
      configuration.setLocale(newLocale); 
      context = context.createConfigurationContext(configuration); 

     } else { 
      configuration.locale = newLocale; 
      res.updateConfiguration(configuration, res.getDisplayMetrics()); 
     } 

     return new ContextWrapper(context); 
    } 
} 

オーバーライド活動のattachBaseContext方法

@Override 
protected void attachBaseContext(Context newBase) { 
    Locale languageType = LanguageUtil.getLanguageType(mContext); 
    super.attachBaseContext(MyContextWrapper.wrap(newBase, languageType)); 
} 
を拡張して作成します。

アクティビティを終了してもう一度開始すると、新しいロケールが有効になります。

デモ:https://github.com/fanturbo/MultiLanguageDemo

+0

LanguageUtilまたはMyContextWrapperクラスを変更して、アプリ全体に言語を設定するときはどうすればよいですか? –

+0

@MinaFawzy申し訳ありません、あなたは何を意味するのか分かりません.Plzは詳細を記述します。 – turbofan

関連する問題