写在前面
这几天发现小米手机自带的锁屏画报/小米画报中的 ACG 壁纸很好看。所以想办法提取了一下收藏用。
随便来几张看看 API 的效果。
壁纸路径
小米画报的版本为 M920090800-S
。
查了查资料发现小米画报的壁纸缓存路径为 /data/data/com.mfashiongallery.emag/files/img_cache/
。但是这个路径并不能通过常规方式去访问。需要同时满足下列条件:
- 需要 ROOT 权限
- 使用类似 ES, RE 这样的浏览器访问,或者使用 adb 调试工具去访问。
手动提取
通过 adb 提取
adb 即 Android Debug Bridge。在 Windows 上安装好 adb 后使用 Powershell运行下面的命令。就可以把所有的缓存文件拷贝到当前目录的 wallpaper
目录下。
adb root
adb pull /data/data/com.mfashiongallery.emag/files/img_cache wallpaper
Code language: PowerShell (powershell)
提取后处理
提取出来的文件全部没有后缀,但是通过查看文件头可以确定是 JPEG 格式文件,通过修改后缀为 .jpg
即可打开。
文件大致有两种命名规律,能够被下列正则表达式中的其中一个匹配到。
^home_page_I[0-9]+_.{3}$
^I[0-9]+$
通过查看文件的大小可以猜测第一种规律对应的文件画质较高,而第二种规律对应文件画质较低。所以我们真正需要的其实是符合第一种命名规律的文件。
自动提取
通过观察发现缓存目录中的文件并不会一直累积下去,所以不能通过类似几天一收集的方式去提取,我们编写一个 Andorid 程序去自动提取。不过本文不提供程序下载,但是会说明一些编写程序时的思路和注意事项。
思路
观察猜测文件名能被 ^home_page_I[0-9]+_.{3}$
成功匹配的文件为高清的壁纸原图。每当一个新的壁纸被设置,就会出现对应的符合上述规律的文件。
那么我们就可以监控缓存目录的动向,一旦某个文件被访问,我们检查被读取的文件名是否符合上述规律,如果符合则拷贝到另外的位置。
为什么不去监控创建呢?因为我在测试过程中发现监控创建的话有时候可能会拷贝到大小为 0KB 的文件、改为监控读取之后暂时还没发现类似的情况。
同一个文件可能被多次读取,但显然我们只需要拷贝一次。所以在拷贝前计算一下文件的 HASH,如果计算出来的 HASH 之前没有遇到过,就拷贝,拷贝完成后存储这个 HASH。如果之前遇到过则忽视即可。
我们不能将提取工作放到 Activity
中,因为一旦程序到后台 Activity
就会被挂起,提取工作也就停止了。所以我们需要在 Activity
中启动一个 Service
,通过将我们的程序添加到白名单中防止被杀后台。
注意事项
- 监控目录通过
FileObserver
实现,https://developer.android.com/reference/android/os/FileObserver。 - 回调函数
FileObserver.onEvent(int eventID, String filename)
的第二参数filename
有可能是null
,需要注意。 - 程序需要 ROOT 权限。
- 拷贝文件前需要修改小米画报目录及其目录内文件的权限为 755,拷贝的目标目录的权限也要设为 755,即
chmod 755 -R originDir targetDIr
。