web-dev-qa-db-ja.com

Androidデバイスのロケールを取得

Androidプログラムのインストール時に、デバイスのロケールを確認します。

String deviceLocale=Locale.getDefault().getLanguage();

DeviceLocaleがサポートされている言語(英語、フランス語、ドイツ語)内にある場合、ロケールは変更しません。

しかし、たとえば、デバイスの言語をサポートしていない場合、たとえばスペイン語だと言ってください。
ほとんどの人が英語を部分的に理解できるため、現在のロケールを英語に設定します。

Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
pContext.getResources().updateConfiguration(config, null);

しかし、その後、他の方法で、次のようにデバイスのロケールを確認すると:

String deviceLocale=Locale.getDefault().getLanguage();

「英語」として結果が得られます。ただし、デバイスのロケールはスペイン語です。

GetLanguage()は現在のアプリのロケールを提供しますか?
デバイスのロケールを取得するにはどうすればよいですか?

編集:アプリの最初の実行では、デバイスのロケールを保存するオプションです。しかし、保存後にユーザーがデバイスのロケールを変更すると、デバイスの新しいロケールを知ることができません。アプリのインストール時に保存したロケールしか知ることができません。

38
trante

これを行うには、リフレクションを使用したり、システムプロパティを解析したりするよりもはるかに簡単でクリーンな方法があります。

アプリでデフォルトのロケールを設定すると、システムのデフォルトのロケールにアクセスできなくなります。アプリで設定したデフォルトのロケールは、アプリのライフサイクル中のみ有効です。 Locale.setDefault(Locale)で設定したものは、プロセスが終了すると消えます。アプリを再起動すると、システムのデフォルトのロケールを再び読み取ることができます。

したがって、アプリの起動時にシステムのデフォルトロケールを取得するだけで、アプリが実行されている限りそれを記憶し、ユーザーがAndroid設定で言語を変更することに決めた場合は更新します。この情報はアプリが実行されている間のみ必要なので、アプリ内のどこからでもアクセスできる静的変数に保存するだけです。

そして、これが私たちのやり方です:

public class MyApplication extends Application {

    public static String sDefSystemLanguage;

    @Override
    public void onCreate() {
        super.onCreate();

        sDefSystemLanguage = Locale.getDefault().getLanguage();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        sDefSystemLanguage = newConfig.locale.getLanguage();
    }

}

アプリケーションを使用して(マニフェストで定義することを忘れないでください)、アプリの起動時にデフォルトのロケールを取得し(onCreate())、ユーザーがAndroid = settings(onConfigurationChanged(Configuration))。それだけです。setDefaultコールを使用する前にシステムのデフォルト言語を知る必要がある場合は、sDefSystemLanguageが答えを提供します。

あなたのコードで私が見つけた1つの問題があります。新しいロケールを設定するとき、次のことを行います。

Configuration config = new Configuration();
config.locale = locale;
pContext.getResources().updateConfiguration(config, null);

これを行うと、保持する可能性があるすべての構成情報が上書きされます。例えば。 Configuration.fontScaleは、アクセシビリティ設定の大きなテキストを反映しています。言語を設定し、他のすべての構成を失うと、アプリは大きなテキスト設定を反映しなくなります。つまり、テキストは本来よりも小さくなります(ユーザーが大きなテキスト設定を有効にしている場合)。正しい方法は次のとおりです。

Resources res = pContext.getResources();
Configuration config = res.getConfiguration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    configuration.setLocale(Locale.CANADA);
}
else {
    configuration.locale = Locale.CANADA;
}
res.updateConfiguration(config, null);

したがって、新しいConfigurationオブジェクトを作成する代わりに、現在のオブジェクトを更新するだけです。

69

グローバルロケールにアクセスするには-

defaultLocale = Resources.getSystem().getConfiguration().locale;

http://developer.Android.com/reference/Android/content/res/Resources.html#getSystem() をご覧ください-

システムリソースのみへのアクセスを提供するグローバルな共有リソースオブジェクトを返します(アプリケーションリソースはなし)

更新:コメントで指摘されているように、「ロケール」フィールドは非推奨であり、代わりに getLocales() を使用する必要があります。

defaultLocale = Resources.getSystem().getConfiguration().getLocales().get(0);

42
Aniket Awati

アプリを設計する最良の方法は、values /の下にデフォルトのlangを使用することです。values-XX/の下に追加のlangsを追加できます。このように、言語がサポートされていない場合Androidデフォルトにフォールバックするので、英語。OSがあなたに代わって作業を行います:)ただし、ロケールを変更すると、最後の設定なので、その情報をどこかに保存する必要があります。

7
greywolf82

変更中に、Application language programatically like

Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
pContext.getResources().updateConfiguration(config, null);

そして

But after that, in other methods, when I check device's locale like this:

String deviceLocale=Locale.getDefault().getLanguage();
I get result as "English". But device's locale is Spanish.

その代わりに、以下のコードを使用してdevice's Local

try {
    Process exec = Runtime.getRuntime().exec(new String[]{"getprop", "persist.sys.language"});
    String locale = new BufferedReader(new InputStreamReader(exec.getInputStream())).readLine();
    exec.destroy();
    Log.e("", "Device locale: "+locale);
} catch (IOException e) {
    e.printStackTrace();
}

出力:Spanishこれをチェック

まさにあなたが探しているこれを願っています。

3
Amit Gupta

@ user2944616 による回答は政治的に正しいものの、提起された実際の質問に対する回答を与えるものではありません。

したがって、ユーザーがシステムロケールを設定することを本当に知っていなければならなかった場合、リフレクションを使用します(ATMのより良いオプションはわかりません)。

private String getSystemPropertyValue(String name) {
    try {
        Class<?> systemProperties = Class.forName("Android.os.SystemProperties");
        try {
            Method get = systemProperties.getMethod("get", String.class, String.class);
            if (get == null) {
                return "Failure!?";
            }
            try {
                return (String)get.invoke(systemProperties, name, "");
            } catch (IllegalAccessException e) {
                return "IllegalAccessException";
            } catch (IllegalArgumentException e) {
                return "IllegalArgumentException";
            } catch (InvocationTargetException e) {
                return "InvocationTargetException";
            }
        } catch (NoSuchMethodException e) {
            return "SystemProperties.get(String key, String def) method is not found";
        }
    } catch (ClassNotFoundException e) {
        return "SystemProperties class is not found";
    }
}

指定されたデバイスロケールがスペイン語(米国)/Español(Estados Unidos)に設定されている文字列

<string name="system_locale">System locale: <xliff:g id="profile_name">%1$s</xliff:g>&#95;<xliff:g id="device_name">%2$s</xliff:g></string>

そしてこのコード

private static final String SYS_COUNTRY = "persist.sys.country";
private static final String SYS_LANG = "persist.sys.language";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView tv = (TextView)findViewById(R.id.locale);
    tv.setText(getString(R.string.system_locale, getSystemPropertyValue(SYS_LANG),
            getSystemPropertyValue(SYS_COUNTRY)));
}

次の画面を生成します。

System locale screenshot

必要に応じて、上記を使用してLocaleインスタンスを簡単に構築することもできます。

Locale locale = new Locale(getSystemPropertyValue(SYS_LANG),
        getSystemPropertyValue(SYS_COUNTRY));
Log.d(TAG, "Language: " + locale.getLanguage());
Log.d(TAG, "Country: " + locale.getCountry());

ログ出力:

D/GetSystemLocale(5697): Language: es
D/GetSystemLocale(5697): Country: US

お役に立てれば。

1
ozbek

言語の代わりにString deviceLocale= Locale.getDefault().getDisplayLanguage();を使用して言語を表示する必要があります

String deviceLocale=Locale.getDefault().getLanguage();

上記で解決できない場合は、この回答をご覧ください。 クリック可能

1
k0sh