É possível alterar o idioma de um aplicativo de forma programática enquanto ainda usa os recursos do Android?
Caso contrário, é possível solicitar um recurso em um idioma específico?
Gostaria de permitir que o usuário altere o idioma do aplicativo.
É possível alterar o idioma de um aplicativo de forma programática enquanto ainda usa os recursos do Android?
Caso contrário, é possível solicitar um recurso em um idioma específico?
Gostaria de permitir que o usuário altere o idioma do aplicativo.
Respostas:
É possível. Você pode definir o código do idioma. No entanto, eu não recomendaria isso. Nós tentamos isso nos estágios iniciais, basicamente combatendo o sistema.
Temos o mesmo requisito para alterar o idioma, mas decidimos concluir que a interface do usuário deve ser a mesma do telefone. Ele estava funcionando através da configuração da localidade, mas era muito complicado. E você deve defini-lo toda vez que inserir atividade (cada atividade) da minha experiência. aqui está um código se você ainda precisar disso (novamente, eu não recomendo isso)
Resources res = context.getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.setLocale(new Locale(language_code.toLowerCase())); // API 17+ only.
// Use conf.locale = new Locale(...) if targeting lower versions
res.updateConfiguration(conf, dm);
Se você tiver um conteúdo específico do idioma - poderá alterar essa base na configuração.
atualização em 26 de março de 2020
public static void setLocale(Activitycontext) {
Locale locale;
Sessions session = new Sessions(context);
//Log.e("Lan",session.getLanguage());
locale = new Locale(langCode);
Configuration config = new Configuration(context.getResources().getConfiguration());
Locale.setDefault(locale);
config.setLocale(locale);
context.getBaseContext().getResources().updateConfiguration(config,
context.getBaseContext().getResources().getDisplayMetrics());
}
Context.createConfigurationContext(), que pode ser usado para agrupar o contexto padrão com a configuração específica do código do idioma e, em seguida, chamar getResourcesisso sem a necessidade de atualizar a configuração nos próprios objetos de recursos.
conf.setLayoutDirection(locale), você pode substituir conf.locale = new Locale(...))por conf.setLocale(new Locale(...)). Ele ligará internamente setLayoutDirection.
Este código realmente funciona:
fa = persa, en = inglês
Digite seu código de idioma na languageToLoadvariável:
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
public class Main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String languageToLoad = "fa"; // your language
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
this.setContentView(R.layout.main);
}
}
Resources.updateConfigurationmétodo. Recuei o código para torná-lo mais claro.
Eu estava procurando uma maneira de alterar a linguagem do sistema programaticamente. Embora eu compreenda perfeitamente que um aplicativo normal nunca deve fazer isso e, em vez disso:
havia uma necessidade de realmente alterar o idioma do sistema programaticamente.
Esta é uma API não documentada e, portanto, não deve ser usada para aplicativos de mercado / usuário final!
Enfim, aqui está a solução que eu encontrei:
Locale locale = new Locale(targetLocaleAsString);
Class amnClass = Class.forName("android.app.ActivityManagerNative");
Object amn = null;
Configuration config = null;
// amn = ActivityManagerNative.getDefault();
Method methodGetDefault = amnClass.getMethod("getDefault");
methodGetDefault.setAccessible(true);
amn = methodGetDefault.invoke(amnClass);
// config = amn.getConfiguration();
Method methodGetConfiguration = amnClass.getMethod("getConfiguration");
methodGetConfiguration.setAccessible(true);
config = (Configuration) methodGetConfiguration.invoke(amn);
// config.userSetLocale = true;
Class configClass = config.getClass();
Field f = configClass.getField("userSetLocale");
f.setBoolean(config, true);
// set the locale to the new value
config.locale = locale;
// amn.updateConfiguration(config);
Method methodUpdateConfiguration = amnClass.getMethod("updateConfiguration", Configuration.class);
methodUpdateConfiguration.setAccessible(true);
methodUpdateConfiguration.invoke(amn, config);
android.permission.CHANGE_CONFIGURATIONsó pode ser concedido pelo aplicativo assinado com a tecla Perform.
Se você deseja manter o idioma alterado em todo o seu aplicativo, precisa fazer duas coisas.
Primeiro, crie uma Atividade base e faça com que todas as suas atividades se estendam a partir disso:
public class BaseActivity extends AppCompatActivity {
private Locale mCurrentLocale;
@Override
protected void onStart() {
super.onStart();
mCurrentLocale = getResources().getConfiguration().locale;
}
@Override
protected void onRestart() {
super.onRestart();
Locale locale = getLocale(this);
if (!locale.equals(mCurrentLocale)) {
mCurrentLocale = locale;
recreate();
}
}
public static Locale getLocale(Context context){
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
String lang = sharedPreferences.getString("language", "en");
switch (lang) {
case "English":
lang = "en";
break;
case "Spanish":
lang = "es";
break;
}
return new Locale(lang);
}
}
Observe que eu salvo o novo idioma em uma sharedPreference.
Segundo, crie uma extensão de Aplicativo como esta:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
setLocale();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setLocale();
}
private void setLocale() {
final Resources resources = getResources();
final Configuration configuration = resources.getConfiguration();
final Locale locale = getLocale(this);
if (!configuration.locale.equals(locale)) {
configuration.setLocale(locale);
resources.updateConfiguration(configuration, null);
}
}
}
Observe que getLocale () é o mesmo que acima.
Isso é tudo! Espero que isso possa ajudar alguém.
Applicationé e como usar. mobomo.com/2011/05/how-to-use-application-object-of-android
configuration.locateestá obsoleto, setLocale requer API 17+ e updateConfiguration está obsoleto.
De acordo com este artigo . Você precisará fazer o download LocaleHelper.javamencionado nesse artigo.
MyApplicationclasse que se estendeApplication attachBaseContext()para atualizar o idioma.Registre esta classe no manifesto.
public class MyApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
}
}
<application
android:name="com.package.MyApplication"
.../>Crie BaseActivitye substitua onAttach()para atualizar o idioma. Necessário para Android 6+
public class BaseActivity extends Activity {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base));
}
}Faça com que todas as atividades em seu aplicativo se estendam BaseActivity.
public class LocaleHelper {
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
String lang = getPersistedData(context, Locale.getDefault().getLanguage());
return setLocale(context, lang);
}
public static Context onAttach(Context context, String defaultLanguage) {
String lang = getPersistedData(context, defaultLanguage);
return setLocale(context, lang);
}
public static String getLanguage(Context context) {
return getPersistedData(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
persist(context, language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
}
return updateResourcesLegacy(context, language);
}
private static String getPersistedData(Context context, String defaultLanguage) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}
private static void persist(Context context, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.apply();
}
@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLayoutDirection(locale);
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}Apenas adicionando uma peça extra que me tropeçou.
Enquanto as outras respostas funcionam bem com "de", por exemplo
String lang = "de";
Locale locale = new Locale(lang);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
O exemplo acima não funcionará, por exemplo, com o "fr_BE"código do idioma, para que ele use a values-fr-rBEpasta ou similar.
Precisa da seguinte pequena alteração para trabalhar com "fr_BE"
String lang = "fr";
//create a string for country
String country = "BE";
//use constructor with country
Locale locale = new Locale(lang, country);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
activity.recreate()
android.content.res.Configuration conf = res.getConfiguration();vez de criar uma nova Configurationinstância? Existe algum benefício em usar um novo?
Eu mudei para o idioma alemão, pois meu aplicativo é iniciado.
Aqui está o meu código correto. Alguém quer usar esse mesmo para mim .. (Como mudar o idioma no android programaticamente)
meu código:
Configuration config ; // variable declaration in globally
// this part is given inside onCreate Method starting and before setContentView()
public void onCreate(Bundle icic)
{
super.onCreate(icic);
config = new Configuration(getResources().getConfiguration());
config.locale = Locale.GERMAN ;
getResources().updateConfiguration(config,getResources().getDisplayMetrics());
setContentView(R.layout.newdesign);
}
Eu sei que é tarde para responder, mas eu encontrei este artigo aqui . O que explica muito bem todo o processo e fornece um código bem estruturado.
Classe auxiliar de localidade:
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.preference.PreferenceManager;
import java.util.Locale;
/**
* This class is used to change your application locale and persist this change for the next time
* that your app is going to be used.
* <p/>
* You can also change the locale of your application on the fly by using the setLocale method.
* <p/>
* Created by gunhansancar on 07/10/15.
*/
public class LocaleHelper {
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
String lang = getPersistedData(context, Locale.getDefault().getLanguage());
return setLocale(context, lang);
}
public static Context onAttach(Context context, String defaultLanguage) {
String lang = getPersistedData(context, defaultLanguage);
return setLocale(context, lang);
}
public static String getLanguage(Context context) {
return getPersistedData(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
persist(context, language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
}
return updateResourcesLegacy(context, language);
}
private static String getPersistedData(Context context, String defaultLanguage) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}
private static void persist(Context context, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.apply();
}
@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLayoutDirection(locale);
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}
Você precisa substituir o attachBaseContext e chamar LocaleHelper.onAttach () para inicializar as configurações de localidade no seu aplicativo.
import android.app.Application;
import android.content.Context;
import com.gunhansancar.changelanguageexample.helper.LocaleHelper;
public class MainApplication extends Application {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(LocaleHelper.onAttach(base, "en"));
}
}
Tudo o que você precisa fazer é adicionar
LocaleHelper.onCreate(this, "en");
onde quer que você queira alterar a localidade.
createConfigurationContext, que foi útil
Criar uma classe Estende Applicatione cria um método estático. Em seguida, você pode chamar esse método em todas as atividades anteriores setContentView().
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
}
public static void setLocaleFa (Context context){
Locale locale = new Locale("fa");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
context.getApplicationContext().getResources().updateConfiguration(config, null);
}
public static void setLocaleEn (Context context){
Locale locale = new Locale("en_US");
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
context.getApplicationContext().getResources().updateConfiguration(config, null);
}
}
Uso em atividades:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyApp.setLocaleFa(MainActivity.this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
}
Alterar idioma programaticamente no Android
Resposta antiga
Isso inclui suporte a RTL / LTR:
public static void changeLocale(Context context, Locale locale) {
Configuration conf = context.getResources().getConfiguration();
conf.locale = locale;
Locale.setDefault(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
conf.setLayoutDirection(conf.locale);
}
context.getResources().updateConfiguration(conf, context.getResources().getDisplayMetrics());
}
A única solução que funciona totalmente para mim é uma combinação do código de Alex Volovoy com o mecanismo de reinicialização do aplicativo:
void restartApplication() {
Intent i = new Intent(MainTabActivity.context, MagicAppRestart.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainTabActivity.context.startActivity(i);
}
/** This activity shows nothing; instead, it restarts the android process */
public class MagicAppRestart extends Activity {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
finish();
}
protected void onResume() {
super.onResume();
startActivityForResult(new Intent(this, MainTabActivity.class), 0);
}
}
activity.recreate()
Eu estava enfrentando o mesmo problema. No GitHub, encontrei a biblioteca Android-LocalizationActivity .
Essa biblioteca facilita muito a alteração do idioma do seu aplicativo em tempo de execução, como você pode ver no exemplo de código abaixo. Um projeto de exemplo, incluindo o código de exemplo abaixo e mais informações, pode ser encontrado na página do github.
O LocalizationActivity estende o AppCompatActivity, para que você também possa usá-lo quando estiver usando fragmentos.
public class MainActivity extends LocalizationActivity implements View.OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple);
findViewById(R.id.btn_th).setOnClickListener(this);
findViewById(R.id.btn_en).setOnClickListener(this);
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.btn_en) {
setLanguage("en");
} else if (id == R.id.btn_th) {
setLanguage("th");
}
}
}
Hora de uma atualização devida.
Primeiro, a lista preterida com a API na qual foi preterida:
configuration.locale (API 17)updateConfiguration(configuration, displaymetrics) (API 17)A coisa que nenhuma pergunta respondida recentemente acertou é o uso do novo método .
createConfigurationContext é o novo método para updateConfiguration.
Alguns o usaram autônomo assim:
Configuration overrideConfiguration = ctx.getResources().getConfiguration();
Locale locale = new Locale("en_US");
overrideConfiguration.setLocale(locale);
createConfigurationContext(overrideConfiguration);
... mas isso não funciona. Por quê? O método retorna um contexto, que é usado para manipular traduções Strings.xml e outros recursos localizados (imagens, layouts, qualquer que seja).
O uso adequado é assim:
Configuration overrideConfiguration = ctx.getResources().getConfiguration();
Locale locale = new Locale("en_US");
overrideConfiguration.setLocale(locale);
//the configuration can be used for other stuff as well
Context context = createConfigurationContext(overrideConfiguration);
Resources resources = context.getResources();
Se você acabou de copiar e colar isso no seu IDE, poderá receber um aviso de que a API exige que você direcione a API 17 ou superior. Isso pode ser contornado, colocando-o em um método e adicionando a anotação@TargetApi(17)
Mas espere. E as APIs mais antigas?
Você precisa criar outro método usando updateConfiguration sem a anotação TargetApi.
Resources res = YourApplication.getInstance().getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale("th");
res.updateConfiguration(conf, dm);
Você não precisa retornar um contexto aqui.
Agora, gerenciar isso pode ser difícil. Na API 17+, você precisa do contexto criado (ou dos recursos do contexto criado) para obter os recursos apropriados com base na localização. Como você lida com isso?
Bem, é assim que eu faço:
/**
* Full locale list: /programming/7973023/what-is-the-list-of-supported-languages-locales-on-android
* @param lang language code (e.g. en_US)
* @return the context
* PLEASE READ: This method can be changed for usage outside an Activity. Simply add a COntext to the arguments
*/
public Context setLanguage(String lang/*, Context c*/){
Context c = AndroidLauncher.this;//remove if the context argument is passed. This is a utility line, can be removed totally by replacing calls to c with the activity (if argument Context isn't passed)
int API = Build.VERSION.SDK_INT;
if(API >= 17){
return setLanguage17(lang, c);
}else{
return setLanguageLegacy(lang, c);
}
}
/**
* Set language for API 17
* @param lang
* @param c
* @return
*/
@TargetApi(17)
public Context setLanguage17(String lang, Context c){
Configuration overrideConfiguration = c.getResources().getConfiguration();
Locale locale = new Locale(lang);
Locale.setDefault(locale);
overrideConfiguration.setLocale(locale);
//the configuration can be used for other stuff as well
Context context = createConfigurationContext(overrideConfiguration);//"local variable is redundant" if the below line is uncommented, it is needed
//Resources resources = context.getResources();//If you want to pass the resources instead of a Context, uncomment this line and put it somewhere useful
return context;
}
public Context setLanguageLegacy(String lang, Context c){
Resources res = c.getResources();
// Change locale settings in the app.
DisplayMetrics dm = res.getDisplayMetrics();//Utility line
android.content.res.Configuration conf = res.getConfiguration();
conf.locale = new Locale(lang);//setLocale requires API 17+ - just like createConfigurationContext
Locale.setDefault(conf.locale);
res.updateConfiguration(conf, dm);
//Using this method you don't need to modify the Context itself. Setting it at the start of the app is enough. As you
//target both API's though, you want to return the context as you have no clue what is called. Now you can use the Context
//supplied for both things
return c;
}
Esse código funciona com um método que faz chamadas para o método apropriado com base em qual API. Isso é algo que fiz com muitas chamadas obsoletas diferentes (incluindo Html.fromHtml). Você tem um método que aceita os argumentos necessários, que o divide em um dos dois (ou três ou mais) métodos e retorna o resultado apropriado com base no nível da API. É flexível, pois você não precisa verificar várias vezes, o método "entry" faz isso por você. O método de entrada aqui ésetLanguage
Você precisa usar o contexto retornado ao obter recursos. Por quê? Vi outras respostas aqui que usam createConfigurationContext e não usam o contexto que ele retorna. Para que funcione dessa maneira, é necessário chamar updateConfiguration. Qual foi preterido. Use o contexto retornado pelo método para obter recursos.
Exemplo de uso :
Construtor ou em algum lugar semelhante:
ctx = getLanguage(lang);//lang is loaded or generated. How you get the String lang is not something this answer handles (nor will handle in the future)
E então, onde você quiser obter os recursos que você faz:
String fromResources = ctx.getString(R.string.helloworld);
Usar qualquer outro contexto (em teoria) irá quebrar isso.
AFAIK, você ainda precisa usar um contexto de atividade para mostrar diálogos ou brindes. para isso, você pode usar uma instância de uma atividade (se estiver fora)
E, finalmente, use recreate()a atividade para atualizar o conteúdo. Atalho para não precisar criar uma intenção de atualização.
Se você escrever
android:configChanges="locale"
Em todas as atividades (no arquivo de manifesto), não é necessário defini-lo toda vez que você entra Activity.
configChangesusado para um hack para preservar o estado da Atividade nas rotações / etc.
Locale locale = new Locale("en");
Locale.setDefault(locale);
Configuration config = context.getResources().getConfiguration();
config.setLocale(locale);
context.createConfigurationContext(config);
Atualização Importante:
context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
Observe que, no SDK> = 21, você precisa chamar 'Resources.updateConfiguration ()' , caso contrário, os recursos não serão atualizados.
Context ctx = createConfigurationContext(args);e obter recursos de que
/*change language at Run-time*/
//use method like that:
//setLocale("en");
public void setLocale(String lang) {
myLocale = new Locale(lang);
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
Intent refresh = new Intent(this, AndroidLocalize.class);
startActivity(refresh);
}
activity.recreate()
Locale configurationdeve ser definido em cada um activityantes de definir o conteúdo -this.setContentView(R.layout.main);
activity.recreate()
Primeiro, crie multi string.xml para diferentes idiomas; então use este bloco de código no onCreate()método:
super.onCreate(savedInstanceState);
String languageToLoad = "fr"; // change your language here
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config,
getBaseContext().getResources().getDisplayMetrics());
this.setContentView(R.layout.main);
Aqui está um código que funciona para mim:
public class MainActivity extends AppCompatActivity {
public static String storeLang;
@Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences shp = PreferenceManager.getDefaultSharedPreferences(this);
storeLang = shp.getString(getString(R.string.key_lang), "");
// Create a new Locale object
Locale locale = new Locale(storeLang);
// Create a new configuration object
Configuration config = new Configuration();
// Set the locale of the new configuration
config.locale = locale;
// Update the configuration of the Accplication context
getResources().updateConfiguration(
config,
getResources().getDisplayMetrics()
);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Fonte: aqui
Nenhuma das soluções listadas aqui me ajudou.
O idioma não foi ativado no android> = 7.0 se AppCompatDelegate.setDefaultNightMode (AppCompatDelegate.MODE_NIGHT_YES)
Este LocaleUtils funciona bem: https://gist.github.com/GigigoGreenLabs/7d555c762ba2d3a810fe
LocaleUtils
public class LocaleUtils {
public static final String LAN_SPANISH = "es";
public static final String LAN_PORTUGUESE = "pt";
public static final String LAN_ENGLISH = "en";
private static Locale sLocale;
public static void setLocale(Locale locale) {
sLocale = locale;
if(sLocale != null) {
Locale.setDefault(sLocale);
}
}
public static void updateConfig(ContextThemeWrapper wrapper) {
if(sLocale != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
Configuration configuration = new Configuration();
configuration.setLocale(sLocale);
wrapper.applyOverrideConfiguration(configuration);
}
}
public static void updateConfig(Application app, Configuration configuration) {
if(sLocale != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
//Wrapping the configuration to avoid Activity endless loop
Configuration config = new Configuration(configuration);
config.locale = sLocale;
Resources res = app.getBaseContext().getResources();
res.updateConfiguration(config, res.getDisplayMetrics());
}
}
}
Adicionado este código ao aplicativo
public class App extends Application {
public void onCreate(){
super.onCreate();
LocaleUtils.setLocale(new Locale("iw"));
LocaleUtils.updateConfig(this, getBaseContext().getResources().getConfiguration());
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
LocaleUtils.updateConfig(this, newConfig);
}
}
Código em Atividade
public class BaseActivity extends AppCompatActivity {
public BaseActivity() {
LocaleUtils.updateConfig(this);
}
}
A resposta de Alex Volovoy só funciona para mim se estiver no método onCreate da atividade.
A resposta que funciona em todos os métodos está em outro segmento
Alterar idioma programaticamente no Android
Aqui está a adaptação do código
Resources standardResources = getBaseContext().getResources();
AssetManager assets = standardResources.getAssets();
DisplayMetrics metrics = standardResources.getDisplayMetrics();
Configuration config = new Configuration(standardResources.getConfiguration());
config.locale = new Locale(languageToLoad);
Resources defaultResources = new Resources(assets, metrics, config);
Espero que ajude.
Observe que esta solução usando updateConfiguration não funcionará mais com o lançamento do Android M em algumas semanas. A nova maneira de fazer isso agora está usando o applyOverrideConfigurationmétodo da ContextThemeWrapper
consulte API doc
Você pode encontrar minha solução completa aqui desde que eu enfrentei o problema: https://stackoverflow.com/a/31787201/2776572
Existem algumas etapas que você deve implementar
Primeiro, você precisa alterar o local da sua configuração
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = new Locale(language);
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
Segundo, se você deseja que suas alterações se apliquem diretamente ao layout visível, você pode atualizar as visualizações diretamente ou simplesmente chamar activity.recreate () para reiniciar a atividade atual.
E também é necessário persistir nas alterações, pois após o usuário fechar o aplicativo, você perderia a alteração do idioma.
Expliquei uma solução mais detalhada no meu post no blog Alterar idioma programaticamente no Android
Basicamente, basta chamar LocaleHelper.onCreate () na sua classe de aplicativo e, se você quiser alterar a localidade rapidamente, pode chamar LocaleHelper.setLocale ()
Isso está funcionando quando pressiono o botão para alterar o idioma do meu TextView. (Strings.xml na pasta values-de)
String languageToLoad = "de"; // your language
Configuration config = getBaseContext().getResources().getConfiguration();
Locale locale = new Locale(languageToLoad);
Locale.setDefault(locale);
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
recreate();
Adicionar classe LocaleHelper
public class LocaleHelper{
private static final String SELECTED_LANGUAGE = "Locale.Helper.Selected.Language";
public static Context onAttach(Context context) {
String lang = getPersistedData(context, Locale.getDefault().getLanguage());
return setLocale(context, lang);
}
public static Context onAttach(Context context, String defaultLanguage) {
String lang = getPersistedData(context, defaultLanguage);
return setLocale(context, lang);
}
public static String getLanguage(Context context) {
return getPersistedData(context, Locale.getDefault().getLanguage());
}
public static Context setLocale(Context context, String language) {
persist(context, language);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return updateResources(context, language);
}
return updateResourcesLegacy(context, language);
}
private static String getPersistedData(Context context, String defaultLanguage) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(SELECTED_LANGUAGE, defaultLanguage);
}
private static void persist(Context context, String language) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(SELECTED_LANGUAGE, language);
editor.apply();
}
@TargetApi(Build.VERSION_CODES.N)
private static Context updateResources(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
configuration.setLayoutDirection(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private static Context updateResourcesLegacy(Context context, String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
configuration.setLayoutDirection(locale);
}
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}
}
Em atividade ou fragmento
Context context = LocaleHelper.setLocale(this, App.getSharedPre().getLanguage());
Resource resources = context.getResources();
Agora SetText em cada texto
TextView tv = findViewById(R.id.tv);
tv.setText(resources.getString(R.string.tv));
semelhante à versão aceita respondida, mas 2017, e adicionada reinicialização (sem reiniciar, às vezes a próxima atividade ainda renderiza o inglês):
// Inside some activity...
private void changeDisplayLanguage(String langCode) {
// Step 1. Change the locale in the app's configuration
Resources res = getResources();
android.content.res.Configuration conf = res.getConfiguration();
conf.setLocale(currentLocale);
createConfigurationContext(conf);
// Step 2. IMPORTANT! you must restart the app to make sure it works 100%
restart();
}
private void restart() {
PackageManager packageManager = getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(getPackageName());
ComponentName componentName = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName);
mainIntent.putExtra("app_restarting", true);
PrefUtils.putBoolean("app_restarting", true);
startActivity(mainIntent);
System.exit(0);
}
activity.recreate()3) o contexto voltou Eu acho que tem que ser usado para obter os recursos
Primeiro você cria valores de nome de diretório - "Nome do idioma" como hindi do que escrever "oi" e a mesma cópia de nome de arquivo de string neste diretório e alterar o valor não altera o parâmetro após definir o código abaixo em sua ação como o botão etc ...
Locale myLocale = new Locale("hi");
Resources res = getResources();
DisplayMetrics dm = res.getDisplayMetrics();
Configuration conf = res.getConfiguration();
conf.locale = myLocale;
res.updateConfiguration(conf, dm);
Intent refresh = new Intent(Home.this, Home.class);
startActivity(refresh);
finish();
conf.localeestá obsoleto
private void setLanguage(String language) {
Locale locale = new Locale(language);
Locale.setDefault(locale);
Configuration config = new Configuration();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
config.setLocale(locale);
} else {
config.locale = locale;
}
getResources().updateConfiguration(config,
getResources().getDisplayMetrics());
}
No exemplo, definimos o idioma inglês:
Configuration config = GetBaseContext().getResources().getConfiguration();
Locale locale = new Locale("en");
Locale.setDefault(locale);
config.locale = locale;
GetBaseContext().getResources().updateConfiguration(config,
GetBaseContext().getResources().getDisplayMetrics());
Lembre-se de que isso funciona apenas se o idioma for encontrado no sistema do dispositivo também, não apenas no aplicativo
Para suporte árabe / RTL
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(updateBaseContextLocale(newBase));
}
public Context updateBaseContextLocale(Context context) {
String language = SharedPreference.getInstance().getValue(context, "lan");//it return "en", "ar" like this
if (language == null || language.isEmpty()) {
//when first time enter into app (get the device language and set it
language = Locale.getDefault().getLanguage();
if (language.equals("ar")) {
SharedPreference.getInstance().save(mContext, "lan", "ar");
}
}
Locale locale = new Locale(language);
Locale.setDefault(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
updateResourcesLocale(context, locale);
return updateResourcesLocaleLegacy(context, locale);
}
return updateResourcesLocaleLegacy(context, locale);
}
@TargetApi(Build.VERSION_CODES.N)
private Context updateResourcesLocale(Context context, Locale locale) {
Configuration configuration = context.getResources().getConfiguration();
configuration.setLocale(locale);
return context.createConfigurationContext(configuration);
}
@SuppressWarnings("deprecation")
private Context updateResourcesLocaleLegacy(Context context, Locale locale) {
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
configuration.locale = locale;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
return context;
}