2017-10-31 2 views

Antwort

0

Die einzige Lösung war ich konnte die +id der Textview-Instanzen im Layout von XML mit dem name der Zeichenfolge übereinstimmen, dann Ressourcen verwenden die beiden zu bekommen paaren:

/** 
    * finds a string id matching a text view id name and returns the value 
    * @param textView - text view 
    * @param context - the context 
    * @param locale - the locale string 
    * @return String - resource string if found, empty string otherwise 
    */ 
    public static String getTextViewStringFromResources(TextView textView,Context context,String locale){ 
     String result = ""; 
     final int textViewID = textView.getId(); 

     if(textViewID <= 0){ 
      Log.e(TAG,"invalid id for textView " + textView + " text = " + textView.getText()); 
      result = textView.getText().toString(); 
      return result; 
     } 
     //get resources (re-usable) 
     final Resources resources = getLocalizedResources(context,locale); 
     // get textViews id 
     final String entryName = resources.getResourceEntryName(textView.getId()); 
     // get the string id !! must match the textview id !! 
     final int stringID = resources.getIdentifier(entryName,"string",context.getPackageName()); 
     //return string value for string id found by textview id 
     try{ 
      result = resources.getString(stringID); 
     }catch (Resources.NotFoundException e){ 
      Log.e(TAG,"couldn't find a string id for " + entryName); 
      Log.e(TAG,e.getMessage()); 
     } 
     return result; 
    } 

//!! requires minSDK 17 
    @NonNull 
    public static Resources getLocalizedResources(Context context, String locale) { 
     Locale desiredLocale = new Locale(locale); 
     Configuration conf = context.getResources().getConfiguration(); 
     conf.setLocale(desiredLocale); 
     Context localizedContext = context.createConfigurationContext(conf); 
     return localizedContext.getResources(); 
    } 

Der Austausch teilweise basiert auf Gunhan Sancar's method von swapping Textfeld.

Dies funktioniert, aber es ist ziemlich ein Hack.

Schließlich musste ich auch die Google Handwriting Input-Sprache programmgesteuert ändern und für diese Juuso's ADB Change Language App kam in super praktisch.

Als Referenz ist hier eine Funktion Juuso Ansatz mit:

final String TAG = "ChangeLanguage" 
//change language utils "kindly borrowed" from net.sanapeli.adbchangelanguage: brilliant little app! 

    /** 
    * updates a Configuration with a list of Locales 
    * @param configuration - a configuration to updated 
    * @param arrayList - an ArrayList of Locale instances 
    * @return the updated configuration 
    */ 
    @TargetApi(24) 
    public static Configuration addLocalesToConfiguration(Configuration configuration, ArrayList<Locale> arrayList) { 
     configuration.setLocales(new LocaleList((Locale[]) arrayList.toArray(new Locale[arrayList.size()]))); 
     return configuration; 
    } 

    /** 
    * Change the system language 
    * @param lanaguageList - a list of Locale instances to change to 
    */ 
    public static void changeLanguages(ArrayList<Locale> lanaguageList){ 
     try { 
      Class cls = Class.forName("android.app.ActivityManagerNative"); 
      Method method = cls.getMethod("getDefault", new Class[0]); 
      method.setAccessible(true); 
      Object invoke = method.invoke(cls, new Object[0]); 
      method = cls.getMethod("getConfiguration", new Class[0]); 
      method.setAccessible(true); 
      Configuration configuration = (Configuration) method.invoke(invoke, new Object[0]); 
      configuration.getClass().getField("userSetLocale").setBoolean(configuration, true); 
      if (VERSION.SDK_INT >= 24) { 
       configuration = addLocalesToConfiguration(configuration, lanaguageList); 
      } else { 
       configuration.locale = (Locale) lanaguageList.get(0); 
      } 
      Method method2 = cls.getMethod("updateConfiguration", new Class[]{Configuration.class}); 
      method2.setAccessible(true); 
      method2.invoke(invoke, new Object[]{configuration}); 
      Log.d(TAG,"locale updated to" + lanaguageList.get(0).toString()); 
     } catch (Exception e) { 
      Log.e(TAG,"error changing locale (double check you're granted permissions to the app first: pm grant com.hirschandmann.googlearts android.permission.CHANGE_CONFIGURATION)"); 
      e.printStackTrace(); 
     } 
    } 

Denken Sie daran, CHANGE_CONFIGURATION zu Ihrer App zu gewähren.

Dies wurde mit Android 7.1.1 getestet, aber es wird unter Android 8.0 (und möglicherweise aufwärts) als getConfiguration wird unter bestimmten Build-Bedingungen nicht gefunden (die API ist anders) nicht gefunden.

Die Methode erwartet eine ArrayList von Locale-Objekten mit der Sprache, die Sie oben ändern möchten: z.

ArrayList<Locale> fr = new ArrayList<Locale>(); 
fr.add(new Locale("fr")); 
fr.add(new Locale("en")); 

ArrayList<Locale> en = new ArrayList<Locale>(); 
en.add(new Locale("en")); 
en.add(new Locale("fr")); 

Vergewissern Sie sich, dass die Sprachen auf den Geräten installiert sind.

Wenn Sie andere Verbesserungsvorschläge haben würde ich mehr als glücklich sein, die Antwort

1

Sie können nicht. A TextView speichert die ID der String-Ressourcen nicht, wenn Sie setText(int resid) aufrufen. Bei dieser überladenen Methode wird die Zeichenfolge aus den Ressourcen abgerufen und die Methode setText(CharSequence text) aufgerufen.

+0

Hmmm zu aktualisieren, das ist kein Spaß. Ich wünschte, es gäbe einen Weg –

+0

Ich weiß nicht, was Ihr Anwendungsfall ist, aber ich bin sicher, dass Sie verfolgen können, welche String-Ressource Sie zuletzt auf die TextView in Ihrem eigenen Code eingestellt haben. – Sander

+0

Ich tausche einige Locale-Zeichenfolgen, ohne die Einstellungen für das vollständige Betriebssystem zu ändern, nur intern in meiner App. Gibt es ein 'setContentView' nachdem eine Aktivität aufgerufen wurde? –

Verwandte Themen