很多第三方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文件浏览器替换回去,修改相应权限和所有者,看看效果吧。