目前在使用的小米 8 手机,更新 Miui 到 12.5 后,无法使用之前安装的谷歌框架了,后来搜索很多资料,最后能找到的唯一有效可行的方案就是此文。原文由 qin meng 写于知乎,原文地址:折腾小米8 MIUI 12.5 安装Google GMS套件 (需unlock,非root方案),转载前已经取得作者同意。本文内容较长,建议使用大屏设备阅读(以便于展开目录查看上下文对照)。

前言

去年我的老米8在MIUI 更新12.0的某后期版本和12.5以后,不再支持GMS套件了,即使自己安装也不行。小米自称是因为存储空间和电量消耗的问题,而网上又有人曝光实际上是因为谷歌对中国区GMS套件的限制要求导致的。不管什么原因,更新后GMS不能用了的确很麻烦,而实际上原来米8在MIUI10的时候是内置GMS套件的,只要在配置中打开即可。如下:

MIUI10的时候内置GMS套件

如果你的小米手机的设置中发现有这个设置,那么你就很幸运的不需要折腾GMS的套件了。打开这个后选项后,直接在小米应用市场中搜索play商店,安装后即可使用所有google play store的应用,十分方便。但是并不是所有小米和红米手机都支持这个选项,只有部分高端机型才有。现在我知道最便宜的支持GMS的小米手机是小米10青春版(需要升级到MIUI 12.5以后)。

在MIUI12.0后期某些版本之前,MIUI是支持自己安装GMS套件的方式来使用google的相关应用的,但是12.5中这种方式不行了。这对于常年在外的人来说,没有谷歌套件应用是很不方便的,虽然已近买了新手机,但是决定折腾一下,让这个老手机充当备用机的时候也能充分发挥余热。

所以如果你面临跟我一样的问题,那么这篇文章可能帮到你。

适应范围和要求

首先,说一下这篇文章的适应范围和要求:

本文只适用于MIUI 版本是12.5.1.0的 小米8手机。

由于MIUI不同机型的Android版本和系统软件配置都不相同,所以本文涉及到的方法很可能不能适用其他版本和型号的手机,但是原理是一致的,喜欢折腾的可以自己尝试。另外,本文涉及到刷机和修改系统,有很高风险,不适合小白,使用到的工具也需要一定的经验,不熟悉的同学请先学习相关刷机常识。如果你不理解以下关键字,那么本文可能不适合你:unlock bootloader, TWRP,fastboot,线刷,adb,root。

刷机有风险,折腾需谨慎,数据无价,参考本文的方法代表你自愿为你的设备和数据负责,本文作者不承担你的设备和数据安全责任。

工欲善其事,必先利其器,开始折腾前,需要做一些准备工作。

手机需要unlock bootloader

具体方法方法不是本文重点,请到MIUI相关论坛上自行搜索。unlock这点是必须,本文的方法需要修改system分区文件,不unlock是做不到的。但是不一定需要彻底fastboot重刷系统。另外unlock手机可能会导致保修失效,请慎重考虑,本文不为此负责。为了安全起见,请在折腾前备份好你的数据!切记!切记!

小米手机解锁:申请解锁小米手机

TWRP

因为要修改system分区文件,所以TWRP是必须的,这点不过多解释。关于TWRP是什么,怎么使用也不是本文的重点,请自行搜索。注意本文并不一定需要root手机,但是达到效果类似。当然如果使用root方案比如Magisk也可以达到类似效果,但是root毕竟比非root方法风险更高,本方法对系统的安全影响相对较小。

TWRP: TeamWin - TWRP

Mi 8 TWRP: Download TWRP for dipper

Root App Magisk(非必须):topjohnwu/Magisk

配套的 boot.img

本文方法的关键,一个适用于此手机的,没有 dm-verity 的 boot.img 。上面说到了,这里我们的方法不用root手机,使用TWRP在recovery阶段修改system文件。但是Android 4.4+的系统其实对于system都有一个叫做dm-verity的保护手段,所以即使你使用TWRP在启动阶段修改了system中的文件,手机也没办法启动,系统会强制重启到fastboot状态,你只能重新刷新系统。

使用Magisk套件进行boot分区修改和获取root是最方便的获取修改system文件系统的方法,但是我们实际上并不需要在手机正常状态下的root功能,那怎么办呢?答案就在boot.img里面。跟Magisk套件原理一样,我们也需要修改boot,将其中的关键系统分区校验功能dm-verity关闭掉。

但是修改boot难度很高,且也不太安全,那怎么办呢?其实相关的自动patch工具也不少,但是这里面我推荐一个最简单的办法。常玩刷机的同学可能知道MIUI有一个非官方的EU版系统。即欧版系统,它是在CN版本上修改而成的,所以实际上EU版本的MIUI image中的boot.img都是没有dm-verity的。这样我们只要找一个Android版本相同,MIUI版本近似的EU版本image,解压出其中的boot.img,flash到手机当中,就可以完成system的解锁了。

MIUI EU: xiaomi.eu/community/

MIUI 12 EU: Downloads for : -Android- Generic Device/Other | AndroidFileHost.com | Download GApps, Roms, Kernels, Themes, Firmware and more. Free file hosting for all Android developers.

这里我们使用的是从xiaomi.eu_multi_MI8_V12.0.4.0.QEACNXM_v12-10.zip中解压出来的boot.img

Android Platform Tools

主要就是adb和fastboot工具,调试Android必备,使用方法请自行搜索。

developer.android.com/studio/releases/platform-tools

以及adb进行usb手机连接的驱动:

Universal ADB Drivers

Google 三件套 apk 文件

这个请自行到Apkmirror上寻找,推荐版本越新越好。安装Google套件基本要求至少以下三个应用,GmsCore(Google Play Services),Google框架(Google Services Framework)和Play商店(Google Play Store)。但是参考Global版本系统,如果完全符合Google要求,你可能需要内置更多Google相关的应用,例如Google Ext Service,Share Services等等。需要注意的是,你的apk文件必须架构(armv7a/arm64v8)和Android版本跟你的手机保持一致。如果不确定可以选择universial架构和nodpi。手机的安卓版本请到 设置 - 我的设备 - 全部参数 - Android 版本查看。

Google Service FrameWork: www.apkmirror.com/uploads/?q=google-services-framework
Google Play Service: www.apkmirror.com/uploads/?q=google-play-services
Google Play Store: www.apkmirror.com/uploads/?q=google-play-store

科学上网,不解释,懂的都懂。

本文使用小米8,MIUI升级到最新的12.5.1.0,稳定版系统:

MIUI升级到最新的12.5.1.0

  • TWRP版本: twrp-3.5.2_9-0-dipper
  • Google Play服务版本:com.google.android.gms_21.24.18_(120400-383468479)-212418037_minAPI29(arm64-v8a,armeabi-v7a)(nodpi).apk
  • Google框架版本:com.google.android.gsf_10-29_minAPI29(nodpi).apk
  • Play商店版本:com.android.vending_26.0.65-21_0_PR_382774978-82606510_minAPI21(arm64-v8a,armeabi-v7a,x86,x86_64)(nodpi).apk
  • 去除AVB, dm-verity boot.img取自欧版系统: xiaomi.eu_multi_MI8_V12.0.4.0.QEACNXM_v12-10.zip

正式开始操作

好了,下面我们正式开始,本文的方法因为使用TWRP直接修改手机上的system分区文件,所以理论上可以适用于现有手机,不需要重新刷新的系统,也不需要root。但是限于安全原因,这里我们使用的是全新刷好的MIUI 12.5.1.0的系统。如果你使用现有的系统,那修改后可能需要清除手机的data和cache 。

去掉手机的密码

在正式开始之前,这里建议先去掉手机的密码,因为密码会加密相关分区,当然这里也可以不去掉,现在的TWRP可以支持输入密码后解密相关分区。

重启到fastboot模式

方法是重启手机,并在重启过程中按住音量减键。直到手机上见到这个画面:

重启到fastboot模式

使用 fastboot 加载TWRP

下载,解压,安装好Android Platforms Tools, ADB USB驱动,和TWRP。将TWRP的img文件拷贝到fastboot.exe同目录下。使用usb连接手机和电脑,打开一个cmd窗口,切换到fastboot.exe的目录下,用以下命令运行TWRP:

fastboot boot twrp-3.5.2_9-0-dipper.img
Downloading 'boot.img'                                OKAY [  1.009s]
booting                                               OKAY [  0.047s]
Finished. Total time: 1.069s

这里我们没有选择将TWRP刷入到recovery分区,网上不少教程都这么做,实际上这是没必要的。而且即使将TWRP刷入到recovery了,如果不root手机,MIUI在OTA升级或者其他什么时候也会将其恢复为原来的官方recovery。

正常输入命令后,手机会重启,第一次启动到TWRP会有点慢,稍等一会进入欢迎界面。先选择修改语言到中文,之后滑动解锁进入TWRP主界面,记得不要选择只读挂载system选项,我们就是要编辑system分区。

备份boot, system以及data分区

因为我们即将对系统进行修改,保留一个备份是个好习惯。当然了,如果新刷的系统无所谓此步骤可免。这里建议,即使重刷的机器来折腾,那也至少备份一下boot和system。这样即使哪步失败了,也可以回到fastboot,重新加载TWRP,恢复分区,然后重新来过。

选择备份,勾选boot, system是否备份data自选,然后滑动滑块进行备份。

勾选boot, system

备份需要一定时间,等备份完成。这时候手机已经连接到电脑,在文件浏览器中应该可以看到手机内部存储目录。拷贝到电脑一份,就不怕以后刷机失败了。

重启到fastboot,刷入EU版boot.img

在TWRP中选择重启->bootloader,重启到步骤一的fastboot界面。此步也可以长按电源键,手机重启后,迅速按音量减键进入fastboot界面。

在电脑上,将EU版boot.img放到fastboot.exe同目录下执行以下命令刷新boot:

> fastboot flash boot boot.img
Sending 'boot' (44457 KB)                          OKAY [  1.034s]
Writing 'boot'                                     OKAY [  0.132s]
Finished. Total time: 1.171s

瞬间刷好,然后使用fastboot reboot命令重启,或者长按电源键重启。

这时候,应该可以正常重启到系统,不需要很久。这时,如果你不太需要Sogou输入法,建议换一个别的输入法,因为等下清理文件时我们可能会删掉系统内置的Sogou输入法。

如果系统没能正常重启,那么系统可能直接返回到fastboot界面,或者一直卡着不动。那么我们需要重新找一个版本的boot.img,然后重新执行步骤1-3,刷入一个可用的boot.img。此时如果不想折腾了,也可以在TWRP中选择恢复原来的boot。如果实在找不到,那么TWRP安装Magisk也可以达到目的,详细安装方式情自行网上搜索。

但请注意如果使用Magsik进行system解锁,那么今后就不能卸载Magisk了,否则system会自动恢复,或者直接不能启动。而且Magisk存在意味着系统被root了,一些安全性要求较高的应用会检测到Magisk,从而不能使用。

如果系统正常重启,那么接下来我们还是重新执行一遍1-2步骤,回到TWRP,进行下一阶段的修改。

挂载system和vendor分区

重新回到TWRP之后,我们到挂载中,勾选system和vendor分区:

勾选system和vendor分区

这样我们就挂载了system和vendor,接下来我们就开始hack系统。

清理system分区

这里我们需要使用adb shell来对/system下进行清理,这里需要读者熟练使用linux shell命令。

> adb shell
dipper:/ # 

在修改相关系统文件,安装谷歌框架之前,我们现需要清理一下system分区,为什么呢,因为米8的system分区只有3个G,而MIUI的系统文件把system分区几乎都撑满了:

dipper:/ # df
Filesystem       1K-blocks    Used Available Use% Mounted on
tmpfs              2862376     288   2862088   1% /dev
tmpfs              2862376       0   2862376   0% /mnt
tmpfs              2862376      36   2862340   1% /tmp
/dev/block/sda20    229344     880    228464   1% /cache
/dev/block/sde46    196528  168352     28176  86% /firmware
/dev/block/sda21  55158144 2256104  52902040   5% /data
/dev/block/sde48   3047900 2959712     88188  98% /system_root
/dev/block/sde47   1015944  876872    139072  87% /vendor

而安装google框架,至少需要200M的空间,不清理一下,还真就装不了。看来小米之前给出的理由可能是真的。

这里可能有人问,为什么一定要把GMS框架装到system分区呢?跟之前一样安装在/data不行么?这个事情说起来就比较复杂了,这里还真是Google的限制导致的。现在结论的就是:如果系统是Android 10的实际上是可以,但是只能安装某些旧版本的GMS框架。Android 11因为权限要求的更改,GMS必须运行在/system下,所以彻底不行了。

而部分google应用(比如google地图)的适配现在已经面向了新版本的GMS框架,所以造成这些应用在这种老的GMS框架下运行时会出现一些奇怪的问题。

比如,我曾经尝试在MIUI 12.0.4上手动安装一些旧的GMS框架版本,虽然Play Store可以登录google账号,成功下载安装应用程序。但是Google地图启动的时候会闪退。debug调试原因指向缺少Crontnet库,这个库现在在新的Google地图中不在内置了,而在对应版本的GMS服务中内置。所以,这就导致实际上即使安装了框架,但是一部分应用也是用不了的。

而且,这种老版本GMS会自动升级到新的新版本GMS,一旦升级到最新版本后,就彻底不能支持/data下运行了,GMS服务会因为权限原因不停被杀掉。现象就是,即使你安装好了GMS框架,一段时间后,Play Store也登录不了,各种刚安装好时可以用的应用也都不好使了。

所以现在唯一的办法,就是把最新版本的GMS框架,安装在system分区下。同时还需要hack一些文件文件来打开对应权限。现在Android的权限管理越来越严,即使在system的priv-app下面安装应用,需要对应的描述文件来定义才能打开特殊权限,GMS也不能例外。

好了,还是回到清理/system中来,具体怎么清理呢?这里就要见仁见智了,简单说,就是删掉那些你认为用不到的东西,而且尽量不影响系统。可以在/system/app,/system/data-app和/system/product/app下面找找你不需要用的应用。

这里面推荐几个体积较大且可以安全删掉,如果需要的话都可以用应用商店重装的应用。所以删掉它们是完全无害的:

  • /system/app/SogouInput (搜狗输入法,完全没必要安装在system下面,但删除之前记得在输入法配置里面选择其他输入法,比如讯飞或者百度,否则相关配置会出错,如果需要之后也可以在应用商店重新安装)
  • /system/priv-app/MiuiVideo (小米视频,不需要的话完全可以删掉,需要的话也可以通过应用商店装回来)
  • /system/app/Mipay (小米钱包,完全可以删掉,需要的话可以通过应用商店装回来)

同时你也可以顺便把类似MIUI广告三大件AnalyticsCore,mab,MSA都删掉。

关于具体可以删什么,这里有篇文章不错:

MIUI 11&12系统应用精简列表与功能

验证清理后系统可用

删除完成后,我们重启手机,这里面要验证一下,第一,是否system被我们成功修改了,第二,清理后系统没问题,可以运行。

第二点如果重启成功即可验证。第一点比较麻烦,我们需要在系统中打开USB调试(MIUI开发者模式打开方法和USB调试打开方法请自行搜索),使用adb shell连入,查看一下刚才被我们删掉的文件是否还在,如果还在,那说明我们刚才刷入的boot.img无效,并没有解除dm-verity。这时需要重新寻找一个可用的boot.img,按照1-4的步骤重新刷入。

另外,如果刚才你删除的应用过于关键,那么MIUI可能也不能启动,所以这里我建议一开始先删掉一两个不重要的app,比如Sogou输入法,然后启动一次,看看是否正常,是否真的删掉了,之后在进行更大规模的清理。

到这里,正常情况下系统可以正常启动,且system下的包被正常删掉了。

此时,我们实际上已经可以完全掌控系统了,而且没有进行root。这时候其实你想做什么都可以了。

修改权限文件,安装GMS套件

前文说过,由于MIUI 12.5或者Android 9+修改了权限相关的规则文件,导致即使安装在system分区下priv-app目录中的软件,也需要正确的权限文件描述来打开相应权限才能让应用正确运行。所以我们需要修改对应的文件。

对比Global版本对于Google套件的相关描述文件,我们总共需要修改/添加三个文件:

  • 修改 /system/product/etc/permissions/privapp-permissions-platform.xml
  • 添加 /system/product/etc/sysconfig/google-hiddenapi-package-whitelist.xml
  • 添加 /system/product/etc/sysconfig/google.xml

这三个文件可以从对应(Android 版本相同)MIUI的Global中进行提取(本文使用dipper_global_images_V12.0.2.0.QEAMIXM_20201113.0000.00_10.0_global_b450e91e17.tgz),为了方便同学们,我把他提取出来放到了这里:

mengqin/MIUI-12.5-GMS-permissions-files

之后,我们把GMS,GoogleServicesFramework和Play商店的apk文件安装在/system/product/priv-app文件夹下。

为了简化操作,我们可以在电脑上adb.exe同目录下,建立一个product文件,然后将上述文件路径,建立对应目录,并按照对应的路径放入其中,如下:

product
├─etc
│  ├─permissions
│  │      privapp-permissions-platform.xml
│  │
│  └─sysconfig
│          google-hiddenapi-package-whitelist.xml
│          google.xml
│
└─priv-app
    ├─GmsCore
    │      GmsCore.apk
    │
    ├─GoogleServicesFramework
    │      GoogleServicesFramework.apk
    │
    └─Phonesky
            Phonesky.apk

之后,我们使用如下命令:

> adb push product /system/
product\: 6 files pushed. 34.0 MB/s (184034668 bytes in 5.160s)

便可一次性的刷入进去了。

刷入成功后,即可重启进行验证。祝你好运。

后记

本文的主要原理实际上很简单,关键点有三个:

第一,使用TWRP进行system分区的修改。
第二,使用EU的boot.img绕开system分区的AVB和dm-verity检验。
第三,正确修改GMS所需权限文件。

这里面扩展开一点来说,如果采用root手机的方法的话,上述操作也都可以在手机的系统直接进行,所以实际上有熟悉Magisk插件开发的同学可以尝试写一个插件,但是通用程度可能有限。

这里需要注意的是,米8的12.5.1系统使用的是Android 10,现在大部分12.5的小米手机都使用的是Android 11,这里面安装GMS的方法实际上差别很大。Android 11系统权限更为严格,所以需要更多的权限描述文件,另外,GMS套件也不在安装在/system/product下面,而是安装在/system/或者/system_ext下面。这里需要同学们自行对比近似MIUI版本的Global版本系统的GMS套件来进行修改,这个工作比较复杂。

另外提供一个偷懒的方法,如果你不想研究Android复杂的权限描述文件,这里有个方法可以绕过。但是同时也增加了系统的风险性。

在/vendor/build.prop中,找到这样一行:

ro.control_privapp_permissions=enforce

将enforce改为log后,可以解除priv_app的一切权限限制,改为只log记录权限违反情况。这么修改后,会让一些原来无法运行的priv_app中的应用启动,自启动,甚至常驻内存,修改配置,所以可能会造成一些类似手机更耗电的问题。

另外,在Android 11版本之后,可能需要修改其他目录中的build.prop,而不只是/vendor下面的。

还有,本文GMS套件实际上只安装了GmsCore, GoogleSerivcesFramework和Play商店,这三个是最基本的GMS套件,但是如果你想使用更多google功能,那么你需要内置更多的套件,详细可以操作Global版本的系统。

本文参考:

https://source.android.com/devices/tech/config/perms-whitelist?hl=zh-cn
https://source.android.com/devices/tech/config?hl=zh-cn
https://source.android.com/devices/bootloader/partitions/product-partitions#legacy-oem
https://source.android.com/devices/tech/config/perms-allowlist?hl=zh-cn#adding-allowlists
xiaomi
https://source.android.com/security/verifiedboot/dm-verity?hl=zh-cn
Android 权限的一些细节 - Endv - 博客园
MIUI 11&12系统应用精简列表与功能