2023年8月14日
说明
运动模拟器是基于Xposed框架的定位模拟应用。它胜过其他应用的点在于对以下功能的支持:
- 传感器和基站数据的收集和模拟
- 路径修改和混淆
- 同时对root和非root设备的支持
- 地图和坐标系转化
下载
此文章提供了几种下载方式,你可以决定从哪个链接下载。
开始下载
发行注记v1.2.2
漏洞修复 - 导出(分享)已记录的数据时崩溃 - 记录界面和模拟界面的视觉错误 -
在基于Compose的页面中缺少导航到上一层级的提示
开始使用
要开始使用运动模拟器,只需以下几个步骤。
选择合适的插件
不同插件以不同的方式实现运动模拟器的部分或全部功能。根据条件选择合适的插件。
| 插件名 | 平台 | 实现方式 | 适用于 | 位置模拟 | 传感器模拟 | 基站模拟 |
|---|---|---|---|---|---|---|
| 模拟位置插件 | 原生Android | 不屏蔽模拟位置的应用 | ✅🅱️ | ❎ | ❎ | |
| Websocket插件 | Xposed | 大部分应用 | ✅🅰️ | ✅ | ✅ | |
| 内容提供器插件 | Xposed | 大部分目标SDK不高于30的应用 | ✅🅰️ | ✅ | ✅ |
激活插件
在软件主界面,选择找不到插件卡片,进入插件管理器。
从已禁用列表中,点击需要的插件,开始下载。下载完成后,可能需要给予软件安装未知应用的权限。软件会自动要求安装下载好的插件。
将插件拖放到已启用列表,激活该插件。
插件指定设置
基于Xposed的插件需要在你使用的框架中进行额外设置。
模拟位置插件需要按照内部的提示进行额外设置。
绘制路径
回到主界面。选择绘制路径卡片。第一次使用,需要设置地图选项。
选择合适的地图
对于大陆用户,如果你不知道自己在做什么,请选择高德地图。
注意,地图已以你的粗略位置为中心。点击屏幕下方的新路径按钮,开始路径创建。软件提供两种方法绘制新路径。
手绘
不妨移动地图,寻找大致区域。可以点击屏幕上方的搜索按钮,快速跳转到兴趣点。
要开始手绘路径,选择屏幕下方的绘制路径按钮,然后点击选择。与地图交互将不能移动地图,而是在地图上留下痕迹。
需要撤销上一次操作,点击屏幕下方的撤销按钮。需要清除路径,点击清除按钮。
绘制完成后,点击屏幕下方的返回按钮。
GPS采样
要记录实际位置为路径存档,点击屏幕下方的GPS采样。
寻找信号
找到卫星信号较好的地点,通常是户外开阔地。软件将在信号较优时开始记录。
要暂停记录,点击屏幕下方的暂停按钮。要恢复记录,点击继续按钮。要撤销至上次暂停的状态,点击撤销按钮。
完成记录后,点击暂停按钮,然后点击返回按钮。
开始模拟
回到主界面。选择模拟卡片。根据需要,配置路径、重复次数、速度等参数。在对配置感到自信之后,点击屏幕下方的开始模拟按钮。
使用传感器数据
开始记录
在主界面,选择记录卡片。选择需要的传感器类型。点击继续。软件生成使用的传感器对应的图表。在记录完成后,点击屏幕底部的停止按钮。不使用停止按钮而直接返回上一界面,将舍弃记录好的数据。
合适的数据
不同软件算法不同。如果你不知道自己在做什么,通常以步频为标准。回到主页,选择管理卡片,在传感器页面可以找到记录。步频的估计速度应接近模拟时的目标速度。
重放方式
重放时,运动模拟器对数据有特殊处理。对于时间不够长的记录,将重复已有片段。对与目标速度不匹配的步频,将加速或减速该片段。这样的操作可能产生不自然的数据。
讨论
传感器模拟是经过最少测试的功能。大部分软件的检测手段不是很强。相反,手段强的软件最好做专门的适配。
给路径添加随机性
在主界面,选择管理卡片。导航到路径页面。选择要编辑的路径。在随机因子中,点击新建,选择随机因子。展开新建的随机因子。随机因子的名称是任何不含空格的字母组合。因子的图像反应其结果的概率分布。

图像的工作方式是,在横轴随机选择一个点,在曲线上对应的纵坐标就是计算结果。
点击新建,在旋转、缩放和平移中选择需要的变换。
旋转
从加盐菜单中选择旋转。展开该变换。点击右侧的Σ按钮,选择使用输入。在弧度制角度输入框内,输入以下文本。
2 * pi * x
为什么
pi = π。* = ×。在弧度制角度中,2π是一周。x的范围是[0, 1]。这个随机变换至多让路径旋转一周。
平移
从加盐菜单中选择平移。展开该变换。在x和y输入框内输入以下文本。
x * 10 ^ -4
为什么
^是指数运算符。10 ^ -4表示十的负四次幂。这个随机变换至多让路径沿纬线方向平移十的负四次方度。
缩放
从加盐菜单中选择缩放。展开该变换。在x轴比例中输入以下内容。
e ^ -x
为什么
e是自然对数的底数。这样做只是好玩。贡献代码
克隆项目
从GitHub克隆项目源代码。
git clone https://github.com/zhufucdev/MotionEmulator
main为开发分支,在达到稳定后合并进stable。不接受提交至stable分支的拉取请求。
下载和配置Android Studio
这个项目十分激进。最新的Android Studio Cancary被用来编写和调试这个项目。你可以从Android Developers获得一份它的副本。请安装最新的编译工具和SDK。下表是经过测试的工具版本。
| 名称 | 版本号 |
|---|---|
| Android Studio | Android Studio Iguana 2023.2.1 Canary 1 |
| SDK Build Tools | 34 |
| SDK Platforms | 34 revision 2 |
| JDK | Amazon Corretto 17 |
配置项目
用Android
Studio打开克隆的项目。如果没有自动同步,点击右上角的Sync Project with Gradle Files按钮。
环境变量
在根目录下新建local.properties。所需字段如下表所示。
| 名称 | 格式 | 说明 |
|---|---|---|
| sdk.dir | 文件系统路径 | Android SDK文件夹根目录 |
| amap.web.key | 32位十六进制数 | 高德地图Web API密钥·文档 |
| AMAP_SDK_KEY | 32位十六进制数 | 高德地图Android SDK密钥·文档 |
| GCP_MAPS_KEY | /[a-zA-Z0-9_]*/ | 谷歌地图SDK密钥·文档 |
更新服务(可选)
运动模拟器主程序和模拟位置插件具有自检查更新功能。如果你希望发布自己的运动模拟器发行版,可自建服务器。在app和mock_location_plugin目录下创建server.properties。填入以下字段。
| 名称 | 格式 | 说明 |
|---|---|---|
| PRODUCT | 无空格字符串 | 用于自索引的项目ID |
| SERVER_URI | HTTP URL | 服务器地址。项目使用的Ktor仅支持HTTP(S)协议。 |
要自建服务器,就要实现特定的RESTful API。参考我的实现。
代码规范及注意事项
在提交前,至少在推送前,请留意IDE的警告,特别是对冗余引入(unused import directive)的警告。
请保持提交的代码被正确格式化。统一使用4空格缩进。单行100字符。禁止大量无意义空行。
如果有破坏性更改(breaking changes),例如修改了stub API的参数,请修改或添加文档。
接受大规模重构,当且仅当新的实现更加规范或便于维护。
大规模重构
大规模重构,是指重新实现了应用框架,因为原先的框架不是最佳实践。前端的大规模重构可能是改变了主页面的整理方式。后端的大规模重构可能是重新实现了通讯桥。
单元测试
该项目对单元测试没有强制要求。仅在自动化比手动测试节约时间时编写和运行测试,例如进程间通信。该项目不以单元测试的通过率为标准评价拉取请求的质量。
界面设计
请遵循M3设计指南。尽可能使用Jetpack Compose编写新页面。UI美观,UX流畅、符合直觉。
请使用ViewModel或遵循其设计模式(designing pattern),注意资源回收、作用域和生命周期。
页面相关的文件,整理在.ui包下。一个Activity衍生的不同Fragment或Composable,整理在同一子目录下。
扩展函数
避免使用全局扩展。请使用DSL模式限制作用域。
Do
fun String.toInt(): Int {...} Don't
fun parseInt(str: String): Int {...} 将相关的扩展整理在同一个文件。避免Utility.kt。

