aidl实现Android系统语言切换

来源:互联网 发布:单片机开发板哪个好 编辑:程序博客网 时间:2024/06/03 18:31

参考和引用:ytmfdw博文

简要分析

One step点击系统Settings直接看logcat

I/ActivityManager( 458): Config changes=2004 {1.0 ?mcc?mnc ja_JP ldltr sw800dp w800dp h1207dp 160dpi xlrg port finger -keyb/v/h -nav/h s.9}
I/ContactsProvider( 680): Locale has changed from zh_TW to ja_JP
I/ContactsDatabaseHelper( 680): Switching to locale ja_JP (ICU v51.1.0.1)
I/ContactsDatabaseHelper( 680): Locale change completed in 490ms
I/ContactsDatabaseHelper( 680): Switching to locale ja_JP (ICU v51.1.0.1)

Two_stepSettings_apk

packages/apps/Settings/com/android/settings/LocalePicker.Java

发现其中onLocaleSelected(final Locale locale)方法,去调用了fromwork层下的/frameworks/base/core/Java/com/android/internal/app/LocalePicker下的updateLocale()方法

public static void updateLocale(Locale locale) {    try {            IActivityManager am = ActivityManagerNative.getDefault();            Configuration config = am.getConfiguration();            config.setLocale(locale);            am.updateConfiguration(config);            BackupManager.dataChanged("com.android.providers.settings");     } catch (RemoteException e) {     } }

实现步骤

One_step添加一个公共方法

/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

         public void updateLanguage(Configuration values) {                 if (mHeadless)                     return;                 int changes = 0;                 boolean kept = true;                 if (values != null) {                     Configuration newConfig = new Configuration(mConfiguration);                     changes = newConfig.updateFrom(values);                     if (changes != 0) {                         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {                             Slog.i(TAG, "Updating configuration to: " + values);                         }                         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);                         if (values.locale != null) {                             saveLocaleLocked(values.locale,                                     !values.locale.equals(mConfiguration.locale),                                     values.userSetLocale);                             Slog.i(TAG, "update language::" + values.toString());                        }                     }                 }           }

Two_step:修改代理

/frameworks/base/core/java/android/app/ActivityManagerNative.java

updateLanguage方法

           public void updateLanguage(Configuration values) throws RemoteException           {                 Parcel data = Parcel.obtain();                 Parcel reply = Parcel.obtain();                 data.writeInterfaceToken(IActivityManager.descriptor);                 values.writeToParcel(data, 0);                 mRemote.transact(UPDATE_LANGUAGE_TRANSACTION, data, reply, 0);                 reply.readException();                 data.recycle();                 reply.recycle();             }

添加调用接口在方法体中,添加一分支:

public boolean onTransact(int code, Parcel data, Parcel reply, int flags)throws RemoteException {switch (code) {…………}
case UPDATE_LANGUAGE_TRANSACTION: {data.enforceInterface(IActivityManager.descriptor);Configuration config = Configuration.CREATOR.createFromParcel(data);updateLanguage(config);reply.writeNoException();return true;}

Three_step声明常量

updateLanguage(Configuration values) 方法

/frameworks/base/core/java/android/app/IActivityManager.java
public void updateLanguage(Configuration values) throws RemoteException;int UPDATE_LANGUAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+161;//(161视情况而定,不能重复)

Four_stepservice中添加方法

import com.android.internal.app.LocalePicker; import android.os.RemoteException;import java.util.Locale;import android.content.res.Configuration;import android.app.IActivityManager;import android.app.backup.BackupManager;import android.app.ActivityManagerNative;......  Locale locale;  public void updateLanguage(String arg,String arg1) {// switch(arg)// { case 1:// locale = new Locale("zh","CN");// break;// default:// break;// }locale = new Locale(arg,arg1);Slog.e(TAG,"ldd_locale locale:"+locale);String language = locale.getDisplayName();Slog.e(TAG,"ldd_locale language:"+language);  try {  IActivityManager am = ActivityManagerNative.getDefault();  Configuration config = am.getConfiguration(); Slog.e(TAG,"ldd_locale old_language:"+config);  config.setLocale(locale); Slog.e(TAG,"ldd_locale new_language:"+config);  am.updateLanguage(config);Slog.e(TAG,"ldd_locale updateLanguage success");  BackupManager.dataChanged("com.android.providers.settings");  } catch (RemoteException e) {  }  }

Five_stepaidl接口

aidl接口
void updateLanguage(String arg,String arg1);

将3个文件push 到 /system/framework/ 后重启
应用层调用例:

  • 中文简体 reemanService.updateLanguage(zh,CN);
  • 中文香港 reemanService.updateLanguage(zh,HK);
  • 中文繁体(台湾)zh_TW
  • 英文(英国)en_GB
  • 英文(美国)en_US
  • 日文 ja_JP
  • 韩文 ko_KR
    调用接口需要系统重启,系统才会更新语言

Six_step直接调用系统updateLocale方法
直接调用updateLocale()方法来传递参数locale来实现语言切换,而不需要系统重启

service中添加方法

public  void wakeLocale(String arg,String arg1){        Locale wake = new Locale(arg,arg1);     LocalePicker.updateLocale(wake);     Slog.e(TAG,"ldd_locale success");  }

系统签名&添加权限
在AndroidManifest.xml 中添加

android:sharedUserId="android.uid.system"
 <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />

在Android.mk中添加

LOCAL_CERTIFICATE:=platform

在实际项目开发过程中,可能你需要用到第一种方法,后者的方法的应用程序需要内嵌入系统中来编译下执行?系统签名?……

1 0
原创粉丝点击