1. 程式人生 > >Android 系統語言切換監聽和設定

Android 系統語言切換監聽和設定

最近專案上產品經理提了個需求,要求關閉語言國際化,不管手機系統設定那個國家的語言,都要顯示漢語,好吧,既然有需求,那就做吧。但是專案中已經有英文的配置了,且是作為預設String提供的,這麼多翻譯好的文字,直接刪除掉替換成中文為預設String又感覺棄之可惜。故網上Google下解決方案。就開始往下看吧。

一、程式碼中動態設定應用顯示語言(手動控制使用values-zh-rCN下字串)

這個方法是通過改變Resource中的配置來實現的,程式碼如下:
public static void initAppLanguage(Context context) {
    if (context == null
) { return; } Locale.setDefault(Locale.CHINA); Configuration config = context.getResources().getConfiguration(); config.locale = Locale.CHINA; context.getResources().updateConfiguration(config , context.getResources().getDisplayMetrics()); }
上面方法我們可以在MyApplication中設定也可以在Activity的基類中呼叫 但是上面的方法還是不足以讓我們的應用一直顯示指定的某種語言文字的。因為我們的應用在執行階段中,系統語言發生了改變後,我們的應用還是會被切換語言的,如果沒有指定語言,就顯示預設的語言。這肯定不是我們要看到的結果,那就到了標題中提到的語言切換監聽了。

二、語言切換監聽

1.廣播方式監聽

我們可以通過監聽系統廣播來實現(廣播靜態註冊動態註冊都可以,動態註冊把握好註冊時機)
/**
 * ClassName: LocaleChangeReceiver
 * Description:(這裡用一句話描述這個類的作用)
 * Created by chensf on 2016-8-17 16:47.
 */
public class LocaleChangeReceiver extends BroadcastReceiver {
    @Override
public void onReceive(Context context, Intent intent) {
        Log.v
(TAG, "mReceiver onReceive intent.getAction(): "+intent.getAction()); if(intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) { Log.e("LocaleChangeReceiver","Language change"); SystemUtil.initAppLanguage(context); } } }

這裡我們通過監聽Intent.ACTION_LOCALE_CHANGED廣播,在系統語言切換後我們會得到通知,然後就愛幹嘛幹嘛了,這裡我通過呼叫上面 提到的設定語言方法,將語言設定為初始設定語言。網上大多都是採用這種方式來監聽語言切換,其實還有另外一種方式。

2.重寫onConfigurationChanged方法

一些系統設定變化後都會回撥這個方法,所以我們可以從這裡下手。 那在哪裡重寫這個方法呢,這個方法大家是不是感覺很熟悉,監聽橫豎屏切換是不是有用到過呢,提到橫豎屏切換,這裡順便講點題外話 在橫豎屏切換的時候,我們為了避免Activity重新呼叫onCreate,一般都會重寫這個方法,但是,橫豎屏切換後Activity沒有呼叫onConfigurationChanged而是依舊呼叫了 onCreate,因為我們Activity預設是不回撥onConfigurationChanged的,開啟方法就是
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
在AndroidManifest中Activity標籤下新增android:configChanges="orientation|screenSize,orientation是橫豎屏切換的配置,至於為什麼要同時加上screenSize,是因為Android3.0之後,如果只設置orientation沒有設定screenSize,onConfigurationChanged依舊不會被回撥。 那回歸正題,大家通過上面的例子知道了這個onConfigurationChanged要在Activity中重寫,配置跟上面一致,引數改變了而已
<activity
android:name=".MainActivity"
android:configChanges="locale|layoutDirection">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

android:configChanges="locale|layoutDirection 這裡同樣存在一個問題,4.2之前的系統只需要設定locale,4.2+就得多設定layoutDirection這個配置,不然onConfigurationChanged依舊不會被回撥。
上面的在Activity重寫onConfigurationChanged方式明視訊記憶體在一個缺點,如果只需要改變某個Activity的語言設定,上面的方式可以適用,如果要改變整個應用的語言設定,上面的方式就很low,要每個Activity都重寫onConfigurationChanged,雖然可以在Activity基類中重寫,但是,AndroidManifest中還是得每個Activity標籤下都去設定 android:configChanges="locale|layoutDirection, 說了這麼多就不繞彎子了,我們可以在Application中重寫onConfigurationChanged
@Override
public void onConfigurationChanged(Configuration newConfig) {
    Log.e("MyApplication","onConfigurationChanged");
    super.onConfigurationChanged(newConfig);
SystemUtil.initAppLanguage(getBaseContext());
}
這個配置是整個應用設定的,在這裡設定語言,能夠改變整個應用的語言設定,而且這種方式,無需在AndroidManifest中增加配置,我測試過,在Application中重寫onConfigurationChanged,Activity的onConfigurationChanged 依舊能夠回撥到,但是其中有沒有造成什麼影響,我這裡暫時沒有發現。如果有采用我提供的這種方式實現語言切換監聽的,遇到問題可以告訴我,我們一起探討下。 好了,本文到此結束。