Autore Topic: Forzare lingua da codice  (Letto 1077 volte)

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Forzare lingua da codice
« il: 14 Gennaio 2015, 19:02:52 CET »
0
E' una cosa che non si fa, mi rendo conto..

Ho una applicazione con N lingue. Una è la lingua di default, inglese.. poi ho le traduzioni nelle cartelle values-XX, una per ogni lingua.

Mettiamo che arrivi un utente italiano, col telefono italiano e così via. Il sistema mi va a prendere il set di stringhe corretto.

Ecco io voglio poter dire da codice: no, tu devi comportarti come se la tua lingua fosse YY invece di XX. Non a prescindere, perché basterebbe eliminare la cartella IT.. voglio che l'utente possa selezionare la sua lingua o l'inglese.

Esiste un modo per farlo?


Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 594
  • Respect: +132
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:Forzare lingua da codice
« Risposta #1 il: 14 Gennaio 2015, 22:06:52 CET »
+2
Devi impostare la lingua al caricamento di ogni Activity:

Codice (Java): [Seleziona]
    Resources res = context.getResources();
    DisplayMetrics dm = res.getDisplayMetrics();
    android.content.res.Configuration conf = res.getConfiguration();
    conf.locale = new Locale(language_code.toLowerCase());
    res.updateConfiguration(conf, dm);

Fonte: localization - Change language programatically in Android - Stack Overflow
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Forzare lingua da codice
« Risposta #2 il: 15 Gennaio 2015, 17:51:23 CET »
0
Undead, dici che non si fa... in realtà questa cosa l'ho vista in più di un App, ed anzi, qualche utente in qualche commento ha chiesto di farla anche a me.

Essendo la maggior parte delle mie traduzioni fatte con Google, magari qualcuno preferisce usare l'inglese :)


Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Forzare lingua da codice
« Risposta #3 il: 15 Gennaio 2015, 20:16:33 CET »
0
Grazie ohmnibus!

Certe app sono più belle in inglese secondo me. Però se non traduci qualcuno si lamenta. Allora meglio dare l'opportunità di scelta.  :-)

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Forzare lingua da codice
« Risposta #4 il: 16 Gennaio 2015, 10:41:14 CET »
0
Guarda, giusto oggi mi è arrivata una richiesta di tradurre l'App in "catalano". :)

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Forzare lingua da codice
« Risposta #5 il: 19 Gennaio 2015, 15:31:34 CET »
+2
Aggiungo che la procedura è più "stabile" se si aggiunge Locale.setDefault passandogli il Locale costruito.

Codice (Java): [Seleziona]
    Resources res = context.getResources();
    DisplayMetrics dm = res.getDisplayMetrics();
    android.content.res.Configuration conf = res.getConfiguration();
    conf.locale = new Locale(language_code.toLowerCase());
    Locale.setDefault(conf.locale);
    res.updateConfiguration(conf, dm);

 :-)

Offline Friz02

  • Utente junior
  • **
  • Post: 104
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    s3 neo Samsung
  • Sistema operativo:
    windows 7
Re:Forzare lingua da codice
« Risposta #6 il: 25 Gennaio 2015, 17:40:02 CET »
0
Salve a tutti,
sto facendo una cosa simile, tramite uno spinner scelgo la lingua che poi verrà impostata per l'utilizzo dell'app.
Il codice suggerito
Codice (Java): [Seleziona]
Resources res = context.getResources();
    DisplayMetrics dm = res.getDisplayMetrics();
    android.content.res.Configuration conf = res.getConfiguration();
    conf.locale = new Locale(language_code.toLowerCase());
    Locale.setDefault(conf.locale);
    res.updateConfiguration(conf, dm);
è perfetto, però, per vedere  in ogni layout la nuova lingua impostata, è necessario che l'onCreate di ogni activity venga richiamato (solo così verranno caricate le nuove impostazioni), ma se le activity sono già state aperte prima di settare la lingua, allora il metodo onCreate non verrà più chiamato e non verranno caricate le nuove impostazioni. Questo è quello che ho constatato io nella mia app. Pertanto, almeno nel mio caso, sarebbe sufficiente che all'uscita di ogni activity con il tasto back, l'activity stessa fosse "distrutta" ; in tal modo, quando rientrerò nell'activity, verrà chiamato nuovamente l'onCreate e le nuove impostazioni saranno correttamente recepite. Ma come si gestisce il tasto "back" in tal senso?.


Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Forzare lingua da codice
« Risposta #7 il: 26 Gennaio 2015, 12:20:01 CET »
0
Se hai come target API >=11 puoi provare con il metodo recreate() dell'activity. Recreate fa quello che dice.. chiude e riapre l'activity.  :-)

Offline Friz02

  • Utente junior
  • **
  • Post: 104
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    s3 neo Samsung
  • Sistema operativo:
    windows 7
Re:Forzare lingua da codice
« Risposta #8 il: 26 Gennaio 2015, 15:35:34 CET »
0
Si fa quello che dice...io invece utilizzavo un metodo che terminava e richiamava l'activity:
Codice (Java): [Seleziona]
public void restart(){
    Intent newActivity = new Intent(MainActivitySetting.this, MainActivitySetting.class);
    finish();
    startActivity(newActivity);
}
...sicuramente meglio il tuo.
Però c'è qualcosa che non va, mi spiego: queste istruzioni (il mio metodo o quello suggerito recreate()) sono inserite dentro un onItemSelected di uno spinner; quando accedo all'activity che contiene lo spinner cioè MainActivitySetting.java, se nel codice è inserito il metodo recreate() parte un'iterazione infinita, cioè  l'activity viene riavviata infinite volte. Se invece del metodo recreate() metto restart() è tutto ok....premetto che e il codice del resto del programma non è cambiato.
Immagino che qualcuno dirà, è ovvio che succeda questo perchè all'apertura di un'activity con uno spinner, vengono sempre eseguite le istruzioni relative all'item che andrà ad occupare il primo posto dello spinner (quello che viene visualizzato) e nel mio caso troverà recreate() o restart() che daranno vita ad un ciclo infinito ....(spero di essermi spiegato); per questo motivo ho modificato lo spinner in modo tale che all'apertura dell'activity il primo item dello spinner sia occupato da una stringa alla quale non è associato alcun comando, in modo tale da non far partire restart() o recreate() ....e questo funzionava perfettamente con il codice iniziale (cioè con restart()), con il nuovo metodo suggerito, invece, non funziona più. La cosa è strana, le due situazioni sono analoghe, quindi perchè in un modo funziona e nell'altro no?.....magari posto parte del codice:
Codice (Java): [Seleziona]
public class MainActivitySetting extends ActionBarActivity {

      //imposto la variabile da inserie nel primo item dello spinner
      String setlingua=Locale.getDefault().toString();
      String lingua=setlingua.equals("it_IT") ? "IT" : Locale.getDefault().toString().toUpperCase();

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getActionBar().setDisplayHomeAsUpEnabled(true);
        setContentView(R.layout.activity_main_setting);

        final List<String> arrayLingue = new ArrayList<String>();
        arrayLingue.add("IT");
        arrayLingue.add("EN");
        arrayLingue.add(lingua);

        final Spinner spinner = (Spinner) findViewById(R.id.spinner);

        ArrayAdapter lingueAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, arrayLingue);
        spinner.setAdapter(lingueAdapter);

        //setto lo spinner con la sigla della lingua impostata, ma senza conferirgli alcuna istruzione....
        spinner.setSelection(2);

        AdapterView.OnItemSelectedListener listnerSpinner = new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                int lingua = spinner.getSelectedItemPosition();
                //imposto "vuota" la sigla che appare nel primo item dello spinner per evitare che venga ripetuta nello spinner quando lo apro
                arrayLingue.set(2, " ");
                Log.d("lingue", Integer.toString(lingua));

                switch (lingua){
                    case 0:
                        Configuration configIT = new Configuration();
                        Context contextIT=getBaseContext();
                        Resources resIT = contextIT.getResources();
                        DisplayMetrics dmIT = resIT.getDisplayMetrics();
                        Locale localeIT = new Locale("it");
                        Locale.setDefault(localeIT);
                        configIT.locale = localeIT;
                        resIT.updateConfiguration(configIT,dmIT);
                        //recreate(); ......se metto questo metodo itera all'infinito
                        restart();
                        break;
                    case 1:
                        Configuration configEN = new Configuration();
                        Context contextEN=getBaseContext();
                        Resources resEN = contextEN.getResources();
                        DisplayMetrics dmEN = resEN.getDisplayMetrics();
                        Locale localeEN = new Locale("en");
                        Locale.setDefault(localeEN);
                        configEN.locale = localeEN;
                        resEN.updateConfiguration(configEN,dmEN);
                        //recreate(); ......se metto questo metodo itera all'infinito
                        restart();
                        break;                    
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {

            }
        };

        spinner.setOnItemSelectedListener(listnerSpinner);
...........resto del codice omesso.....
 

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Forzare lingua da codice
« Risposta #9 il: 28 Gennaio 2015, 16:00:14 CET »
0
Scusa mi era sfuggito il tuo post.

Beh io ho il settaggio su uno spinner e funziona, il trucco è non usare la onitemselected ma intercettare il click.
In pratica io leggo l'impostazione all'avvio, seleziono l'item che mi interessa e dopo metto un onclicklistener (onitemclicklistener? non ho il codice sottomano) che al click (non alla selezione) mi esegue il restart.

In questo modo non ho problemi di riavvio fino a quando fisicamente non clicco qualcosa nello spinner.  :-)

Offline Friz02

  • Utente junior
  • **
  • Post: 104
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    s3 neo Samsung
  • Sistema operativo:
    windows 7
Re:Forzare lingua da codice
« Risposta #10 il: 28 Gennaio 2015, 20:05:06 CET »
0
Ho provato a mettere onitemclicklistener ma l'app va in crash.
Il problema dev'essere qua da qualche parte:
Codice (Java): [Seleziona]
AdapterView.OnItemClickListener listnerSpinner = new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                int ling = spinner.getSelectedItemPosition();                        
                switch (ling){
                    case 0:
                        Configuration configIT = new Configuration();
                        Context contextIT=getBaseContext();
                        Resources resIT = contextIT.getResources();
                        DisplayMetrics dmIT = resIT.getDisplayMetrics();
                        Locale localeIT = new Locale("it");
                        Locale.setDefault(localeIT);
                        configIT.locale = localeIT;
                        resIT.updateConfiguration(configIT,dmIT);
                        //recreate();
                        //restart();
                        setlingua=Locale.getDefault().toString();
                        //dbLingua();
                        //callActivity();
                        break;
                    case 1:
                        Configuration configEN = new Configuration();
                        Context contextEN=getBaseContext();
                        Resources resEN = contextEN.getResources();
                        DisplayMetrics dmEN = resEN.getDisplayMetrics();
                        Locale localeEN = new Locale("en");
                        Locale.setDefault(localeEN);
                        configEN.locale = localeEN;
                        resEN.updateConfiguration(configEN,dmEN);
                        //recreate();
                        //restart();
                        setlingua=Locale.getDefault().toString();
                        //dbLingua();
                        callActivity();
                       break;
                }
            }
        };
        spinner.setOnItemClickListener(listnerSpinner);

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Forzare lingua da codice
« Risposta #11 il: 28 Gennaio 2015, 20:36:23 CET »
0
Il logcat cosa dice?

Offline Friz02

  • Utente junior
  • **
  • Post: 104
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    s3 neo Samsung
  • Sistema operativo:
    windows 7
Re:Forzare lingua da codice
« Risposta #12 il: 29 Gennaio 2015, 18:49:13 CET »
0
01-29 18:43:30.183  24314-24314/com.corso_android.myapp2.helloworld E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.corso_android.myapp2.helloworld, PID: 24314
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.corso_android.myapp2.helloworld/com.corso_android.myapp2.helloworld.MainActivitySetting}: java.lang.RuntimeException: setOnItemClickListener cannot be used with a spinner.
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2328)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2386)
            at android.app.ActivityThread.access$900(ActivityThread.java:169)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1277)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5476)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.RuntimeException: setOnItemClickListener cannot be used with a spinner.
            at android.widget.Spinner.setOnItemClickListener(Spinner.java:482)
            at com.corso_android.myapp2.helloworld.MainActivitySetting.onCreate(MainActivitySetting.java:120)
            at android.app.Activity.performCreate(Activity.java:5451)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2292)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2386)
            at android.app.ActivityThread.access$900(ActivityThread.java:169)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1277)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5476)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
            at dalvik.system.NativeStart.main(Native Method)

La riga in giallo corrisponde a questa riga di codice
Codice (Java): [Seleziona]
spinner.setOnItemClickListener(listnerSpinner);Forse non ho ben capito come hai fatto tu....mi manca qualcosa.

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Forzare lingua da codice
« Risposta #13 il: 29 Gennaio 2015, 19:00:56 CET »
0
Mmmm allora... prova così:

PRIMA metti la selezione con setSelection
DOPO imposti setOnItemSelectedListener

all'interno del selection listener invece di chiedere quale è la selezione verifica che sia cambiata:

Codice (Java): [Seleziona]
  spinner.setAdapter(lingueAdapter);

        //setto lo spinner con la sigla della lingua impostata, ma senza conferirgli alcuna istruzione....
        spinner.setSelection(2);
m_OldSelection = 2;
        AdapterView.OnItemSelectedListener listnerSpinner = new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                int lingua = i;
if( i == m_OldSelection)
return;
m_OldSelection = i;
                Log.d("lingue", Integer.toString(lingua));


Offline Friz02

  • Utente junior
  • **
  • Post: 104
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    s3 neo Samsung
  • Sistema operativo:
    windows 7
Re:Forzare lingua da codice
« Risposta #14 il: 29 Gennaio 2015, 19:41:04 CET »
0
Niente da fare, non va in crash ma ripete recreate() all'infinito, è come se non riuscisse a settare l'item nella posizione che voglio io ma ritorna sempre dove c'è recreate().
Dopo aver scelto ad esempio IT nello spinner, viene settata la lingua e poi esegue recreate(),prima però viene settato un valore con
Codice (Java): [Seleziona]
spinner.setSelection(2);che sarà attribuito all'item dopo il riavvio dell'activity. Quando riparte l'activity nello spinner non dovrebbe succedere niente perchè la selezione dovrebbe essere su l'item che non esegue alcuna istruzione, invece, e non capisco perchè, la selezione dello spinner va sempre sull'item 0 cioè dove c'è "IT" e riesegue recreate() e così all'infinito.