MIUI还挺好用的,除了广告比较多,其他都很适合国内的用户使用。但是有一个功能MIUI死活不肯加进去,就是状态栏的时钟死活不加入显秒的设置。当然,目前很多第三方固件支持显秒,或者支持安装Xposed之后安装显秒模块。然而,迁移到第三方固件的一个问题就是数据比较难保持一致,而且可能不太稳定。安装Xposed更不用看了,MIUI原生跟它有仇,而且安装Xposed之后必然导致系统卡顿、耗电增加。所以最好的方法就是使用Magisk模块Systemless地增加时钟显秒。
此教程以小米6X稳定版为例,制作Magisk模块。要注意的是,不同设备不同系统之间模块不通用,也就是说,我制作了MI6X的这样一个模块,MI8是不能用的。我在MI6X的稳定版做了这个模块,MI6X的开发板也不能用。每部设备的每个版本的系统都需要单独制作,这也是为什么我选择发制作教程而不是直接发模块。
手机与设备使用数据线连接,并且手机已经开启USB调试。
使用adb把相关文件和目录拉到工作目录:
/system/framework/arm64目录 adb pull /system/framework/arm64
这时候工作目录下面应该有一个arm64的文件夹了。
/system/priv-app/MiuiSystemUI/oat/arm64目录,也是放到arm64文件夹: adb pull /system/priv-app/MiuiSystemUI/oat/arm64
这时候arm64文件夹应该多了两个文件。
 adb pull /system/priv-app/MiuiSystemUI/MiuiSystemUI.apk
 adb pull /system/framework/framework-ext-res/framework-ext-res.apk
 adb pull /system/framework/framework-res.apk
 adb pull /system/app/miui/miui.apk
 adb pull /system/app/miuisystem/miuisystem.apk
拉完文件之后,进入arm64目录,把MiuiSystemUI进行deodex化:
arm64目录 cd arm64
baksmali进行deodex。(假设baksmali文件名为baksmali.jar,并且在上一一级目录,也就是工作目录上) java -jar ../baksmali.jar de MiuiSystemUI.odex -o MiuiSystemUI
这样之后会生成MiuiSystemUI目录。
然后转成dex文件:
 java -jar ../smali.jar ass MiuiSystemUI -o ../classes.dex
这样之后在工作目录就生成了一个classes.dex文件了。回到工作目录:
 cd ..
用解压软件打开MiuiSystemUI.apk,把classes.dex放进去。
使用apktool反汇编MiuiSystemUI.apk。
假设apktool文件名为apktool.jar并且在当前目录。
 java -jar apktool.jar if framework-res.apk
 java -jar apktool.jar if framework-ext-res.apk
 java -jar apktool.jar if miui.apk
 java -jar apktool.jar if miuisystem.apk
 java -jar apktool.jar d MiuiSystemUI.apk -o MiuiSystemUI
这时候生成了一个MiuiSystemUI目录。
修复pip_dismiss_scrim.9.png文件。
这个文件是Android O里面的一个通有问题,会导致apktool不能重新封包。提示错误:
 W: ERROR: 9-patch image pip_dismiss_scrim.9.png malformed.
 W:        No marked region found along edge.
 W:        Found along left edge.
 W: ERROR: Failure processing PNG image pip_dismiss_scrim.9.png
修复res的目录结构
由于apktool的一些问题,这时候解包出来的res目录结构跟原apk不一样。比如:原来用解压软件打开MiuiSystemUI.apk里面有res/drawable, res/drawable-v21和res/drawable-v23目录。但是解包出来之后一个res/drawable目录了,后面两个目录的文件都跑到第一个文件里面了。这时候我们需要修复目录结构。主要修复分为以下几种:
drawable-ldrtl-xxhdpi-v4变成了drawable-ldrtl-xxhdpi。这需要在对应目录后面加上版本号。drawable-v21和drawable-v23目录合并到drawable里面了。这时候需要创建drawable-v21和drawable-v23两个目录,并对照着原apk文件,把跑到drawable里面的文件剪贴回drawable-v21和drawable-v23里面。qs_tile_expand_indicator.png.png文件(不知道是不是小米工程师改错名了),在解包之后变成了qs_tile_expand_indicator.png,需要把.png加回去。修改完成之后,res里面除了values开头的目录,其余均和原apk文件里面的目录名、目录里面文件一致。
 mkdir color-v11 color-v23 drawable-v21 drawable-v23 layout-v11 layout-v21 layout-v26
 mv drawable-440dpi drawable-440dpi-v4
 mv drawable-hdpi drawable-hdpi-v4 
 mv drawable-land-440dpi drawable-land-440dpi-v4
 mv drawable-land-xxhdpi drawable-land-xxhdpi-v4
 mv drawable-ldrtl-xxhdpi drawable-ldrtl-xxhdpi-v4
 mv drawable-mdpi drawable-mdpi-v4
 mv drawable-nodpi drawable-nodpi-v4
 mv drawable-xhdpi drawable-xhdpi-v4
 mv drawable-xxhdpi drawable-xxhdpi-v4
 mv drawable-xxxhdpi drawable-xxxhdpi-v4
 mv layout-television layout-television-v8
 mv layout-watch layout-watch-v8
 mv mipmap-hdpi mipmap-hdpi-v4
 mv mipmap-mdpi mipmap-mdpi-v4
 mv mipmap-xhdpi mipmap-xhdpi-v4
 mv raw-440dpi raw-440dpi-v4
 mv raw-xxhdpi raw-xxhdpi-v4
 mv color/abc_background_cache_hint_selector_material_dark.xml color/abc_background_cache_hint_selector_material_light.xml color-v11 
 mv color/abc_btn_colored_borderless_text_material.xml color/abc_btn_colored_text_material.xml color/abc_color_highlight_material.xml color/abc_tint_btn_checkable.xml color/abc_tint_default.xml color/abc_tint_edittext.xml color/abc_tint_seek_thumb.xml color/abc_tint_spinner.xml color/abc_tint_switch_track.xml color-v23
 mv drawable/abc_action_bar_item_background_material.xml drawable/abc_btn_colored_material.xml drawable/abc_edit_text_material.xml drawable/preference_list_divider_material.xml drawable-v21
 mv drawable/abc_control_background_material.xml drawable-v23 
 mv layout/preference.xml layout/preference_dropdown.xml layout-v11
 mv layout/preference_category_material.xml layout/preference_dropdown_material.xml layout/preference_information_material.xml layout/preference_material.xml layout-v21
 mv layout/abc_screen_toolbar.xml layout-v26
 mv drawable-440dpi-v4/qs_tile_expand_indicator.png drawable-440dpi-v4/qs_tile_expand_indicator.png.png
修改res/layout/status_bar.xml文件。
用文本编辑器打开res/layout/status_bar.xml,搜索关键字com.android.systemui.statusbar.policy.Clock,然后把:
 <com.android.systemui.statusbar.policy.Clock android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="center_vertical" android:id="@id/clock" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" android:paddingStart="@dimen/status_bar_clock_starting_padding" android:paddingEnd="@dimen/status_bar_clock_end_padding" />
替换为:
 <com.android.systemui.statusbar.policy.Clock android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="center_vertical" android:id="@id/clock" android:layout_width="0.0dip" android:layout_height="fill_parent" android:singleLine="true" android:paddingStart="@dimen/status_bar_clock_starting_padding" android:paddingEnd="@dimen/status_bar_clock_end_padding" />
 <com.android.systemui.statusbar.policy.AdvanceClock android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="center" android:layout_gravity="center" android:id="@id/advance_clock" android:paddingBottom="@dimen/statusbar_text_bottom_padding" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" android:format12Hour="ahh:mm:ss" android:format24Hour="HH:mm:ss" />
保存文件。
修改res/values/ids.xml文件
用文本编辑器打开res/values/ids.xml文件,定位到倒数第二行,在其后添加一行(也就是说在</resources>前添加一行):
 <item type="id" name="advance_clock">false</item>
修改res/values/public.xml文件
用文本编辑器打开res/values/public.xml,定位到以<public type="id"开头的最后一行。
在我这里是xml <public type="id" name="zen_radio_buttons_content" id="0x7f0a0323" />
留意这里id后引号内的内容0x7f0a0323,加一就是0x7f0a0324,记录下来。
在该行后添加一行:
 <public type="id" name="advance_clock" id="0x7f0a0324" />
留意这里id后的印号内的内容就是上一行id内容加一。
搜索status_bar_textColor_darkmode,得到:
 <public type="color" name="status_bar_textColor_darkmode" id="0x7f060175" />
把id后引号内容0x7f060175记录下来。
搜索status_bar_textColor,得到:
 <public type="color" name="status_bar_textColor" id="0x7f060174" />
把id后引号内容0x7f060174记录下来。
搜索clock,得到:
 <public type="id" name="clock" id="0x7f0a0085" />
把id后引号内容0x7f0a0085记录下来。
修改smali/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.smali文件。
用文本编辑器打开smali/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.smali。搜索刚才搜clock时候得到的id,我这里是0x7f0a0085,得到:
 const v3, 0x7f0a0085
在该行的上一行,添加:
 const v3, 0x7f0a0324
 invoke-virtual {v2, v3}, Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;->findViewById(I)Landroid/view/View;
 move-result-object v2
 check-cast v2, Lcom/android/systemui/statusbar/policy/AdvanceClock;
 iput-object v2, p0, Lcom/android/systemui/statusbar/phone/CollapsedStatusBarFragment;->mStatusAdvanceClock:Lcom/android/systemui/statusbar/policy/AdvanceClock;
 iget-object v2, p0, Lcom/android/systemui/statusbar/phone/CollapsedStatusBarFragment;->mStatusBar:Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;
其中第一行的const v3, 0x7f0a0324中的0x7f0a0324就是记住的advance_clock的id(那个加一后的id)。注意替换。
搜索.field private mSignalClusterView:Lcom/android/systemui/statusbar/SignalClusterView;,在该行后添加一行:
 .field private mStatusAdvanceClock:Lcom/android/systemui/statusbar/policy/AdvanceClock;
注意前面有一个点。
搜索addDarkReceiver,在其中一行后加上:
 const-class v2, Lcom/android/systemui/statusbar/policy/DarkIconDispatcher;
 invoke-static {v2}, Lcom/android/systemui/Dependency;->get(Ljava/lang/Class;)Ljava/lang/Object;
 move-result-object v2
 check-cast v2, Lcom/android/systemui/statusbar/policy/DarkIconDispatcher;
 iget-object v3, p0, Lcom/android/systemui/statusbar/phone/CollapsedStatusBarFragment;->mStatusAdvanceClock:Lcom/android/systemui/statusbar/policy/AdvanceClock;
 invoke-interface {v2, v3}, Lcom/android/systemui/statusbar/policy/DarkIconDispatcher;->addDarkReceiver(Lcom/android/systemui/statusbar/policy/DarkIconDispatcher$DarkReceiver;)V
搜索removeDarkReceiver
在其中一行后添加:
 const-class v0, Lcom/android/systemui/statusbar/policy/DarkIconDispatcher;
 invoke-static {v0}, Lcom/android/systemui/Dependency;->get(Ljava/lang/Class;)Ljava/lang/Object;
 move-result-object v0
 check-cast v0, Lcom/android/systemui/statusbar/policy/DarkIconDispatcher;
 iget-object v1, p0, Lcom/android/systemui/statusbar/phone/CollapsedStatusBarFragment;->mStatusAdvanceClock:Lcom/android/systemui/statusbar/policy/AdvanceClock;
 invoke-interface {v0, v1}, Lcom/android/systemui/statusbar/policy/DarkIconDispatcher;->removeDarkReceiver(Lcom/android/systemui/statusbar/policy/DarkIconDispatcher$DarkReceiver;)V
然后保存文件。
添加smali/com/android/systemui/statusbar/policy/AdvanceClock.smali文件。
创建smali/com/android/systemui/statusbar/policy/AdvanceClock.smali文件。然后用文本编辑器打开它。内容为:
 .class public Lcom/android/systemui/statusbar/policy/AdvanceClock;
 .super Landroid/widget/TextClock;
 .source "AdvanceClock.java"
 # interfaces
 .implements Lcom/android/systemui/statusbar/policy/DarkIconDispatcher$DarkReceiver;
 # direct methods
 .method public constructor <init>(Landroid/content/Context;)V
     .locals 0
     .param p1, "context"    # Landroid/content/Context;
     .prologue
     .line 10
     invoke-direct {p0, p1}, Landroid/widget/TextClock;-><init>(Landroid/content/Context;)V
     .line 11
     return-void
 .end method
 .method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
     .locals 0
     .param p1, "context"    # Landroid/content/Context;
     .param p2, "attrs"    # Landroid/util/AttributeSet;
     .prologue
     .line 14
     invoke-direct {p0, p1, p2}, Landroid/widget/TextClock;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
     .line 15
     return-void
 .end method
 .method public constructor <init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
     .locals 0
     .param p1, "context"    # Landroid/content/Context;
     .param p2, "attrs"    # Landroid/util/AttributeSet;
     .param p3, "defStyleAttr"    # I
     .prologue
     .line 18
     invoke-direct {p0, p1, p2, p3}, Landroid/widget/TextClock;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;I)V
     .line 19
     return-void
 .end method
 # virtual methods
 .method public onDarkChanged(Landroid/graphics/Rect;FI)V
     .locals 2
     .param p1, "area"    # Landroid/graphics/Rect;
     .param p2, "darkIntensity"    # F
     .param p3, "tint"    # I
     .prologue
     .line 133
     invoke-virtual {p0}, Landroid/view/View;->getResources()Landroid/content/res/Resources;
     move-result-object v1
     .line 134
     invoke-static {p1, p0, p2}, Lcom/android/systemui/statusbar/policy/DarkIconDispatcherHelper;->inDarkMode(Landroid/graphics/Rect;Landroid/view/View;F)Z
     move-result v0
     if-eqz v0, :cond_0
     .line 135
     const v0, 0x7f060175
     .line 133
     :goto_0
     invoke-virtual {v1, v0}, Landroid/content/res/Resources;->getColor(I)I
     move-result v0
     invoke-virtual {p0, v0}, Landroid/widget/TextView;->setTextColor(I)V
     .line 136
     return-void
     .line 135
     :cond_0
     const v0, 0x7f060174
     goto :goto_0
 .end method
注意这里.line 135后面的一行,const v0, 0x7f060175中的0x7f060175来自之前搜索status_bar_textColor_darkmode时候记录下来的id。注意替换。
同样.line 135后面的第二行,const v0, 0x7f060174中的0x7f060174来自之前搜索status_bar_textColor时候记录下来的id。注意替换。
打包为apk文件。
 java -jar apktool.jar b MiuiSystemUI -o MiuiSystemUI_mod.apk
这时候在工作目录就会生成MiuiSystemUI_mod.apk文件了。
替换文件
同时用解压软件打开MiuiSystemUI_mod.apk和MiuiSystemUI.apk。然后把MiuiSystemUI_mod.apk里面的resources.arsc、classes.dex和res/layout/status_bar.xml这三个文件替换到MiuiSystemUI.apk里面。
测试
替换完成之后得到的MiuiSystemUI.apk,我们需要测试一下。测试很简单,就是再解包一次:
 java -jar apktool.jar d MiuiSystemUI.apk -o MiuiSystemUI_test
如果这时候没有出现错误信息,那就证明制作成功了。
如果出现一下错误:
 Could not decode file, replacing by FALSE value: 
就证明之前的修复res目录结构没有做好。根据错误提示给出的路径检查是不是某个文件漏了剪贴。
制作Magisk模块。
system/placeholder文件删掉。然后把MiuiSystemUI.apk文件放到/system/priv-app/MiuiSystemUI/下(自行建立文件夹)。module.prop修改模块的名字、描述和作者等信息。zip文件。zip文件检查,应该一打开就能看到module.prop才可以。把模块放到手机上,然后打开Magisk Manager安装。
这里建议先安装mm再安装模块。如果出现什么问题,可以到twrp中使用mm把模块删掉或者禁用。
粤公网安备44030002005029号