Pull to refresh

Смена языка приложения в настройках

Reading time 3 min
Views 122K
В системе Android очень удобная для использования система локализации, достаточно создать папку и в ней файл со строками. Но в приложение сложно встроить все возможные языки, и не плохо бы предоставить пользователю выбор языка, отличного от стандартного.
Приведу пример такой ситуации:
В приложении есть 2 языка стандартный английский и русский. Это приложение решил установить украинец, у которого аппарат на украинском языке, но так же он хорошо знает русский, а английский не очень. Но вот Андроид, обнаружив, что в приложении нет украинского языка, запустит приложение со стандартным языком, который в нашей ситуации — английский, а для того, что бы приложение запустить на русском, необходимо менять язык системы, что не очень хорошо.
Вот для этой и многих подобных ситуаций есть решение, в настройки вывести пункт выбора языка, который включает автоматический выбор языка, английский, русский, etc. (смотря какие требуются).


Приступим к написанию.
1. Необходимо создать класс Application и определить его в манифесте в соответственном разделе application в параметре android:name="".
например:
<application android:icon="@drawable/icon" android:label="@string/app_name" android:name="MyApplication" android:enabled="true">
</application>

(хотя у некоторых этот класс уже может быть)
2. Создать настройку с выбором языка, для этого в файле настроек добавим:
<ListPreference
   android:key="lang"
   android:title="@string/LangTitle"
   android:summary="@string/LangSummary"
   android:entries="@array/entries_lang"
   android:entryValues="@array/entryvalues_lang"
   android:dialogTitle="@string/LangDialogTitle" />


3. В файл со строками добавим нужные строки:
<string name="LangTitle">Язык</string>
<string name="LangDialogTitle">Выберите язык:</string>
<string name="LangSummary">Язык приложения.\nНеобходимо перезапустить приложение для принятия изменений.</string>

4. А в файл с массивами 2 текстовых массива:
<string-array name="entries_lang">
  <item>Язык аппарата</item>
  <item>Английский</item>
  <item>Русский</item> 
</string-array> 
<string-array name="entryvalues_lang">
  <item>default</item> 
  <item>en</item>
  <item>ru</item> 
</string-array>

5. В созданном классе в методе onCreate объявим строковую переменную «lang», чтение переменной из настроек, изменение конфигурации приложение, и метод, который вызывается при изменении конфигурации, в котором еще раз её меняем (без повторной смены язык не хотел меняться во всем приложении). В итоге получим следующий класс:
public class MyApplication extends Application {
	private SharedPreferences preferences;
	private Locale locale;
	private String lang;
	
	@Override
	public void onCreate() {
		preferences = PreferenceManager.getDefaultSharedPreferences(this);
		lang = preferences.getString("lang", "default");	
			if (lang.equals("default")) {lang=getResources().getConfiguration().locale.getCountry();}
			locale = new Locale(lang);
			Locale.setDefault(locale);
			Configuration config = new Configuration();
			config.locale = locale;
			getBaseContext().getResources().updateConfiguration(config, null);
	}
	
	@Override
    public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        locale = new Locale(lang);
		Locale.setDefault(locale);
		Configuration config = new Configuration();
		config.locale = locale;
		getBaseContext().getResources().updateConfiguration(config, null);     
    }	
}

6. После для того, что бы язык применился, необходимо полностью перезапустить приложение (finish(); тут не поможет, так как перезапускает только активити), для этого использую команду System.exit();
(В примере сделал пункт перезапуска по будильнику).
7. Для того, что бы в не возникло проблем в сети советуют в манифесте к каждому активити, в котором используется локализация:
 android:configChanges="locale"

А так же, что бы приложение отображалось правильно определить поддерживаемые размеры экранов:
<supports-screens android:anyDensity="true" android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" />


Вот таким нехитрым образом можно упростить пользователю жизнь.



Плюсы этого подхода:
-Пользователю дается выбор языка.
Минусы:
-Необходимость указывать в массивах добавляемые языки.

Как обычно пример приложения с исходным кодом:
1. Исходный код примера;
2. Пример приложения (apk).

P.S. Каким еще способом можно закрыть приложение полностью (включая Application), кроме System.exit()?
Tags:
Hubs:
+28
Comments 42
Comments Comments 42

Articles