2016-04-01 40 views
0

我寫一個Android應用程序,所以從來就得到了我strings.xml照常所有字符串和每個Android的官方文檔中闡明。的Android頭痛的字符串:我如何集中我的應用程序中的所有字符串?

直到這裏一切都很好,但問題來了,當我想在Java「標準」類中使用的字符串;即,讓我們說這個字符串中Email.java

public static final String EMAIL_NOT_VALID = "The email address provided is not valid."; 

你可以說我可以把這個字符串上strings.xml做:

getResources().getString(R.string.invalid_email_message) 

這種方法的問題是,我將被迫通過Android的背景下,以我的應用程序中的每一個Java對象,所有的嘲諷的問題,這涉及到當談到測試。

因此,是有可能做到這一點,而沒有經過語境?或者,我需要有兩個文件(strings.xmlxyz.java)具有獨立字符串

從來就一直在尋找了幾個小時的答案,在計算器上這個問題沒有運氣)

在此先感謝。

+1

你可以有它抽象此獨立的,並調用它得到的字符串,留下了它(單身),以提供上下文?然後你也可以讓單例暴露上下文,這樣你就可以爲測試/嘲諷注入它。 – npinti

+0

@ankitaggarwal請仔細閱讀此問題。我說我不想要那個解決方案 –

+0

@npinti聽起來很有趣。你能解釋一下嗎? –

回答

1

你可以嘗試把你的字符串assets文件夾,它需要建立在YourProject/app/src/main/assets內的資產,你可以創建一個名爲即「本土化」的新文件夾,這裏存放您的本地化文件,如strings_en,在該文件中存儲您的所有完成所有這些操作後,JSON對象"{"key" : "value"}中的字符串將需要創建一個管理所有語言的類。

public class LocalizationManager { 

    private static LocalizationManager mInstance = null; 
    public String currentLanguage = ""; 
    JSONObject currentLanguageObject = new JSONObject(); 
    private AssetManager assetManager = BaseApplication.getInstance().getAssets(); // BaseApplication is just a class that extends Application class 

    private LocalizationManager() { 
    } 

    public static LocalizationManager getInstance() { 
     if (mInstance == null) { 
      mInstance = new LocalizationManager(); 
     } 
     return mInstance; 
    } 

    private boolean assetExists(String path) { 
     boolean bAssetOk = false; 
     try { 
      InputStream stream = assetManager.open(path); 
      stream.close(); 
      bAssetOk = true; 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return bAssetOk; 
    } 

    public String getLocalizedString(String string) { 
     String language = BaseApplication.getInstance().getLanguage(); 
     if (!currentLanguage.equalsIgnoreCase(language)) { 
      if (assetExists("localization/strings_" + language)) { 
       InputStream input; 
       try { 
        input = assetManager.open("localization/strings_" + language); 
        int size = input.available(); 
        byte[] buffer = new byte[size]; 
        input.read(buffer); 
        input.close(); 
        String responseString = new String(buffer); 
        Object json; 
        try { 
         json = new JSONTokener(responseString).nextValue(); 
         if (json instanceof JSONObject) { 
          currentLanguageObject = (JSONObject) json; 
          currentLanguage = language; 
          return currentLanguageObject.optString(string, string); 
         } 
        } catch (JSONException e) { 
         return string; 
        } 
       } catch (IOException e) { 
        return string; 
       } 
      } 
     } else { 
      return currentLanguageObject.optString(string, string); 
     } 
     return string; 
    } 
} 

然後在任何課程,你可以撥打LocalizationManager.getInstance().getLocalizedString("Your string key")。使用這種方法,您需要在應用程序中添加「更改語言」選項,例如在首選項中將值存儲爲en,並且語言將動態更改。這是我如何做的:

public void setLanguage(String language) { 
    mPreferences = getSharedPreferences(LANGUAGE_KEY_FOR_PREFS, MODE_PRIVATE); 
    SharedPreferences.Editor editor = mPreferences.edit(); 
    editor.putString("Language", language); 
    editor.apply(); 
    mListener.onLanguageChanged(); 
} 


public String getLanguage() { 
    mPreferences = getSharedPreferences(LANGUAGE_KEY_FOR_PREFS, MODE_PRIVATE); 
    return mPreferences.getString("Language", "en"); 
} 
+0

感謝哥們!那是我正在尋找的策略! –

+0

不客氣) –

0

您可以使用:

Resources.getSystem().getString(android.R.string.somecommonstuff) 

...到處都在你的應用程序,即使是在靜態常量聲明。不幸的是,它只支持系統資源。

從一個線程的堆棧溢出

+0

這不是因爲我喜歡。該行將返回一個int,而我需要正確的String。同樣,它沒有檢測到strings.xml中的字符串 –

1

,請不要將弦,特別是在信息代碼的類。決不。那麼你不能將它翻譯成其他語言。爲所有內容使用字符串資源,可能除了一些只在調試器中看到的日誌消息。

你可以創建一個像Globals.java類,並把那裏

public static Context appContext; 

和你

Globals.appContext = getApplicationContext(); 

,然後填補了這一靜態的AppStart的(=您的MainActivity的 「的onCreate」)你到處都有一個上下文。 只需確保,當您從後臺返回時,您在MainActivity的onResume事件中刷新上下文。

你會在整個Android API中看到這個「問題」 - SQLiteOpenHelper需要一個上下文... 一切需要一個上下文。這是Android遊戲的一部分。

+0

非常好的回答我的朋友,感謝它。我要去試試看。此外,我打算只顯示來自 Activity.java類的消息;你對這個策略有什麼看法? –

相關問題