Android厂家如果做国际市场,总会遇到这样那样的问题。对于阿拉伯世界,以色列总是一个绕不过的话题。现在默认的规则是,除非有以色列的订单,否则,在手机的默认语言中不会出现希伯来语。
这个过程是如何实现的呢?
具体要求
要求有两点:
1,出厂时按照订单类型进行设置
2,在设置中进行恢复出厂设置不会清除标志位
思路
按照要求2,我们必须按照如下方式进行
1,我们只能在eeprom或者其他不会被andriod出厂复位到的分区进行设置
2,因为恢复出厂设置之后第一次开机就会有选择语言的动作,因此,从eeprom的读取以及传递到andriod系统必须在开机过程中完成
添加希伯来语
这一部分在博主的另外一篇文章中有详细的介绍,具体可以参考 Android系统语言列表
移除希伯来语
经过简单的查找,会发现Android系统读取语言的位置是在LocalePicker.java中,文件路径为:
framework/base/core/java/com/android/internal/app/LocalePicker.java
系统语言列表会读取到localeList数组中,希伯来语在此处以“iw-IL”的形式存在
public static List<LocaleInfo> getAllAssetLocales(Context context, boolean isInDeveloperMode) {
final Resources resources = context.getResources();
final String[] locales = Resources.getSystem().getAssets().getLocales();
List<String> localeList = new ArrayList<String>(locales.length);
Collections.addAll(localeList, locales);`
....
}
有朋友会问,可不可以在这里读取eeprom的值进行判断,答案是否定的,因为framework中不能导入芯片方案商的代码,可能会报编译错误。
那么可以要求方案商提供在开机过程中可以读取eeprom值的位置,然后创建一个文件,C代码如下:
a_cfg_eep_raw_read(0xF02+18 , &ui4_flag , 1 , &ui4_read);
DBG_INFO((" set hebrew flag===%d.\n\r",ui4_flag));
DBG_INFO((" set hebrew read===%d.\n\r",ui4_read));
if ( ui4_flag == 1)
{
int file=open("/tmp/showHebrew",O_RDWR|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
DBG_INFO((" create hebrew result===%d.\n\r",file));
if (file == -1)
{
DBG_INFO(("create hebrew error number===%s.\n\r",strerror(errno)));
}
close(file);
}else{
int result=remove("/tmp/showHebrew");
if (result == -1)
{
DBG_INFO((" delete hebrew error number===%s.\n\r",strerror(errno)));
}
}
博主在创建文件的过程中吃了不少苦头。
- 创建文件要用open函数而不能用fopen函数,虽然说fopen函数是对open函数的封装,但是我再用了fopen函数之后会导致机器无限重启!
- 创建文件的文件名有要求,不能存放在一个没有的路径下,open函数不会自动创建目录,也就是说”/tmp/factory/showHebrew“不行,必须直接创建到/tmp/目录下。
- 对于这种必须全部重新编译才能看到结果的改动,必须要多加点打印。否则解起来很困难。
framework判断是否显示希伯来语
最初的想法是在LocalePicker.java中判断“/tmp/showHebrew”是否存在。
如果存在,则设置“persist.sys.factory.hebrew”的属性值。可以正常编译,但是执行的时候遇到如下权限问题:
avc: denied { write } for name="property_service" dev="tmpfs" ino=2766 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:property_socket:s0 tclass=sock_file permissive=0
需要在platform_app.te中添加如下权限
allow platform_app property_socket:sock_file write;
但是这个权限会和app.te中的如下权限冲突
neverallow { appdomain -bluetooth -radio -shell -system_app -nfc }
property_socket:sock_file write;
如果进行更改,则可能导致Google的认证不能通过。因此,只能通过判断文件是否存在决定是否显示希伯来语。