Android 2.2 改动语言时的Bug

Android 2.2 更改语言时的Bug

现象:Setting -> Language&Locale 设置后中文后,大部分应用程序及相关点都变为中文,但Launcher中所有项该是英文还是英文,Reboot后变为中亠。原因是Launcher中没有 做相应语言变更处理,做如下修改,添加消息注册函数,重新加载AllApps项!

enginer@root # git diff
src/com/android/launcher2/Launcher.java
    patch | blob | history
src/com/android/launcher2/LauncherModel.java
    patch | blob | history
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 84ee599..551a43e 100644 (file)
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -75,7 +75,8 @@
             android:stateNotNeeded="true"
             android:theme="@style/Theme"
             android:screenOrientation="nosensor"
-             android:windowSoftInputMode="stateUnspecified|adjustPan">
+            android:windowSoftInputMode="stateUnspecified|adjustPan"
+            android:configChanges="locale">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.HOME" />

diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 6bd915a..e333bc5 100644 (file)
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -2303,4 +2303,14 @@ public final class Launcher extends Activity
         mAllAppsGrid.dumpState();
         Log.d(TAG, "END launcher2 dump state");
     }
+
+    // Force reload all apps list when locale changes
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        checkForLocaleChange();
+        mModel.setAllAppsLoaded(false); // Set force load all apps list;
+        mModel.startLoader(this, true); // Reload apps list
+    }
+
}
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 17f7573..4915466 100644 (file)
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -86,6 +86,11 @@ public class LauncherModel extends BroadcastReceiver {
     private Bitmap mDefaultIcon;
+    public void setAllAppsLoaded(boolean load)
+    {
+        mAllAppsLoaded = load;
+    }
+
     public interface Callbacks {
         public int getCurrentWorkspaceScreen();
         public void startBinding();

 

1.6 calendar 里,当系统语言改变时, calendar widget 上的语言并没有随着改变。其实这个 bug android 的很多系统程序里都会出现。只要不是把 string 提取出来的,就都要响应“android.intent.action.CONFIGURATION_CHANGED”,为 UI 做一次 update

这个 bug HTC magic 上同样会出现。

 

1. 6 SDK 里,“android.intent.action.CONFIGURATION_CHANGED”本来就是有 bug 的。网上居然没人讨论过这个问题。我们都知道,可以写一个 broadcastReceiver 来接受各种各样的 Notification, 但是,假如你的 broadcastReceiver intentfilter 里允许了接收CONFIGURATION_CHANGED,那好,你的这个 AP 里面就不能再接收其它的通告,要不然,在开机的时候会出现错误提示:你的程序没响应!

不仅如此,假如我接收了 ACTION_CONFIGURATION_CHANGED ,但是我还想知道,这到底是由语言改变引起的呢?还是屏幕旋转了?会不是在 extra 里给出信息?

我追了一下源码,在ActivityManagerService.java,有方法updateConfigurationLocked,这里是系统发送通告的地方:

 

 

view source
print ?
1 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
2 broadcastIntentLocked( null , null , intent, null , null , 0 , null , null ,
3          null , false , false , MY_PID, Process.SYSTEM_UID);

 

是的,我无法知道是怎样的设置改变。 

 

以上的讨论仅限于 1.6 ,这一切在 2.2 SDK 里不存在了!( 1.6 2.2 之间的 SDK 就没考证啦)

同时,在 2.2 里新加了一个通告: ACTION_ CONFIGURATION_CHANGED , 可以通过这个监听到系统语言改变。我也追了一下 2.2 的源码,在老地方:  

view source
print ?
01 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
02 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
03          | Intent.FLAG_RECEIVER_REPLACE_PENDING);
04 broadcastIntentLocked( null , null , intent, null , null , 0 , null , null ,
05          null , false , false , MY_PID, Process.SYSTEM_UID);
06 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0 ) {
07      broadcastIntentLocked( null , null ,
08              new Intent(Intent.ACTION_LOCALE_CHANGED),
09              null , null , 0 , null , null ,
10              null , false , false , MY_PID, Process.SYSTEM_UID);
11 }

 

froyo 里,当系统语言改变时,会发出两个系统通告,分别是 CONFIGURATION_CHANGED ACTION_LOCALE_CHANGED。

 

还的明确一点变动: 2.2 的ACTION_CONFIGURATION_CHANGED只能通过 r egisterReceiver ()才会被接收, manifest 里写进去的作废了。

 

总结:

如何监听系统语言改变?如果是在activity,直接可以用onConfigurationChanged();如果是旧的SDK,只能接收CONFIGURATION_CHANGED,并且这个通告很不好用!在2.2里,ACTION_LOCALE_CHANGED is enough!

1 楼 烧伤的火柴 2012-03-05  
这代码好乱啊?我感觉缺点内容