很多第三方ROM会已经包括了高级电源菜单,但是往往,在重启项中的4个选项会是英文的列表,如下:
normal
hot reboot
bootloader
recovery
这点难免让人有些不爽,那么本文就来教大家如何把这个列表变成:
正常重启
快速重启
引导模式
刷机模式
一、实现原理:
列表中的4项被定义在一个字符串型数组中(数组1),而如果单纯的将这个数组中的4个字符串汉化的话,会导致重启出现错误,这是因为显示值与操作数冲突。好奇的朋友可以试试。那么解决的办法就是再重新定义一个容量为4的字符串型数组(数组2),将汉化后的值赋进去,作用仅仅是显示,与操作数分开,这样就不会造成与操作数的冲突。最终的效果就是在显示的时候读取数组2,而执行操作的时候参数读取自数组1。(理解这里可能需要一些编程基础,不过不懂也不要紧,跟着教程做,会成功的)
二、修改方法:(方法仅供参考,有问题请跟贴回复,谢谢~!)
1、以压缩包方式打开android.policy.jar,将classes.dex取出,放在smali工具根目录下,运行“解包”,输出文件夹out。此举是将dex反编译为smali文件,便于修改。
2、进行修改,这里具体的行数以我自己的做说明,实际中多少可能会有些偏差。
打开\com\android\internal\policy\impl\GlobalActions$SinglePressAction.smali,在24行,找到这样一条语句:
.field protected static final rebootOptions:[Ljava/lang/String;
这条语句的含义是定义了一个字符串型的变量,名称为rebootOptions,通过字面很容易理解为重启设置,就是原理中所述的操作数。同样根据原理所述,我们需要再定义一个同样类型的变量来作为显示。中间空一行,在26行,添加如下语句:
.field protected static final rebootString:[Ljava/lang/String;
变量的名字叫做rebootString,是稍后用来显示的。
3、继续往下看,第38行后:
.method static constructor <clinit>()V
.registers 3 ——声明使用3个寄存器
const/4 v0, 0x4 ——v0=4
new-array v0, v0, [Ljava/lang/String; ——建立新数组,容量为v0,即4
const/4 v1, 0x0 ——v1=0
const-string v2, "Normal" ——v2=Normal
aput-object v2, v0, v1 ——v0数组中的第v1个值为v2,即数组中的第一个为Normal(至于0为什么是第一个就不提了,0123就是1234)
const/4 v1, 0x1
const-string v2, "Hot restart"
aput-object v2, v0, v1
const/4 v1, 0x2
const-string v2, "Bootloader"
aput-object v2, v0, v1
const/4 v1, 0x3
const-string v2, "Recovery"
aput-object v2, v0, v1
sput-object v0, Lcom/android/internal/policy/impl/GlobalActions$SinglePressAction;->rebootOptions:[Ljava/lang/String; ——rebootOptions就从v0数组中取值了,作为操作数
上段原来的代码,有必要的地方都加了注释,会代码的仔细看一看吧。原来的代码,不难看出,这里只定义了给rebootOptions提供参数的一个容量为4的数组。同样,仿照它,再定义一个容量为4的数组,来给上边定义过的rebootString提供参数。
修改后的代码如下:
.method static constructor <clinit>()V
.registers 8
const/4 v7, 0x4
const/4 v6, 0x3
const/4 v5, 0x2
const/4 v4, 0x1
const/4 v3, 0x0
new-array v0, v7, [Ljava/lang/String; ——新的数组v0,容量为v7(4)
const-string v2, "\u6B63\u5E38\u91CD\u542F" ——“正常重启”的转码结果赋值给v2
aput-object v2, v0, v3 ——数组v0的第v3位为v2
const-string v2, "\u5FEB\u901F\u91CD\u542F" ——“快速重启”
aput-object v2, v0, v4
const-string v2, "\u5F15\u5BFC\u6A21\u5F0F" ——“引导模式”
aput-object v2, v0, v5
const-string v2, "\u5237\u673A\u6A21\u5F0F" ——“刷机模式”
aput-object v2, v0, v6
sput-object v0, Lcom/android/internal/policy/impl/GlobalActions$SinglePressAction;->rebootString:[Ljava/lang/String; ——数组定义完毕,rebootString的参数将从数组v0中读取
new-array v1, v7, [Ljava/lang/String;
const-string v2, "Normal"
aput-object v2, v1, v3
const-string v2, "Hot restart"
aput-object v2, v1, v4
const-string v2, "Bootloader"
aput-object v2, v1, v5
const-string v2, "Recovery"
aput-object v2, v1, v6
sput-object v1, Lcom/android/internal/policy/impl/GlobalActions$SinglePressAction;->rebootOptions:[Ljava/lang/String;
这样就有了一个新的数组,其中4位内容分别为:正常重启、快速重启、引导模式、刷机模式。而在显示的时候rebootString会调用这个数组里的值,这样就达到了汉化的目的。然后保存文件。
4、在\com\android\internal\policy\impl\GlobalActions$5.smali中,71行处:
sget-object v2, Lcom/android/internal/policy/impl/GlobalActions$SinglePressAction;->rebootOptions:[Ljava/lang/String;
将rebootOptions改为rebootString,意为显示时指定通过rebootString取值。然后保存文件。
5、将GlobalActions$SinglePressAction.smali和GlobalActions$5.smali修改完毕保存后,回到smali工具的根目录,运行“打包”,生成文件smail-classes.dex。在将这个文件重命名为classes.dex,以压缩包方式打开android.policy.jar,将classes.dex替换进去,不用签名。
这样,一个新的android.policy.jar就做完了,用adb push或者RE文件浏览器替换回去,修改相应权限和所有者,看看效果吧。