2017-10-31 9 views

答えて

0

私は2つのペアを取得するためのリソースを使用し、その後、文字列のnameとレイアウトXMLでのTextViewインスタンスの+idに一致するようにした可能性が唯一の回避策:

/** 
    * 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(); 
    } 

スワップが部分的に基づいていますスワッピングテキストフィールドのGunhan Sancar's methodにあります。

これは動作しますが、かなりハックです。

最終的にはGoogleの手書き入力言語をプログラムで変更する必要があり、そのためJuuso's ADB Change Languageアプリが手軽に利用できるようになりました。

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(); 
     } 
    } 

アプリにCHANGE_CONFIGURATIONを付与することを忘れないでください:

は参考のため、ここではJuusoのアプローチを使用して機能です。

これはAndroid 7.1.1でテストされていますが、特定のビルド条件ではgetConfigurationが見つからないため、Android 8.0(および潜在的に上向き)で失敗する可能性があることに注意してください。

このメソッドは、変更したい言語のLocaleオブジェクトのArrayListが、上に と期待しています。

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")); 

デバイスにも言語がインストールされていることを確認してください。

改善提案が他にもある場合は、回答を更新して幸いです。

1

できません。 A TextViewは、setText(int resid)を呼び出すと、StringリソースのIDを格納しません。このオーバーロードされたメソッドはすべて、リソースからStringを取得し、setText(CharSequence text)メソッドを呼び出します。

+0

うん、それは楽しいことではありません。欲しいものはありますか? –

+0

あなたのユースケースは何か分かりませんが、自分のコードでTextViewに最後に設定したStringリソースを追跡することができます。 – Sander

+0

私はアプリケーションの内部だけで、完全なOS設定を変更せずにロケール文字列を交換しています。 'setContentView'がアクティビティに対して呼び出された後はありますか? –

関連する問題