修复实时距离显示问题

This commit is contained in:
ZhanGSKen
2025-10-01 02:14:10 +08:00
parent f5b2500f06
commit 80424c523d
4 changed files with 766 additions and 745 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Tue Sep 30 13:02:23 GMT 2025 #Tue Sep 30 18:06:22 GMT 2025
stageCount=4 stageCount=4
libraryProject= libraryProject=
baseVersion=15.0 baseVersion=15.0
publishVersion=15.0.3 publishVersion=15.0.3
buildCount=9 buildCount=10
baseBetaVersion=15.0.4 baseBetaVersion=15.0.4

View File

@@ -22,7 +22,7 @@ public class PositionModel extends BaseBean {
double latitude; double latitude;
// 位置备注(空值时显示“无备注”) // 位置备注(空值时显示“无备注”)
String memo; String memo;
// 定位点与指定点实时距离大小 // 定位点与指定点实时距离长度
double realPositionDistance; double realPositionDistance;
// 是否启用实时距离计算 // 是否启用实时距离计算
boolean isEnableRealPositionDistance; boolean isEnableRealPositionDistance;

View File

@@ -8,6 +8,7 @@ package cc.winboll.studio.positions.services;
import android.app.Service; import android.app.Service;
import android.content.Intent; import android.content.Intent;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
@@ -38,21 +39,20 @@ public class DistanceRefreshService extends Service {
public static final long REFRESH_INTERVAL = 5000; // 5秒刷新一次 public static final long REFRESH_INTERVAL = 5000; // 5秒刷新一次
public static final int MSG_UPDATE_DISTANCE = 1001; public static final int MSG_UPDATE_DISTANCE = 1001;
public static final String KEY_POSITION_ID = "key_position_id"; public static final String KEY_POSITION_ID = "key_position_id";
public static final String KEY_DISTANCE_TEXT = "key_distance_text";
public static final String KEY_DISTANCE_COLOR = "key_distance_color";
// 核心成员变量Java7明确泛型初始化 // 核心成员变量Java7明确泛型初始化
private Timer mDistanceTimer; private Timer mDistanceTimer;
private Handler mMainHandler; private Handler mMainHandler;
private PositionModel mCurrentGpsPosition; private PositionModel mCurrentGpsPosition;
private ArrayList<PositionModel> mPositionList; private ArrayList<PositionModel> mPositionList; // 持有Adapter传递的原列表引用
private ArrayList<PositionTaskModel> mAllPositionTasks; private ArrayList<PositionTaskModel> mAllPositionTasks;
private Map<String, Integer> mVisibleDistanceViewTags = new HashMap<String, Integer>(); private Map<String, Integer> mVisibleDistanceViewTags = new HashMap<String, Integer>();
private OnDistanceUpdateReceiver mUpdateReceiver; private OnDistanceUpdateReceiver mUpdateReceiver;
private boolean isPositionListSynced = false; // 新增:标记位置列表是否已同步
// 数据同步与消息接收接口Activity/Adapter实现 // 数据同步与消息接收接口Activity/Adapter实现
public interface OnDistanceUpdateReceiver { public interface OnDistanceUpdateReceiver {
void onDistanceUpdate(String positionId, String distanceText, int distanceColor); void onDistanceUpdate(String positionId); // 简化仅传递位置ID
int getColorRes(int resId); int getColorRes(int resId);
} }
@@ -75,13 +75,13 @@ public class DistanceRefreshService extends Service {
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
super.handleMessage(msg); super.handleMessage(msg);
if (msg.what == MSG_UPDATE_DISTANCE && mUpdateReceiver != null) { if (msg.what == MSG_UPDATE_DISTANCE && mUpdateReceiver != null) {
// 解析消息Java7显式调用getData(),避免链式调用) // 解析消息仅获取位置ID
String positionId = msg.getData().getString(KEY_POSITION_ID); Bundle data = msg.getData();
String distanceText = msg.getData().getString(KEY_DISTANCE_TEXT); String positionId = data.getString(KEY_POSITION_ID);
int distanceColor = msg.getData().getInt(KEY_DISTANCE_COLOR); if (positionId != null) {
LogUtils.d(TAG, "接收消息→转发更新位置ID=" + positionId + ",距离文本=" + distanceText); LogUtils.d(TAG, "接收消息→转发更新位置ID=" + positionId);
mUpdateReceiver.onDistanceUpdate(positionId);
mUpdateReceiver.onDistanceUpdate(positionId, distanceText, distanceColor); }
} }
} }
}; };
@@ -117,7 +117,7 @@ public class DistanceRefreshService extends Service {
mDistanceTimer.scheduleAtFixedRate(new TimerTask() { mDistanceTimer.scheduleAtFixedRate(new TimerTask() {
@Override @Override
public void run() { public void run() {
LogUtils.d(TAG, "定时器触发→开始计算距离,可见位置数量=" + mVisibleDistanceViewTags.size()); LogUtils.d(TAG, "定时器触发→开始计算距离,位置列表同步状态=" + isPositionListSynced);
calculateAndSendDistanceUpdates(); calculateAndSendDistanceUpdates();
checkAndTriggerTasks(); checkAndTriggerTasks();
} }
@@ -125,75 +125,47 @@ public class DistanceRefreshService extends Service {
} }
/** /**
* 计算距离并发送UI更新消息 * 核心修改计算距离并更新到mPositionList仅发送位置ID通知
* Java7使用迭代器遍历Map替代forEach Lambda,显式空判断 * Java7使用迭代器遍历显式空判断
*/ */
private void calculateAndSendDistanceUpdates() { private void calculateAndSendDistanceUpdates() {
// 无可见控件/数据/接收器时,直接返回 // 前置校验:位置列表未同步/为空/无GPS,直接返回
if (mVisibleDistanceViewTags.isEmpty()) { if (!isPositionListSynced || mPositionList.isEmpty()) {
LogUtils.d(TAG, "无需要更新的可见控件,跳过计算"); LogUtils.d(TAG, "位置列表未同步/为空,跳过距离计算");
return; return;
} }
if (mPositionList.isEmpty()) { if (mCurrentGpsPosition == null) {
LogUtils.d(TAG, "位置列表为空,无法计算距离"); LogUtils.d(TAG, "无当前GPS位置跳过距离计算");
return;
}
if (mUpdateReceiver == null) {
LogUtils.d(TAG, "未设置消息接收器Adapter未绑定无法发送更新");
return; return;
} }
// Java7使用Iterator遍历Map.Entry替代forEach Lambda // 遍历所有位置项计算并设置realPositionDistance
Iterator<Map.Entry<String, Integer>> entryIterator = mVisibleDistanceViewTags.entrySet().iterator(); Iterator<PositionModel> positionIter = mPositionList.iterator();
while (entryIterator.hasNext()) { while (positionIter.hasNext()) {
Map.Entry<String, Integer> entry = entryIterator.next(); PositionModel targetModel = positionIter.next();
String positionId = entry.getKey(); String positionId = targetModel.getPositionId();
PositionModel targetModel = findPositionModelById(positionId);
if (targetModel == null) { if (targetModel.isEnableRealPositionDistance()) {
// 位置模型不存在时,发送“无效位置”消息 // 状态为true计算距离设置到realPositionDistance
sendDistanceUpdateMessage(
positionId,
"实时距离:位置无效",
mUpdateReceiver.getColorRes(R.color.colorRed)
);
LogUtils.d(TAG, "位置ID=" + positionId + " 未找到对应模型,发送无效提示");
continue;
}
// 距离计算与文本生成
String distanceText;
int distanceColor;
if (!targetModel.isEnableRealPositionDistance()) {
distanceText = "实时距离:未启用";
distanceColor = mUpdateReceiver.getColorRes(R.color.colorGrayText);
} else if (mCurrentGpsPosition == null) {
// 无GPS时持续发送“等待定位”避免默认文本回落
distanceText = "实时距离等待GPS定位";
distanceColor = mUpdateReceiver.getColorRes(R.color.colorGrayText);
LogUtils.d(TAG, "位置ID=" + positionId + " 无GPS数据发送等待提示");
} else {
try { try {
// 计算距离复用PositionModel静态方法 double distanceM = PositionModel.calculatePositionDistance(
double distanceM = PositionModel.calculatePositionDistance(mCurrentGpsPosition, targetModel, false); mCurrentGpsPosition, targetModel, false
judgeTaskBingoStatus(targetModel, (int) distanceM); );
// 格式化距离文本Java7显式类型转换避免自动拆箱问题 targetModel.setRealPositionDistance(distanceM); // 存储计算结果到列表项
if (distanceM < 1000) { LogUtils.d(TAG, "位置ID=" + positionId + " 计算距离:" + distanceM + "");
distanceText = String.format("实时距离:%.1f 米", distanceM);
} else {
distanceText = String.format("实时距离:%.1f 千米", distanceM / 1000);
}
distanceColor = mUpdateReceiver.getColorRes(R.color.colorEnableGreen);
LogUtils.d(TAG, "位置ID=" + positionId + " 计算完成:" + distanceText);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
distanceText = "实时距离:数据无效"; // 计算异常时,设置为-1标记无效
distanceColor = mUpdateReceiver.getColorRes(R.color.colorRed); targetModel.setRealPositionDistance(-1);
LogUtils.e(TAG, "位置ID=" + positionId + " 计算异常:" + e.getMessage()); LogUtils.e(TAG, "位置ID=" + positionId + " 距离计算异常:" + e.getMessage());
} }
} else {
// 状态为false强制设置realPositionDistance为-1
targetModel.setRealPositionDistance(-1);
LogUtils.d(TAG, "位置ID=" + positionId + " 未启用距离计算,设置距离为-1");
} }
// 发送消息到UI线程 // 发送更新通知仅传位置ID
sendDistanceUpdateMessage(positionId, distanceText, distanceColor); sendDistanceUpdateMessage(positionId);
} }
} }
@@ -202,7 +174,7 @@ public class DistanceRefreshService extends Service {
* Java7使用迭代器遍历任务列表替代forEach Lambda * Java7使用迭代器遍历任务列表替代forEach Lambda
*/ */
private void checkAndTriggerTasks() { private void checkAndTriggerTasks() {
if (mAllPositionTasks.isEmpty()) { if (mAllPositionTasks.isEmpty() || !isPositionListSynced || mPositionList.isEmpty()) {
return; return;
} }
// Java7Iterator遍历ArrayList替代forEach Lambda // Java7Iterator遍历ArrayList替代forEach Lambda
@@ -216,64 +188,69 @@ public class DistanceRefreshService extends Service {
} }
/** /**
* 判断任务触发状态(仅修改数据UI更新由Adapter处理 * 新增:判断任务触发状态(基于mPositionList中的realPositionDistance
* Java7迭代器遍历任务列表显式状态判断 * Java7迭代器遍历任务列表显式状态判断
*/ */
private void judgeTaskBingoStatus(PositionModel model, int distanceM) { private void judgeTaskBingoStatus() {
String targetPosId = model.getPositionId(); if (!isPositionListSynced || mPositionList.isEmpty() || mAllPositionTasks.isEmpty()) {
// Java7Iterator遍历任务列表 return;
Iterator<PositionTaskModel> taskIterator = mAllPositionTasks.iterator(); }
while (taskIterator.hasNext()) {
PositionTaskModel task = taskIterator.next();
if (targetPosId.equals(task.getPositionId())) {
boolean oldBingoState = task.isBingo();
boolean newBingoState = false;
// 根据任务条件判断新状态Java7if-else替代三元表达式增强可读性 Iterator<PositionModel> posIter = mPositionList.iterator();
if (task.isGreaterThan()) { while (posIter.hasNext()) {
newBingoState = task.isEnable() && distanceM > task.getDiscussDistance(); PositionModel posModel = posIter.next();
} else if (task.isLessThan()) { String posId = posModel.getPositionId();
newBingoState = task.isEnable() && distanceM < task.getDiscussDistance(); double distanceM = posModel.getRealPositionDistance();
} else {
newBingoState = task.isEnable();
}
// 更新任务状态(仅状态变化时更新) // 遍历绑定当前位置的任务
if (newBingoState != oldBingoState) { Iterator<PositionTaskModel> taskIter = mAllPositionTasks.iterator();
task.setIsBingo(newBingoState); while (taskIter.hasNext()) {
PositionTaskModel task = taskIter.next();
if (posId.equals(task.getPositionId()) && distanceM != -1) {
boolean oldBingoState = task.isBingo();
boolean newBingoState = false;
// 根据任务条件判断新状态
if (task.isGreaterThan()) {
newBingoState = task.isEnable() && distanceM > task.getDiscussDistance();
} else if (task.isLessThan()) {
newBingoState = task.isEnable() && distanceM < task.getDiscussDistance();
}
// 仅状态变化时更新
if (newBingoState != oldBingoState) {
task.setIsBingo(newBingoState);
}
} }
} }
} }
} }
/** /**
* 发送距离更新消息通过Handler发送到UI线程 * 简化仅发送位置ID通知Adapter从mPositionList读取数据
* Java7显式创建Message避免obtainMessage链式调用 * Java7显式创建Message避免obtainMessage链式调用
*/ */
private void sendDistanceUpdateMessage(String positionId, String distanceText, int distanceColor) { private void sendDistanceUpdateMessage(String positionId) {
Message msg = mMainHandler.obtainMessage(MSG_UPDATE_DISTANCE); Message msg = mMainHandler.obtainMessage(MSG_UPDATE_DISTANCE);
// Java7显式调用put方法替代链式put Bundle data = new Bundle();
msg.getData().putString(KEY_POSITION_ID, positionId); data.putString(KEY_POSITION_ID, positionId);
msg.getData().putString(KEY_DISTANCE_TEXT, distanceText); msg.setData(data);
msg.getData().putInt(KEY_DISTANCE_COLOR, distanceColor);
mMainHandler.sendMessage(msg); mMainHandler.sendMessage(msg);
LogUtils.d(TAG, "发送消息→位置ID=" + positionId + ",距离文本=" + distanceText); LogUtils.d(TAG, "发送更新通知:位置ID=" + positionId);
} }
/** /**
* 根据位置ID查找位置模型工具方法 * 核心修改:同步位置列表(持有原引用,不拷贝
* Java7迭代器遍历位置列表替代stream().filter()
*/ */
private PositionModel findPositionModelById(String positionId) { public void syncPositionList(ArrayList<PositionModel> positionList) {
// Java7Iterator遍历ArrayList if (positionList != null) {
Iterator<PositionModel> modelIterator = mPositionList.iterator(); this.mPositionList = positionList; // 持有外部列表引用
while (modelIterator.hasNext()) { this.isPositionListSynced = true;
PositionModel model = modelIterator.next(); LogUtils.d(TAG, "同步位置列表(持有引用):数量=" + positionList.size());
if (positionId.equals(model.getPositionId())) { } else {
return model; this.isPositionListSynced = false;
} LogUtils.w(TAG, "同步位置列表失败传入列表为null");
} }
return null;
} }
// ---------------------- 对外API供Activity/Adapter调用 ---------------------- // ---------------------- 对外API供Activity/Adapter调用 ----------------------
@@ -286,14 +263,6 @@ public class DistanceRefreshService extends Service {
LogUtils.d(TAG, "同步GPS位置纬度=" + (currentGpsPosition != null ? currentGpsPosition.getLatitude() : 0.0f)); LogUtils.d(TAG, "同步GPS位置纬度=" + (currentGpsPosition != null ? currentGpsPosition.getLatitude() : 0.0f));
} }
public void syncPositionList(ArrayList<PositionModel> positionList) {
if (positionList != null) {
this.mPositionList.clear();
this.mPositionList.addAll(positionList);
LogUtils.d(TAG, "同步位置列表:数量=" + positionList.size());
}
}
public void syncAllPositionTasks(ArrayList<PositionTaskModel> allPositionTasks) { public void syncAllPositionTasks(ArrayList<PositionTaskModel> allPositionTasks) {
if (allPositionTasks != null) { if (allPositionTasks != null) {
this.mAllPositionTasks.clear(); this.mAllPositionTasks.clear();
@@ -331,10 +300,11 @@ public class DistanceRefreshService extends Service {
} }
// 清空数据,解除引用(避免内存泄漏) // 清空数据,解除引用(避免内存泄漏)
mCurrentGpsPosition = null; mCurrentGpsPosition = null;
mPositionList.clear(); mPositionList = null; // 释放列表引用
mAllPositionTasks.clear(); mAllPositionTasks.clear();
mVisibleDistanceViewTags.clear(); mVisibleDistanceViewTags.clear();
mUpdateReceiver = null; mUpdateReceiver = null;
isPositionListSynced = false;
} }
} }