web-dev-qa-db-ja.com

Androidアプリ内のデフォルトロケールを変更および設定する

Androidアプリのグローバリゼーションに取り組んでいます。アプリ内から異なるロケールを選択するオプションを提供する必要があります。アクティビティ(HomeActivity)で次のコードを使用して、変更するオプションを提供していますロケール

Configuration config = new Configuration();
config.locale = selectedLocale; // set accordingly 
// eg. if Hindi then selectedLocale = new Locale("hi");
Locale.setDefault(selectedLocale); // has no effect
Resources res = getApplicationContext().getResources();
res.updateConfiguration(config, res.getDisplayMetrics());

これは、画面のローテーションなどの設定変更がなく、ロケールがデフォルトでコードによって設定されたロケールではなく、Androidシステムレベルのロケールに設定されている場合に限り、正常に機能します。

Locale.setDefault(selectedLocale);

私が考えることができる1つの解決策は、SharedPreferencesを使用してユーザーが選択したロケールを永続化し、各アクティビティのonCreate()メソッドで、構成の変更ごとにonCreate()が何度も呼び出されるときに永続化されたロケールにロケールを設定することです。すべてのアクティビティでこれを行う必要がないように、これを行うより良い方法はありますか?.

基本的に私が欲しいのは-私がHomeActivityのいくつかのロケールに変更/設定したら、設定の変更に関係なく、アプリ内のすべてのアクティビティがそのロケール自体を使用するようにします...それ以外のロケールに変更されるまではロケールを変更するオプションを提供するアプリのHomeActivity。

21
Xavier DSouza

この回答で述べた解決策は一般的なケースで機能しますが、私は自分の設定画面に追加することに気づきました:

 <activity Android:name="com.example.UserPreferences"
     Android:screenOrientation="landscape"
     Android:configChanges="orientation|keyboardHidden|screenSize">
 </activity>

これは、アプリケーションが横長モードで設定画面が縦長モードのときに、ロケールを変更してアプリケーションに戻ると問題が発生する可能性があるためです。両方を横向きモードに設定すると、これが発生しなくなります。

一般的な解決策

アプリケーションレベルでロケールを変更して、その効果がどこにでもあるようにする必要があります。

public class MyApplication extends Application
{
  @Override
  public void onCreate()
  {
    updateLanguage(this);
    super.onCreate();
  }

  public static void updateLanguage(Context ctx)
  {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
    String lang = prefs.getString("locale_override", "");
    updateLanguage(ctx, lang);
  }

  public static void updateLanguage(Context ctx, String lang)
  {
    Configuration cfg = new Configuration();
    if (!TextUtils.isEmpty(lang))
      cfg.locale = new Locale(lang);
    else
      cfg.locale = Locale.getDefault();

    ctx.getResources().updateConfiguration(cfg, null);
  }
}

次に、マニフェストに次のように記述する必要があります。

<application Android:name="com.example.MyApplication" ...>
  ...
</application>
26
Mikaël Mayer