wshuo 发表于 2021-5-8 23:45

X活手环的表盘自定义修改

[文章用到的所有工具及软件成品](https://wshuo.lanzoui.com/iYwkRoxznza)
### 前言
前几天我在某宝买了一个智能手环,无奈软件中的表盘太少,所有我想着修改一下app中的资源文件。
### 反编译APK
这里反编译**APK**用apktool工具就可以。
apktool 的版本是`2.4.1`,反编译命令:
```bash
apktool d 安装包名
```
### 文件分析
反编译后:

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210508204951250.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Nob3V6aG91OTcwMQ==,size_16,color_FFFFFF,t_70)

在 `\assets\80x160` 下面有`online` ,`custom`俩个文件夹分布 对应 软件中的`在线表盘`和`自定义表盘`

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210508205202928.jpg)
在线表盘是**bin**文件,也就是二进制文件,无奈以我的能力无法逆向解析其构成(如有大佬弄过还请评论指出),应该需要读java的代码。所以我侧重点在 `custom` 也就是**自定义表盘**的文件夹。
在`views`文件下存放调用图片路径位置, 例如 `0.txt` 文件:
```python
[
{
    "path": "/background/0.png",
    "pos": "0, 0",
    "pictype": "background",
    "itemtype": 254,
    "color": "Black",
    "show_num": 1,
    "para": 0,
    "w": 80,
    "h": 160
},
{
    "path": "/bluetooth/0",
    "pos": "2, 2",
    "pictype": "bluetooth",
    "itemtype": 8,
    "color": "White",
    "show_num": 1,
    "para": 11,
    "w": 8,
    "h": 10
},
{
    "path": "/battery/0",
    "pos": "64, 3",
    "pictype": "电池",
    "itemtype": 11,
    "color": "White",
    "show_num": 1,
    "para": 0,
    "w": 13,
    "h": 8
},




{
    "path": "/time/0",
    "pos": "47, 14",
    "pictype": "时",
    "itemtype": 4,
    "color": "White",
    "show_num": 2,
    "para": 8,
    "w": 32,
    "h": 25
},

{
    "path": "/time/0",
    "pos": "47, 43",
    "pictype": "分",
    "itemtype": 5,
    "color": "White",
    "show_num": 2,
    "para": 5,
    "w": 32,
    "h": 25
},

{
    "path": "/date/0",
    "pos": "40, 73",
    "pictype": "日期",
    "itemtype": 18,
    "color": "White",
    "show_num": 5,
    "para": 6,
    "w": 40,
    "h": 10
},
{
      "path": "/am_pm/0",
      "pos": "65, 85",
      "pictype": "AMPM",
      "itemtype": 19,
      "color": "255, 255, 255",
      "show_num": 1,
      "para": 0,
      "w": 13,
      "h": 7
    },
    {
      "path": "/slash/0",
      "pos": "58, 73",
      "pictype": "图片",
      "itemtype": 253,
      "color": "White",
      "show_num": 1,
      "para": 0,
      "w": 0,
      "h": 0
      }
]
```
列表中包含字典,每一个字典都是一个图片,可以用来显示蓝牙图标,电源图标,小时,分钟等等。。
|字段|说明|
|------|------|
|path|调用的图片路径|
|pos|图片位置|
|pictype|说明,这个值可以任意写|
|itemtype|用来识别对象的关键字段,后面详细解释|
|color|没啥用,任意填|
|show_num| 显示的数量,例如`时`显示的是俩位,那么就是2,而蓝牙图标一般以一个,那么就是1|
|para|未知,不过没什么影响|
|w|图片总的宽度,因为要乘上show_num值|
|h|图片高度,纵向|
多个图片的`path`都是指定到目录,图片的名字从零开始依次索引。

这里着重说一下`slash`文件夹的下面的图片,这个图片是在息屏后开始的点亮的一瞬间使用,而且这个图片的w和h总是写0,但是实际的宽度和高度是图片的宽度和高度。
另外说明一下`date`文件夹,这个是用来显示日期的,显示5位是因为中间一位显示的是分隔符,分隔符显示的是`12.png`, 而有前俩位显示时间,后俩位显示的是日期。
### itemtype
前面我说了这个是识别类型的关键字段,这个字段用来区分是显示的时间,日期,蓝牙图标等等。所以这个字段是很重要的。而我们需要知道什么数值对应什么意思图标。
这里我用的反编译`dex`到`jar`包,将**apk**的后缀改成**zip**然后直接解压便可得到**dex**文件。然后使用`d2j-dex2jar.bat`反编译成**jar**包,然后用`jd-gui`打开**jar**包,里面有一个类就是定义**itemtype**类的。
```java
public class ItemType {
public static final int ITEM_AMPM = 19;
public static final int ITEM_ANIMATION = 10;
public static final int ITEM_BACKGROUND = 254;
public static final int ITEM_BATTERY = 11;
public static final int ITEM_BLUETOOTH = 8;
public static final int ITEM_DATE = 18;
public static final int ITEM_DAY = 3;
public static final int ITEM_DISTANCE = 13;
public static final int ITEM_HEARTRATE = 9;
public static final int ITEM_HOUR = 4;
public static final int ITEM_HOUR_DIGIT = 15;
public static final int ITEM_HOUR_TEN = 14;
public static final int ITEM_KCAL = 12;
public static final int ITEM_MINUTE = 5;
public static final int ITEM_MINUTE_DIGIT = 17;
public static final int ITEM_MINUTE_TEN = 16;
public static final int ITEM_MONTH = 2;
public static final int ITEM_SHOE = 253;
public static final int ITEM_STEP = 6;
public static final int ITEM_WEEK = 7;
public static final int ITEM_YEAR = 1;
}

```
通过这上面的英文,可以大致理解什么数值表示什么。
这里说一下我用到的东西,例如动画`ITEM_ANIMATION=10`,文件夹下面的图片就是从**0.png**图片开始遍历,一直遍历到最后从而形成动画,是每一秒刷新一次。

### 表盘资源文件寻找   
这里自定义表盘就是新建 txt文件,然后写入对应位置和图片路径,当然图片资源是不可能自己画的,[网址](https://amazfitwatchfaces.com/ucp/309443)。这个网站有各个手环平台的资源文件,下载下来的格式是bin, 而要解析成图片也是需要一下工具的,例如我解析的是`mi-band-5`的资源文件,用到的工具是`MiBandWFTool_2.1.6`。

### 制作表盘工具
由于反复调节图片的位置太过费劲,我弄得头疼,所有我用opencv写了一个简单的工具,用来实时显示图片位置,更加直观。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210508225753403.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Nob3V6aG91OTcwMQ==,size_16,color_FFFFFF,t_70)
index表示切换各个资源,在切换的时候对应的标题会改变,用来显示当前修改的是什么资源的位置,当然如果的txt中资源顺序和我的不一致可以修改78行代码:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210508230439140.png)

而PosX是和横向位置,PosY纵向位置,W是单个图片的宽度,注意这里我做了转换,否者按照配置文件的w是表示总的横向宽度,H是单个图片的高度,按q退出。这里每一次调节都会实时修改txt文件。但是不会改变真正的图片大小。如果需要修改图片大小可以使用我写的`convert.py`的脚本。修改实际图片大小也能有效的压缩表盘文件的大小。
### 打包签名
添加自定义表盘资源文件后,就可以对app进行打包,同样使用 apktool,命令:
```bash
apktool b 安装包文件夹
```
然后会在**dist**文件夹下面生成一个**apk**,而这个apk也是不能安装的,需要签名,签名使用**signapk.jar**然后生成的**apk**才可以安装到手机上。

### 效果

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210508232855169.jpg)

后面俩个是我添加进去的表盘。这里我删除了一个狗的表盘,因为我当时以为是表盘文件太多导致报错buffer size不够,后来发现是资源文件过大导致的。
### 其它一些细节
1. 我写的表盘调整工具,按q退出后,会在**effect**,和**cover**文件中写入图片。这俩个图片也是重要的,会在APP自定义表盘中显示出来图片,否者图片是空白或者找不到你自定义的表盘。
2. 资源文件不要太大,并且调节完表盘最好使用**convert.py**文件调节一下图片的大小,否者会导致上传表盘文件失败。
3. 图片透明边缘过小会导致数字粘连,是因为**show_num**,图片拼接导致的。这种问题可以使用我写的`add_border.py`来填充透明边缘,这样拼接后的图片也不会显示数字太近。
4. 更多的细节需要反复调节代码和反复修改app才能知道,毕竟我写代码也花了接近一天的时间,不可能把所有细节描述清楚。

shinexieonline 发表于 2021-5-9 00:03

大神作品!

吾爱蛋蛋 发表于 2021-5-9 00:07

华为B3手环可以吗

雾都孤尔 发表于 2021-5-9 00:19

自己动手绝对丰衣足食。

amor0507 发表于 2021-11-12 16:36

非常感谢,学习一下
页: [1]
查看完整版本: X活手环的表盘自定义修改