2012-11-01 32 views
10

Mamy aplikację na Androida, która działa jako klient dla zdalnego programu na komputerze. Chcielibyśmy dodać funkcję, dzięki której komputer będzie mógł polecić aplikacji na Androida, aby zmieniła ustawienia regionalne w czasie wykonywania, tj. Uruchom aplikację; komunikuj się z komputerem; czasem później komputer powie aplikacji, aby przełączyła się na, powiedzmy, hiszpański lub chiński.Zmienić ustawienia narodowe w czasie wykonywania?

Mamy już skonfigurowane zasoby układu i łańcucha dla ich odpowiednich ustawień narodowych. Nasza aplikacja jest jedyną aplikacją, którą widzi użytkownik, więc nie ma znaczenia, czy reszta urządzenia pozostanie w języku angielskim.

Istnieje inny wątek na ten temat w Change language programmatically in Android, ale wydaje się, że nie dochodzi do wniosku.

Mogę umieścić. . .

Locale locale = new Locale(sTheNewLocale); 
Locale.setDefault(locale); 
Configuration config = new Configuration(); 
config.locale = locale; 
getBaseContext().getResources().updateConfiguration(config, 
     getBaseContext().getResources().getDisplayMetrics()); 

. . . w onCreate() przed setContentView() ale to naprawdę nie pomoże, jeśli chcę zmienić ustawienia regionalne po uruchomieniu mojego ekranu. Czy istnieje sposób na ponowne załadowanie widoku treści po uruchomieniu działania? Czy istnieje więc jakiś praktyczny sposób na niezawodne zmienianie ustawień lokalnych w locie lub czy muszę powiedzieć mojemu szefowi, że nie można tego zrobić, z wyjątkiem ustawienia całego urządzenia na nowe ustawienia regionalne przed uruchomieniem aplikacji?

Odpowiedz

15

Ponieważ API 11 można użyć recreate więc można zrobić z tej metody w swojej działalności:

private void restartInLocale(Locale locale) 
{ 
    Locale.setDefault(locale); 
    Configuration config = new Configuration(); 
    config.locale = locale; 
    Resources resources = getResources(); 
    resources.updateConfiguration(config, resources.getDisplayMetrics()); 
    recreate(); 
} 
+1

Metoda 'updateConfiguration()' jest przestarzała. Oto niezastrzeżone rozwiązanie: http://stackoverflow.com/questions/40221711/android-context-getresources-updateconfiguration-deprecated – wilkas

+0

config.locale jest również amortyzowany –

+0

@ HasanAliKaraca, który jest objęty połączoną odpowiedzią. – weston

3

Możesz rozpocząć nową instancję aktywności i wyjść ze starej. Oto pełny (niesprawdzony) przykład, w jaki sposób można zapisać żądany język i ponownie uruchomić aplikację. Musisz tylko zadzwonić pod numer restartInLanguage w swoim preferowanym języku.

public class YourMainActivity extends Activity { 
    private static final String APP_SHARED_PREFS = "com.example.test"; 
    private SharedPreferences settings; 
    private Editor editor; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     settings=getSharedPreferences(APP_SHARED_PREFS, Activity.MODE_PRIVATE); 
     editor=settings.edit(); 

     Locale locale = new Locale(settings.getString("lang", "default-lang")); 
     Locale.setDefault(locale); 
     Configuration config = new Configuration(); 
     config.locale = locale; 
     getResources().updateConfiguration(config, getResources().getDisplayMetrics()); 

     // your stuff... 
    } 

    public void restartInLanguage(String lang) { 
     editor.putString("lang", lang); 
     editor.commit(); 
     Intent intent = getIntent(); 
     finish(); 
     startActivity(intent); 
    } 

    // ... 
} 
+0

Jeżeli zrobiłbym to z?Program rozpoczyna się w głównym działaniu, więc jak to zmienić ustawienia narodowe głównego ekranu? Czy masz na myśli rozpoczęcie nowej instancji głównego działania od głównego działania, a następnie zabicie się w starej głównej aktywności? (może to być nawet zrobione?) – user316117

+0

Tak, więc to jest ... Umieszczasz powyższy kod w * zmienionym języku obsługi *, który restartuje twoją główną działalność. – rekire

+0

Nadal nie mogę zanalizować odpowiedzi. Czy mówisz, że mogę ponownie uruchomić główną aktywność * z * mojej głównej działalności? Jak mogę to zrobić? – user316117

0

Rozwiązaniem jest użycie setContentView i controlLanguage (można również wywołać tę metodę z globalnej klasy) metody w KAŻDEJ czynności w metodzie onResume po ustawieniu lokalizacji. przykład:

@Override 
    public void onClick(View v) { 
     SharedPreferences.Editor editor; 
     editor = sharedPref.edit(); 
     Configuration config = new Configuration(getBaseContext().getResources().getConfiguration()); 
     String language = ""; 
     switch (v.getId()){ 
      case R.id.turkceButton: 
       editor.putString("language", "tr"); 
       language="tr"; 
       break; 
      case R.id.englishButton: 
       editor.putString("language", "en"); 
       language="en"; 
       break; 
     } 
     Locale locale = new Locale(language); 
     Locale.setDefault(locale); 
     config.locale = locale; 
     getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics()); 
     editor.commit(); 


@Override 
    protected void onResume() { 
     super.onResume(); 
     controlLanguage(getApplicationContext(), getResources()); 
     setContentView(R.layout.main); 
    } 

public void controlLanguage(Context context, Resources res){ 
     SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); 
     String language = sharedPref.getString("language","en"); 
     Locale locale = new Locale(language); 
     Locale.setDefault(locale); 
     res.getConfiguration().locale = locale; 
     res.updateConfiguration(res.getConfiguration(), res.getDisplayMetrics()); 
    } 
1

I połączone @weston i @rekire (zarówno + 1) i extendet do obsługi tego przypadków użycia:

  • ActivityA => ActivityB => SettingsActivity-changeLocale

Po changeLocale w SettingsActivity należy również odtworzyć działania macierzyste ActivityA i ActivityB, aby odzwierciedlić nowe ustawienia narodowe.

Moje rozwiązanie: ActivityA i ActivityB dziedziczą LocalizedActivity który sprawdza w onResume jeśli locale zmieniła i wywołać recreate() razie potrzeby

więc każde działanie, które dziedziczy LocalizedActivity automatycznie obsługuje konkretną zmianę lokalizacji aplikacji.

/** 
* An activity that can change the locale (language) of its content. 
* 
* Inspired by http://stackoverflow.com/questions/13181847/change-the-locale-at-runtime 
* 
* Created by k3b on 07.01.2016. 
*/ 
public class LocalizedActivity extends Activity { 
    /** if myLocale != Locale.Default : activity must be recreated in on resume */ 
    private Locale myLocale = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     fixLocale(this); 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     // Locale has changed by other Activity ? 
     if ((myLocale != null) && (myLocale.getLanguage() != Locale.getDefault().getLanguage())) { 
      myLocale = null; 
      recreate(); 
     } 
    } 

    /** 
    * Set Activity-s locale to SharedPreferences-setting. 
    * Must be called before onCreate 
    * @param context 
    */ 
    public static void fixLocale(Context context) 
    { 
     final SharedPreferences prefs = PreferenceManager 
       .getDefaultSharedPreferences(context); 
     String language = prefs.getString(Global.PREF_KEY_USER_LOCALE, ""); 
     Locale locale = Global.systemLocale; // in case that setting=="use android-locale" 
     if ((language != null) && (!language.isEmpty())) { 
      locale = new Locale(language); // overwrite "use android-locale" 
     } 

     if (locale != null) { 
      Locale.setDefault(locale); 
      Configuration config = new Configuration(); 
      config.locale = locale; 
      Resources resources = context.getResources(); 
      resources.updateConfiguration(config, resources.getDisplayMetrics()); 
      // recreate(); 

      if (context instanceof LocalizedActivity) { 
       ((LocalizedActivity) context).myLocale = locale; 
      } 
     } 
    } 
} 

Oto źródło LocalizedActivity.java i SettingsActivity.java które są wykorzystywane w mój A Photo Manager project

Powiązane problemy