feat(GPS): 添加空转GPS模拟服务与动态源切换逻辑
1. 新增IdleGpsService,在空转模式下定时发送模拟GPS坐标(默认北京) 2. LocationActivity支持动态切换GPS源:空转时使用IdleGpsService,正常时使用MainService 3. 优化onResume逻辑,确保空转状态变更时GPS监听源实时同步 4. 统一反注册逻辑,避免多服务监听冲突
This commit is contained in:
@@ -25,6 +25,7 @@ import cc.winboll.studio.positions.MainActivity;
|
||||
import cc.winboll.studio.positions.R;
|
||||
import cc.winboll.studio.positions.adapters.PositionAdapter;
|
||||
import cc.winboll.studio.positions.models.PositionModel;
|
||||
import cc.winboll.studio.positions.services.IdleGpsService;
|
||||
import cc.winboll.studio.positions.services.MainService;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -340,17 +341,38 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新GPS监听源(根据空转状态自动切换)
|
||||
*/
|
||||
private void refreshGpsListener() {
|
||||
LogUtils.d(TAG, "refreshGpsListener invoke");
|
||||
// 统一注销旧监听(防止重复注册)
|
||||
IdleGpsService.getInstance().unregisterGpsUpdateListener(mGpsUpdateListener);
|
||||
if (mMainService != null) {
|
||||
try { mMainService.unregisterGpsUpdateListener(mGpsUpdateListener); } catch (Exception e) {}
|
||||
}
|
||||
// 重新注册正确的监听
|
||||
registerGpsListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册GPS监听
|
||||
*/
|
||||
private void registerGpsListener() {
|
||||
LogUtils.d(TAG, "registerGpsListener invoke");
|
||||
if (isFinishing() || isDestroyed() || mMainService == null || mGpsUpdateListener == null) {
|
||||
if (isFinishing() || isDestroyed() || mGpsUpdateListener == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mMainService.registerGpsUpdateListener(mGpsUpdateListener);
|
||||
LogUtils.d(TAG, "GPS监听注册成功");
|
||||
if (App.isAppIdleRunning()) {
|
||||
IdleGpsService.getInstance().registerGpsUpdateListener(mGpsUpdateListener);
|
||||
LogUtils.d(TAG, "空转GPS监听注册成功");
|
||||
} else {
|
||||
if (mMainService != null) {
|
||||
mMainService.registerGpsUpdateListener(mGpsUpdateListener);
|
||||
LogUtils.d(TAG, "系统GPS监听注册成功");
|
||||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
LogUtils.e(TAG, "GPS注册异常 : " + e.getMessage());
|
||||
}
|
||||
@@ -361,12 +383,20 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit
|
||||
*/
|
||||
private void unregisterGpsListener() {
|
||||
LogUtils.d(TAG, "unregisterGpsListener invoke");
|
||||
if (mMainService == null || mGpsUpdateListener == null) {
|
||||
if (mGpsUpdateListener == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mMainService.unregisterGpsUpdateListener(mGpsUpdateListener);
|
||||
LogUtils.d(TAG, "GPS监听反注册成功");
|
||||
// 尝试从空转服务注销
|
||||
IdleGpsService.getInstance().unregisterGpsUpdateListener(mGpsUpdateListener);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
// 尝试从主服务注销
|
||||
if (mMainService != null) {
|
||||
mMainService.unregisterGpsUpdateListener(mGpsUpdateListener);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
LogUtils.e(TAG, "GPS反注册异常 : " + e.getMessage());
|
||||
}
|
||||
@@ -404,6 +434,7 @@ public class LocationActivity extends WinBoLLActivity implements IWinBoLLActivit
|
||||
super.onResume();
|
||||
LogUtils.d(TAG, "onResume invoke");
|
||||
refreshIdleStatusTitle();
|
||||
refreshGpsListener(); // 根据当前空转状态刷新GPS源
|
||||
|
||||
if (isServiceBound.get() && mMainService != null && !isAdapterInited.get()) {
|
||||
syncDataFromMainService();
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package cc.winboll.studio.positions.services;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import cc.winboll.studio.positions.models.PositionModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 空转GPS模拟服务
|
||||
* 在应用空转模式下,模拟系统GPS服务向客户端发送坐标数据
|
||||
*/
|
||||
public class IdleGpsService {
|
||||
|
||||
private static final long MOCK_INTERVAL_MS = 1000; // 模拟坐标更新间隔
|
||||
private static IdleGpsService instance;
|
||||
private final List<MainService.GpsUpdateListener> listeners = new ArrayList<>();
|
||||
private final Handler handler;
|
||||
private final Runnable updateRunnable;
|
||||
private final PositionModel mockPosition;
|
||||
private boolean isRunning;
|
||||
|
||||
private IdleGpsService() {
|
||||
handler = new Handler(Looper.getMainLooper());
|
||||
mockPosition = new PositionModel();
|
||||
mockPosition.setPositionId("mock_idle_pos");
|
||||
mockPosition.setMemo("空转模拟坐标");
|
||||
// 默认模拟坐标:北京
|
||||
mockPosition.setLatitude(39.9042);
|
||||
mockPosition.setLongitude(116.4074);
|
||||
|
||||
updateRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isRunning) {
|
||||
notifyListeners(mockPosition);
|
||||
handler.postDelayed(this, MOCK_INTERVAL_MS);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static IdleGpsService getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new IdleGpsService();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册GPS监听
|
||||
*/
|
||||
public void registerGpsUpdateListener(MainService.GpsUpdateListener listener) {
|
||||
synchronized (listeners) {
|
||||
if (!listeners.contains(listener)) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
}
|
||||
if (!isRunning) {
|
||||
startMockUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销GPS监听
|
||||
*/
|
||||
public void unregisterGpsUpdateListener(MainService.GpsUpdateListener listener) {
|
||||
synchronized (listeners) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
if (listeners.isEmpty() && isRunning) {
|
||||
stopMockUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void startMockUpdate() {
|
||||
if (isRunning) return;
|
||||
isRunning = true;
|
||||
// 通知状态变更
|
||||
notifyStatusChange("空转GPS服务已启动");
|
||||
handler.post(updateRunnable);
|
||||
}
|
||||
|
||||
private void stopMockUpdate() {
|
||||
isRunning = false;
|
||||
handler.removeCallbacks(updateRunnable);
|
||||
notifyStatusChange("空转GPS服务已停止");
|
||||
}
|
||||
|
||||
private void notifyListeners(PositionModel pos) {
|
||||
synchronized (listeners) {
|
||||
for (MainService.GpsUpdateListener listener : listeners) {
|
||||
listener.onGpsPositionUpdated(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyStatusChange(String status) {
|
||||
synchronized (listeners) {
|
||||
for (MainService.GpsUpdateListener listener : listeners) {
|
||||
listener.onGpsStatusChanged(status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRunning() {
|
||||
return isRunning;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user