Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
3. 历史记录
4. 位置搜索
5. 直接输入坐标
6. 通过 adb 远程设置坐标(无需操作 UI,适合脚本与自动化场景,命令示例见下文「通过 adb 设置坐标」一节)

## 截图
![joystick.jpg](./docs/images/joystick.jpg)
Expand All @@ -63,6 +64,37 @@
2. 启动影梭,赋予相关权限
3. 单击地图位置,然后点击启动按钮

## 通过 adb 设置坐标
  在按上述步骤启动定位服务(点击启动按钮、通知栏出现影梭常驻通知)之后,可以通过 adb 直接注入经纬度,方便脚本化、自动化等场景使用。GPS 与 NETWORK 两个 provider 会在 100ms 内同步刷新,摇杆的当前位也会一并更新。

命令格式:

```bash
adb shell am broadcast -p com.zcshou.gogogo \
-a com.zcshou.gogogo.action.SET_LOCATION \
--ed lat <纬度> --ed lng <经度> [--ed alt <海拔>]
```

参数说明:

- `lat` / `lng`:必填,WGS84 经纬度,类型为 `double`,因此 adb 端必须使用 `--ed`(extra double),写成 `--ef` 或 `--ei` 会被忽略
- `alt`:可选,海拔(米),缺省时沿用当前值
- `-p com.zcshou.gogogo`:显式指定包名,避免在 Android 13+ 上被隐式广播限制拦截

示例(注入上海外滩坐标):

```bash
adb shell am broadcast -p com.zcshou.gogogo \
-a com.zcshou.gogogo.action.SET_LOCATION \
--ed lat 31.2304 --ed lng 121.4737 --ed alt 10
```

注意:

- 服务必须先通过 APP UI 启动一次,receiver 才会注册;服务被销毁后该通道随之失效
- 必须在系统设置 → 开发者选项中将"选择模拟位置应用"设为本 APP,否则系统不会接受 mock 位置
- 经纬度的合法范围会做基础校验(`lat ∈ [-90, 90]`,`lng ∈ [-180, 180]`),越界将被忽略并在日志中提示

## 文档
&emsp;&emsp;由于本人并不是做移动开发的,很多功能代码写的都比较差。我也第一次写 Android APP,目前还处在学习中。。。此外,就一个简单的 APP,应该也不需要啥文档,开发过程中遇到的一些问题,我一般都会记录在个人博客中,具体参见:https://blog.csdn.net/zcshoucsdn/category_10559121.html

Expand Down
48 changes: 48 additions & 0 deletions app/src/main/java/com/zcshou/service/ServiceGo.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ public class ServiceGo extends Service {
private NoteActionReceiver mActReceiver;
// 摇杆相关
private JoyStick mJoyStick;
// adb 远程设位通道:通过 am broadcast 注入坐标
// 用法: adb shell am broadcast -a com.zcshou.gogogo.action.SET_LOCATION \
// --ed lat 31.2304 --ed lng 121.4737 [--ed alt 10]
public static final String ACTION_SET_LOCATION = "com.zcshou.gogogo.action.SET_LOCATION";
public static final String EXTRA_LAT = "lat";
public static final String EXTRA_LNG = "lng";
public static final String EXTRA_ALT = "alt";
private AdbLocationReceiver mAdbReceiver;

private final ServiceGoBinder mBinder = new ServiceGoBinder();

Expand All @@ -83,6 +91,8 @@ public void onCreate() {
initNotification();

initJoyStick();

initAdbReceiver();
}

@Override
Expand All @@ -108,6 +118,13 @@ public void onDestroy() {
removeTestProviderGPS();

unregisterReceiver(mActReceiver);
if (mAdbReceiver != null) {
try {
unregisterReceiver(mAdbReceiver);
} catch (IllegalArgumentException e) {
XLog.e("SERVICEGO: ERROR - unregister mAdbReceiver");
}
}
stopForeground(STOP_FOREGROUND_REMOVE);

super.onDestroy();
Expand Down Expand Up @@ -307,6 +324,37 @@ private void setLocationNetwork() {
}
}

private void initAdbReceiver() {
mAdbReceiver = new AdbLocationReceiver();
IntentFilter filter = new IntentFilter(ACTION_SET_LOCATION);
// target=32, 暂不需要 RECEIVER_EXPORTED 显式 flag;后续升 33+ 再加
registerReceiver(mAdbReceiver, filter);
}

public class AdbLocationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent == null || !ACTION_SET_LOCATION.equals(intent.getAction())) {
return;
}
// lat/lng 必填;alt 可缺省,沿用当前值
if (!intent.hasExtra(EXTRA_LAT) || !intent.hasExtra(EXTRA_LNG)) {
XLog.e("SERVICEGO: ADB - missing lat or lng extra");
return;
}
double lat = intent.getDoubleExtra(EXTRA_LAT, mCurLat);
double lng = intent.getDoubleExtra(EXTRA_LNG, mCurLng);
double alt = intent.getDoubleExtra(EXTRA_ALT, mCurAlt);
if (lat < -90.0 || lat > 90.0 || lng < -180.0 || lng > 180.0) {
XLog.e("SERVICEGO: ADB - invalid lat/lng " + lat + "," + lng);
return;
}
XLog.d("SERVICEGO: ADB - setPosition lng=" + lng + " lat=" + lat + " alt=" + alt);
// 复用 UI 路径:会同步推送给 GPS/NETWORK provider 并刷新摇杆当前位
mBinder.setPosition(lng, lat, alt);
}
}

public class NoteActionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Expand Down