[Xiaomi Mi Note Pro] Aqq123:
Patching and Recompiling the Application Packages

Attached to this post are diffs for each of the APKs, along with their recompiled patched versions. The recompiled versions are based on Xiaomi.eu's ROM version 5.12.31.

Purpose

Nearly everything can be customized by modifying the code inside the APK. Resources can also be changed to translate or modify text or images displayed in a particular place. This is a last resort for stuff that cannot be adjusted through the Settings interface or by editing the configuration files. As of now, with Leo/MIUI I do it for three reasons:

Remove the Mi Talk notification asking me to "activate" my SIM card, without confirming my phone number and sending the text message to Xiaomi.

Remove the Mi Voice (built-in VOIP) group from the Contacts

Remove the notification saying that I have "lost connectivity because I left my home network", which was nearly always on because I put a foreign SIM card in the second slot, even though the first card is selected for data. This last diff might also be useful to non-MIUI users.

Reference

What follows is a quick summary how to do the modifications described below. I will not be explaining everything in detail but it should be enough to get you started.

APK Tool Wrapper

apktool2.bat

@echo off
setlocal
set PATH=%CD%;%PATH%;
java -jar \path\to\apktool-2.x.x.jar %1 %2 %3 %4 %5 %6 %7 %8 %9

Initial Framework Installation

apktool2 if -t miui system/framework/framework-res.apk

apktool2 if -t miui system/framework/framework-ext-res/framework-ext-res.apk

apktool2 if -t miui system/app/miui/miui.apk

apktool2 if -t miui system/app/miuisystem/miuisystem.apk

This only needs to be done once, the first time you are modifying any MIUI APK.

Decompiling with APK Tool

apktool2 d -b -o <AppName> -r -t miui <AppName>.apk

Decompiling with -b skips the generation of comments such as line numbers, which should make the diffs easier to apply even against future versions. Also, since in the situations below I'm only modifying the code, the -r flag skips decompiling the resources.

Applying a Diff Patch

patch --binary --no-backup-if-mismatch -E -i <DiffFileName>.diff -p0

Generating a Diff Patch

To generate your own patches, the syntax is:

diff -uN <FileName>.orig <FileName> > <FileName>.diff

For a single file.

diff -urN <DirName>.orig <DirName> > <DirName>.diff

For a recursive patch comparing directories.

Before making any changes, copy the original file or directory to <FileName>.orig or <DirName>.orig

Recompiling with APK Tool

apktool2 b -a aapt-miui.exe -c -o <AppName>.apk.unaligned <AppName>

The special version of AAPT for MIUI is available from Xiaomi with the drivers package, although based on my experience, the regular AAPT works just as well. Using the -c flag just copies over the old signature, so we don't need to sign the app again, note however that this will not work if you make any changes to AndroidManifest.xml.

zipalign -f 4 <AppName>.unaligned.apk <AppName>.apk

Aligns the APK file.

Changes

Mi Talk SIM Card Activation Nag

/system/app/XiaomiServiceFramework/XiaomiServiceFramework.apk

The following patch removes the Mi Talk notification asking to "activate" the SIM card. Normally to get rid of this message you'd need to send a text message to Xiaomi every time you change the SIM card. The patch doesn't interfere with the Mi Talk functionality so if you decide to register for it later, it will still be possible. This just removes the notification nag.

The patch:

diff -urN XiaomiServiceFramework.orig/smali/com/xiaomi/activate/ActivateProgressController.smali XiaomiServiceFramework/smali/com/xiaomi/activate/ActivateProgressController.smali
--- XiaomiServiceFramework.orig/smali/com/xiaomi/activate/ActivateProgressController.smali	Sat Jan 02 19:25:42 2016
+++ XiaomiServiceFramework/smali/com/xiaomi/activate/ActivateProgressController.smali	Sat Jan 02 20:03:19 2016
@@ -168,20 +168,6 @@
.locals 2
.param p1 # Landroid/content/Context;

- const-string v1, "notification"
-
- invoke-virtual {p1, v1}, Landroid/content/Context;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
-
- move-result-object v0
-
- check-cast v0, Landroid/app/NotificationManager;
-
- const/4 v1, 0x5
-
- invoke-virtual {v0, v1}, Landroid/app/NotificationManager;->cancel(I)V
-
- invoke-static {}, Lcom/xiaomi/activate/ActivatePopupActivity;->dismiss()V
-
return-void
.end method

@@ -858,64 +844,6 @@
.method private notifyUnactivatedSimCards(Landroid/content/Context;)V
.locals 7
.param p1 # Landroid/content/Context;
-
- const/4 v6, 0x1
-
- const-string v3, "notification"
-
- invoke-virtual {p1, v3}, Landroid/content/Context;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
-
- move-result-object v1
-
- check-cast v1, Landroid/app/NotificationManager;
-
- new-instance v0, Landroid/app/Notification$Builder;
-
- invoke-direct {v0, p1}, Landroid/app/Notification$Builder;-><init>(Landroid/content/Context;)V
-
- const v3, 0x7f07002c
-
- invoke-virtual {p1, v3}, Landroid/content/Context;->getString(I)Ljava/lang/String;
-
- move-result-object v3
-
- invoke-virtual {v0, v3}, Landroid/app/Notification$Builder;->setContentTitle(Ljava/lang/CharSequence;)Landroid/app/Notification$Builder;
-
- invoke-static {}, Lcom/xiaomi/activate/ActivateExternal;->getSysInteface()Lcom/xiaomi/activate/SysInterface;
-
- move-result-object v3
-
- invoke-interface {v3}, Lcom/xiaomi/activate/SysInterface;->getAppIconRes()I
-
- move-result v3
-
- invoke-virtual {v0, v3}, Landroid/app/Notification$Builder;->setSmallIcon(I)Landroid/app/Notification$Builder;
-
- invoke-virtual {v0, v6}, Landroid/app/Notification$Builder;->setAutoCancel(Z)Landroid/app/Notification$Builder;
-
- invoke-static {}, Ljava/lang/System;->currentTimeMillis()J
-
- move-result-wide v4
-
- invoke-virtual {v0, v4, v5}, Landroid/app/Notification$Builder;->setWhen(J)Landroid/app/Notification$Builder;
-
- const/4 v3, -0x1
-
- const/4 v4, 0x0
-
- invoke-static {p1, v3, v6, v4}, Lcom/xiaomi/activate/ActivateProgressController;->getActivatePopupPendingIntent(Landroid/content/Context;IILjava/lang/String;)Landroid/app/PendingIntent;
-
- move-result-object v2
-
- invoke-virtual {v0, v2}, Landroid/app/Notification$Builder;->setContentIntent(Landroid/app/PendingIntent;)Landroid/app/Notification$Builder;
-
- const/4 v3, 0x5
-
- invoke-virtual {v0}, Landroid/app/Notification$Builder;->build()Landroid/app/Notification;
-
- move-result-object v4
-
- invoke-virtual {v1, v3, v4}, Landroid/app/NotificationManager;->notify(ILandroid/app/Notification;)V

invoke-direct {p0}, Lcom/xiaomi/activate/ActivateProgressController;->setNotifiedEverFlagTrue()V

Apply with:

adb pull /system/app/XiaomiServiceFramework/XiaomiServiceFramework.apk

apktool2 d -b -o XiaomiServiceFramework -r -t miui XiaomiServiceFramework.apk

patch --binary --no-backup-if-mismatch -E -i system_app_XiaomiServiceFramework.diff -p0

apktool2 b -a aapt-miui.exe -c -o XiaomiServiceFramework.apk.unaligned XiaomiServiceFramework

zipalign -f 4 XiaomiServiceFramework.apk.unaligned XiaomiServiceFramework.apk

adb root

adb shell mount -o remount,rw /system

adb push XiaomiServiceFramework.apk /system/app/XiaomiServiceFramework/

Mi Voice Ad in Contacts

/system/priv-app/Contacts/Contacts.apk

MIUI Contacts now include a "Mi Voice" entry, which is essentially just an ad encouraging you to sign up for Xiaomi's proprietary VoIP service. The contact cannot be deleted or hidden from within the Settings, at least without activating it first, which involves sending a text message (again). This patch will get rid of it. It does not impact any of the other functionality of Mi Voice, so if you decide to register with it later, it should still work. Just do it from the Settings menu instead.

The patch:

diff -urN Contacts.orig/smali/com/android/contacts/list/ProfileAndContactsLoader.smali Contacts/smali/com/android/contacts/list/ProfileAndContactsLoader.smali
--- Contacts.orig/smali/com/android/contacts/list/ProfileAndContactsLoader.smali	Tue Jan 05 17:53:40 2016
+++ Contacts/smali/com/android/contacts/list/ProfileAndContactsLoader.smali	Tue Jan 05 17:57:12 2016
@@ -190,19 +190,6 @@
invoke-virtual {v8, v9}, Landroid/database/MatrixCursor;->addRow([Ljava/lang/Object;)V

:cond_3
- iget-boolean v0, p0, Lcom/android/contacts/list/ProfileAndContactsLoader;->mLoadVoipGroup:Z
-
- if-eqz v0, :cond_4
-
- const-string v0, "lookup_voip_group"
-
- const v1, 0x7f0c03ff
-
- invoke-direct {p0, v0, v1}, Lcom/android/contacts/list/ProfileAndContactsLoader;->loadGroupItem(Ljava/lang/String;I)[Ljava/lang/Object;
-
- move-result-object v9
-
- invoke-virtual {v8, v9}, Landroid/database/MatrixCursor;->addRow([Ljava/lang/Object;)V

:cond_4
iget-boolean v0, p0, Lcom/android/contacts/list/ProfileAndContactsLoader;->mLoadFollowedYellowPage:Z

Apply with:

adb pull /system/priv-app/Contacts/Contacts.apk

apktool2 d -b -o Contacts -r -t miui Contacts.apk

patch --binary --no-backup-if-mismatch -E -i system_priv-app_Contacts.diff -p0

apktool2 b -a aapt-miui.exe -c -o Contacts.apk.unaligned Contacts

zipalign -f 4 Contacts.apk.unaligned Contacts.apk

adb root

adb shell mount -o remount,rw /system

adb push Contacts.apk /system/priv-app/Contacts/

Data Roaming Lost Connection Notification

/system/priv-app/TeleService/TeleService.apk

This patch will remove the notification saying that "You have lost data connectivity because you left your home network". This is not a MIUI-specific message but I believe this notification being active all the time is due to a some glitch in the way MIUI handles the two SIM cards: in my setup, I have a local and a foreign SIM card inserted in my phone, however it is the former one that is selected for mobile data, and the data connection is working just fine, so by all means this notification should not pop up in such circumstances.

Anyway, as this message is annoying and useless in stock Android too, this diff might also be useful to non-MIUI users: feel free to adapt it to your needs of course.

The patch:

diff -urN TeleService.orig/smali/com/android/phone/NotificationMgr.smali TeleService/smali/com/android/phone/NotificationMgr.smali
--- TeleService.orig/smali/com/android/phone/NotificationMgr.smali	Mon Jan 04 00:42:16 2016
+++ TeleService/smali/com/android/phone/NotificationMgr.smali	Mon Jan 04 00:51:47 2016
@@ -637,27 +637,6 @@

# virtual methods
-.method hideDataDisconnectedRoaming()V
- .locals 2
-
- sget-boolean v0, Lcom/android/phone/NotificationMgr;->DBG:Z
-
- if-eqz v0, :cond_0
-
- const-string v0, "hideDataDisconnectedRoaming()..."
-
- invoke-direct {p0, v0}, Lcom/android/phone/NotificationMgr;->log(Ljava/lang/String;)V
-
- :cond_0
- iget-object v0, p0, Lcom/android/phone/NotificationMgr;->mNotificationManager:Landroid/app/NotificationManager;
-
- const/4 v1, 0x5
-
- invoke-virtual {v0, v1}, Landroid/app/NotificationManager;->cancel(I)V
-
- return-void
-.end method
-
.method public postTransientNotification(ILjava/lang/CharSequence;)V
.locals 2
.param p1 # I
@@ -686,167 +665,6 @@

invoke-virtual {v0}, Landroid/widget/Toast;->show()V

- return-void
-.end method
-
-.method showDataDisconnectedRoaming()V
- .locals 13
-
- const/4 v10, 0x0
-
- const/4 v12, 0x0
-
- sget-boolean v9, Lcom/android/phone/NotificationMgr;->DBG:Z
-
- if-eqz v9, :cond_0
-
- const-string v9, "showDataDisconnectedRoaming()..."
-
- invoke-direct {p0, v9}, Lcom/android/phone/NotificationMgr;->log(Ljava/lang/String;)V
-
- :cond_0
- new-instance v4, Landroid/content/Intent;
-
- iget-object v9, p0, Lcom/android/phone/NotificationMgr;->mContext:Landroid/content/Context;
-
- const-class v11, Lcom/android/phone/settings/MobileNetworkSettings;
-
- invoke-direct {v4, v9, v11}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V
-
- iget-object v9, p0, Lcom/android/phone/NotificationMgr;->mContext:Landroid/content/Context;
-
- invoke-static {v9, v12, v4, v12}, Landroid/app/PendingIntent;->getActivity(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
-
- move-result-object v1
-
- iget-object v9, p0, Lcom/android/phone/NotificationMgr;->mContext:Landroid/content/Context;
-
- const v11, 0x7f090221
-
- invoke-virtual {v9, v11}, Landroid/content/Context;->getText(I)Ljava/lang/CharSequence;
-
- move-result-object v2
-
- new-instance v9, Landroid/app/Notification$Builder;
-
- iget-object v11, p0, Lcom/android/phone/NotificationMgr;->mContext:Landroid/content/Context;
-
- invoke-direct {v9, v11}, Landroid/app/Notification$Builder;-><init>(Landroid/content/Context;)V
-
- const v11, 0x108008a
-
- invoke-virtual {v9, v11}, Landroid/app/Notification$Builder;->setSmallIcon(I)Landroid/app/Notification$Builder;
-
- move-result-object v9
-
- iget-object v11, p0, Lcom/android/phone/NotificationMgr;->mContext:Landroid/content/Context;
-
- const v12, 0x7f09021e
-
- invoke-virtual {v11, v12}, Landroid/content/Context;->getText(I)Ljava/lang/CharSequence;
-
- move-result-object v11
-
- invoke-virtual {v9, v11}, Landroid/app/Notification$Builder;->setContentTitle(Ljava/lang/CharSequence;)Landroid/app/Notification$Builder;
-
- move-result-object v9
-
- iget-object v11, p0, Lcom/android/phone/NotificationMgr;->mContext:Landroid/content/Context;
-
- invoke-virtual {v11}, Landroid/content/Context;->getResources()Landroid/content/res/Resources;
-
- move-result-object v11
-
- const v12, 0x7f070027
-
- invoke-virtual {v11, v12}, Landroid/content/res/Resources;->getColor(I)I
-
- move-result v11
-
- invoke-virtual {v9, v11}, Landroid/app/Notification$Builder;->setColor(I)Landroid/app/Notification$Builder;
-
- move-result-object v9
-
- invoke-virtual {v9, v2}, Landroid/app/Notification$Builder;->setContentText(Ljava/lang/CharSequence;)Landroid/app/Notification$Builder;
-
- move-result-object v0
-
- iget-object v9, p0, Lcom/android/phone/NotificationMgr;->mUserManager:Landroid/os/UserManager;
-
- const/4 v11, 0x1
-
- invoke-virtual {v9, v11}, Landroid/os/UserManager;->getUsers(Z)Ljava/util/List;
-
- move-result-object v8
-
- const/4 v3, 0x0
-
- :goto_0
- invoke-interface {v8}, Ljava/util/List;->size()I
-
- move-result v9
-
- if-ge v3, v9, :cond_3
-
- invoke-interface {v8, v3}, Ljava/util/List;->get(I)Ljava/lang/Object;
-
- move-result-object v6
-
- check-cast v6, Landroid/content/pm/UserInfo;
-
- invoke-virtual {v6}, Landroid/content/pm/UserInfo;->isManagedProfile()Z
-
- move-result v9
-
- if-eqz v9, :cond_1
-
- :goto_1
- add-int/lit8 v3, v3, 0x1
-
- goto :goto_0
-
- :cond_1
- invoke-virtual {v6}, Landroid/content/pm/UserInfo;->getUserHandle()Landroid/os/UserHandle;
-
- move-result-object v7
-
- invoke-virtual {v7}, Landroid/os/UserHandle;->isOwner()Z
-
- move-result v9
-
- if-eqz v9, :cond_2
-
- move-object v9, v1
-
- :goto_2
- invoke-virtual {v0, v9}, Landroid/app/Notification$Builder;->setContentIntent(Landroid/app/PendingIntent;)Landroid/app/Notification$Builder;
-
- new-instance v9, Landroid/app/Notification$BigTextStyle;
-
- invoke-direct {v9, v0}, Landroid/app/Notification$BigTextStyle;-><init>(Landroid/app/Notification$Builder;)V
-
- invoke-virtual {v9, v2}, Landroid/app/Notification$BigTextStyle;->bigText(Ljava/lang/CharSequence;)Landroid/app/Notification$BigTextStyle;
-
- move-result-object v9
-
- invoke-virtual {v9}, Landroid/app/Notification$BigTextStyle;->build()Landroid/app/Notification;
-
- move-result-object v5
-
- iget-object v9, p0, Lcom/android/phone/NotificationMgr;->mNotificationManager:Landroid/app/NotificationManager;
-
- const/4 v11, 0x5
-
- invoke-virtual {v9, v10, v11, v5, v7}, Landroid/app/NotificationManager;->notifyAsUser(Ljava/lang/String;ILandroid/app/Notification;Landroid/os/UserHandle;)V
-
- goto :goto_1
-
- :cond_2
- move-object v9, v10
-
- goto :goto_2
-
- :cond_3
return-void
.end method

diff -urN TeleService.orig/smali/com/android/phone/PhoneGlobals$1.smali TeleService/smali/com/android/phone/PhoneGlobals$1.smali
--- TeleService.orig/smali/com/android/phone/PhoneGlobals$1.smali	Mon Jan 04 00:42:16 2016
+++ TeleService/smali/com/android/phone/PhoneGlobals$1.smali	Mon Jan 04 00:51:37 2016
@@ -112,20 +112,10 @@
goto :goto_0

:sswitch_3
- iget-object v4, p0, Lcom/android/phone/PhoneGlobals$1;->this$0:Lcom/android/phone/PhoneGlobals;

- iget-object v4, v4, Lcom/android/phone/PhoneGlobals;->notificationMgr:Lcom/android/phone/NotificationMgr;
-
- invoke-virtual {v4}, Lcom/android/phone/NotificationMgr;->showDataDisconnectedRoaming()V
-
goto :goto_0

:sswitch_4
- iget-object v4, p0, Lcom/android/phone/PhoneGlobals$1;->this$0:Lcom/android/phone/PhoneGlobals;
-
- iget-object v4, v4, Lcom/android/phone/PhoneGlobals;->notificationMgr:Lcom/android/phone/NotificationMgr;
-
- invoke-virtual {v4}, Lcom/android/phone/NotificationMgr;->hideDataDisconnectedRoaming()V

goto :goto_0

Apply with:

adb pull /system/priv-app/TeleService/TeleService.apk

apktool2 d -b -o TeleService -r -t miui TeleService.apk

patch --binary --no-backup-if-mismatch -E -i system_priv-app_TeleService.diff -p0

apktool2 b -a aapt-miui.exe -c -o TeleService.apk.unaligned TeleService

zipalign -f 4 TeleService.apk.unaligned TeleService.apk

adb root

adb shell mount -o remount,rw /system

adb push TeleService.apk /system/priv-app/TeleService/