20251003_031830_311
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Thu Oct 02 18:42:32 GMT 2025
|
#Thu Oct 02 19:13:53 GMT 2025
|
||||||
stageCount=8
|
stageCount=8
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=15.0
|
baseVersion=15.0
|
||||||
publishVersion=15.0.7
|
publishVersion=15.0.7
|
||||||
buildCount=36
|
buildCount=46
|
||||||
baseBetaVersion=15.0.8
|
baseBetaVersion=15.0.8
|
||||||
|
|||||||
@@ -5,25 +5,27 @@ package cc.winboll.studio.positions.activities;
|
|||||||
* @Date 2025/09/29 18:22
|
* @Date 2025/09/29 18:22
|
||||||
* @Describe 位置列表页面(适配MainService GPS接口+规范服务交互+完善生命周期)
|
* @Describe 位置列表页面(适配MainService GPS接口+规范服务交互+完善生命周期)
|
||||||
*/
|
*/
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
import cc.winboll.studio.libappbase.LogUtils;
|
||||||
|
import cc.winboll.studio.libappbase.ToastUtils;
|
||||||
|
import cc.winboll.studio.positions.R;
|
||||||
import cc.winboll.studio.positions.adapters.PositionAdapter;
|
import cc.winboll.studio.positions.adapters.PositionAdapter;
|
||||||
import cc.winboll.studio.positions.models.PositionModel;
|
import cc.winboll.studio.positions.models.PositionModel;
|
||||||
import cc.winboll.studio.positions.models.PositionTaskModel;
|
import cc.winboll.studio.positions.models.PositionTaskModel;
|
||||||
import cc.winboll.studio.positions.services.MainService;
|
import cc.winboll.studio.positions.services.MainService;
|
||||||
import cc.winboll.studio.positions.R;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import cc.winboll.studio.libappbase.ToastUtils;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Java 7 语法适配:
|
* Java 7 语法适配:
|
||||||
@@ -36,7 +38,6 @@ public class LocationActivity extends Activity {
|
|||||||
|
|
||||||
private RecyclerView mRvPosition;
|
private RecyclerView mRvPosition;
|
||||||
private PositionAdapter mPositionAdapter;
|
private PositionAdapter mPositionAdapter;
|
||||||
private ArrayList<PositionModel> mLocalPosCache; // 本地位置缓存(与MainService同步)
|
|
||||||
|
|
||||||
// MainService 引用+绑定状态
|
// MainService 引用+绑定状态
|
||||||
private MainService mMainService;
|
private MainService mMainService;
|
||||||
@@ -58,10 +59,12 @@ public class LocationActivity extends Activity {
|
|||||||
|
|
||||||
LogUtils.d(TAG, "MainService绑定成功,开始同步数据");
|
LogUtils.d(TAG, "MainService绑定成功,开始同步数据");
|
||||||
// 从MainService同步初始数据(位置+任务)
|
// 从MainService同步初始数据(位置+任务)
|
||||||
syncDataFromMainService();
|
//syncDataFromMainService();
|
||||||
// 初始化Adapter(传入MainService实例,确保任务数据从服务获取)
|
// 初始化Adapter(传入MainService实例,确保任务数据从服务获取)
|
||||||
initPositionAdapter();
|
|
||||||
registerGpsListener();
|
registerGpsListener();
|
||||||
|
|
||||||
|
initPositionAdapter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -79,11 +82,13 @@ public class LocationActivity extends Activity {
|
|||||||
|
|
||||||
// 初始化视图+本地缓存
|
// 初始化视图+本地缓存
|
||||||
initView();
|
initView();
|
||||||
mLocalPosCache = new ArrayList<PositionModel>();
|
//mLocalPosCache = new ArrayList<PositionModel>();
|
||||||
|
|
||||||
// 绑定MainService(确保Activity启动时就拿到服务实例)
|
// 绑定MainService(确保Activity启动时就拿到服务实例)
|
||||||
bindMainService();
|
bindMainService();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 初始化GPS监听(提前创建,避免空指针)
|
// 初始化GPS监听(提前创建,避免空指针)
|
||||||
initGpsUpdateListener();
|
initGpsUpdateListener();
|
||||||
}
|
}
|
||||||
@@ -112,25 +117,25 @@ public class LocationActivity extends Activity {
|
|||||||
/**
|
/**
|
||||||
* 从MainService同步数据(位置+任务)
|
* 从MainService同步数据(位置+任务)
|
||||||
*/
|
*/
|
||||||
private void syncDataFromMainService() {
|
// private void syncDataFromMainService() {
|
||||||
if (!isServiceBound || mMainService == null) {
|
// if (!isServiceBound || mMainService == null) {
|
||||||
LogUtils.w(TAG, "同步数据失败:MainService未绑定");
|
// LogUtils.w(TAG, "同步数据失败:MainService未绑定");
|
||||||
showToast("服务未就绪,无法加载数据");
|
// showToast("服务未就绪,无法加载数据");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 同步位置数据(从服务获取最新列表)
|
// // 同步位置数据(从服务获取最新列表)
|
||||||
ArrayList<PositionModel> servicePosList = mMainService.getPositionList();
|
// ArrayList<PositionModel> servicePosList = mMainService.getPositionList();
|
||||||
if (servicePosList != null && !servicePosList.isEmpty()) {
|
// if (servicePosList != null && !servicePosList.isEmpty()) {
|
||||||
mLocalPosCache.clear();
|
// mLocalPosCache.clear();
|
||||||
mLocalPosCache.addAll(servicePosList);
|
// mLocalPosCache.addAll(servicePosList);
|
||||||
LogUtils.d(TAG, "从MainService同步位置数据完成:数量=" + mLocalPosCache.size());
|
// LogUtils.d(TAG, "从MainService同步位置数据完成:数量=" + mLocalPosCache.size());
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// 同步任务数据(无需本地缓存,Adapter直接从服务获取)
|
// // 同步任务数据(无需本地缓存,Adapter直接从服务获取)
|
||||||
ArrayList<PositionTaskModel> serviceTaskList = mMainService.getAllTasks();
|
// ArrayList<PositionTaskModel> serviceTaskList = mMainService.getAllTasks();
|
||||||
LogUtils.d(TAG, "从MainService同步任务数据完成:数量=" + serviceTaskList.size());
|
// LogUtils.d(TAG, "从MainService同步任务数据完成:数量=" + serviceTaskList.size());
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化PositionAdapter(核心:传入MainService实例)
|
* 初始化PositionAdapter(核心:传入MainService实例)
|
||||||
@@ -142,23 +147,23 @@ public class LocationActivity extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Java 7 显式初始化Adapter,传入上下文+本地位置缓存+MainService实例
|
// Java 7 显式初始化Adapter,传入上下文+本地位置缓存+MainService实例
|
||||||
mPositionAdapter = new PositionAdapter(this, mLocalPosCache, mMainService);
|
mPositionAdapter = new PositionAdapter(this, mMainService);
|
||||||
|
|
||||||
// 设置Adapter回调(处理位置删除/保存,最终同步到MainService)
|
// 设置Adapter回调(处理位置删除/保存,最终同步到MainService)
|
||||||
mPositionAdapter.setOnDeleteClickListener(new PositionAdapter.OnDeleteClickListener() {
|
mPositionAdapter.setOnDeleteClickListener(new PositionAdapter.OnDeleteClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onDeleteClick(int position) {
|
public void onDeleteClick(int position) {
|
||||||
// 删除逻辑:先删本地缓存,再调用MainService接口删服务数据
|
// 删除逻辑:先删本地缓存,再调用MainService接口删服务数据
|
||||||
if (position < 0 || position >= mLocalPosCache.size()) {
|
if (position < 0 || position >= mMainService.getPositionList().size()) {
|
||||||
LogUtils.w(TAG, "删除位置失败:无效索引=" + position);
|
LogUtils.w(TAG, "删除位置失败:无效索引=" + position);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PositionModel deletePos = mLocalPosCache.get(position);
|
PositionModel deletePos = mMainService.getPositionList().get(position);
|
||||||
if (deletePos != null && !deletePos.getPositionId().isEmpty()) {
|
if (deletePos != null && !deletePos.getPositionId().isEmpty()) {
|
||||||
// 1. 调用MainService接口删除服务端数据
|
// 1. 调用MainService接口删除服务端数据
|
||||||
mMainService.removePosition(deletePos.getPositionId());
|
mMainService.removePosition(deletePos.getPositionId());
|
||||||
// 2. 删除本地缓存数据
|
// 2. 删除本地缓存数据
|
||||||
mLocalPosCache.remove(position);
|
//mPositionList.remove(position);
|
||||||
// 3. 通知Adapter刷新
|
// 3. 通知Adapter刷新
|
||||||
mPositionAdapter.notifyItemRemoved(position);
|
mPositionAdapter.notifyItemRemoved(position);
|
||||||
showToast("删除位置成功:" + deletePos.getMemo());
|
showToast("删除位置成功:" + deletePos.getMemo());
|
||||||
@@ -176,7 +181,7 @@ public class LocationActivity extends Activity {
|
|||||||
showToast("服务未就绪,保存失败");
|
showToast("服务未就绪,保存失败");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (position < 0 || position >= mLocalPosCache.size()) {
|
if (position < 0 || position >= mMainService.getPositionList().size()) {
|
||||||
LogUtils.w(TAG, "保存位置失败:无效索引=" + position);
|
LogUtils.w(TAG, "保存位置失败:无效索引=" + position);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -184,7 +189,7 @@ public class LocationActivity extends Activity {
|
|||||||
// 1. 调用MainService接口更新服务端数据
|
// 1. 调用MainService接口更新服务端数据
|
||||||
mMainService.updatePosition(updatedPos);
|
mMainService.updatePosition(updatedPos);
|
||||||
// 2. 更新本地缓存数据
|
// 2. 更新本地缓存数据
|
||||||
mLocalPosCache.set(position, updatedPos);
|
//mLocalPosCache.set(position, updatedPos);
|
||||||
// 3. 通知Adapter刷新(可选,Adapter已本地同步)
|
// 3. 通知Adapter刷新(可选,Adapter已本地同步)
|
||||||
mPositionAdapter.notifyItemChanged(position);
|
mPositionAdapter.notifyItemChanged(position);
|
||||||
showToast("保存位置成功:" + updatedPos.getMemo());
|
showToast("保存位置成功:" + updatedPos.getMemo());
|
||||||
@@ -204,6 +209,43 @@ public class LocationActivity extends Activity {
|
|||||||
Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------- 页面交互(新增位置逻辑保留,适配GPS数据) ----------------------
|
||||||
|
/**
|
||||||
|
* 新增位置(调用服务addPosition(),可选:用当前GPS位置初始化新位置)
|
||||||
|
*/
|
||||||
|
public void addNewPosition(View view) {
|
||||||
|
// 1. 隐藏软键盘
|
||||||
|
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
if (imm != null && getCurrentFocus() != null) {
|
||||||
|
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 创建新位置模型(优化:优先用当前GPS位置初始化,无则用默认值)
|
||||||
|
PositionModel newPos = new PositionModel();
|
||||||
|
newPos.setPositionId(PositionModel.genPositionId()); // 生成唯一ID(需PositionModel实现)
|
||||||
|
// (新增)用当前GPS位置初始化新位置(提升用户体验,无需手动输入经纬度)
|
||||||
|
if (mCurrentGpsPos != null) {
|
||||||
|
newPos.setLongitude(mCurrentGpsPos.getLongitude());
|
||||||
|
newPos.setLatitude(mCurrentGpsPos.getLatitude());
|
||||||
|
newPos.setMemo("当前GPS位置(可编辑)");
|
||||||
|
} else {
|
||||||
|
// 无GPS位置时用默认值
|
||||||
|
newPos.setLongitude(116.404267); // 北京经度
|
||||||
|
newPos.setLatitude(39.915119); // 北京纬度
|
||||||
|
newPos.setMemo("默认位置(可编辑备注)");
|
||||||
|
}
|
||||||
|
newPos.setIsSimpleView(true); // 默认简单视图
|
||||||
|
newPos.setIsEnableRealPositionDistance(true); // 启用距离计算(依赖GPS)
|
||||||
|
|
||||||
|
// 4. 调用服务PUBLIC方法新增
|
||||||
|
mMainService.addPosition(newPos);
|
||||||
|
LogUtils.d(TAG, "通过服务新增位置:ID=" + newPos.getPositionId() + ",纬度=" + newPos.getLatitude());
|
||||||
|
|
||||||
|
// 5. 刷新缓存+Adapter(显示新增结果+距离)
|
||||||
|
mPositionAdapter.notifyDataSetChanged();
|
||||||
|
Toast.makeText(this, "新增位置成功(已启用GPS距离计算)", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------- 新增:GPS监听初始化+注册/反注册(核心适配逻辑) ----------------------
|
// ---------------------- 新增:GPS监听初始化+注册/反注册(核心适配逻辑) ----------------------
|
||||||
/**
|
/**
|
||||||
* 初始化GPS监听:实现MainService.GpsUpdateListener,接收实时GPS数据
|
* 初始化GPS监听:实现MainService.GpsUpdateListener,接收实时GPS数据
|
||||||
@@ -224,17 +266,6 @@ public class LocationActivity extends Activity {
|
|||||||
, currentGpsPos.getLatitude(), currentGpsPos.getLongitude()));
|
, currentGpsPos.getLatitude(), currentGpsPos.getLongitude()));
|
||||||
((TextView)findViewById(R.id.tv_latitude)).setText(String.format("当前纬度:%f", currentGpsPos.getLatitude()));
|
((TextView)findViewById(R.id.tv_latitude)).setText(String.format("当前纬度:%f", currentGpsPos.getLatitude()));
|
||||||
((TextView)findViewById(R.id.tv_longitude)).setText(String.format("当前经度:%f", currentGpsPos.getLongitude()));
|
((TextView)findViewById(R.id.tv_longitude)).setText(String.format("当前经度:%f", currentGpsPos.getLongitude()));
|
||||||
|
|
||||||
// 1. 同步GPS位置到MainService(确保服务数据与页面一致,触发距离计算)
|
|
||||||
if (mMainService != null) {
|
|
||||||
// mMainService.syncCurrentGpsPosition(currentGpsPos);
|
|
||||||
// // 2. 强制刷新距离计算+Adapter(显示最新距离)
|
|
||||||
// mMainService.forceRefreshDistance();
|
|
||||||
// refreshCachedDataAndAdapter();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. (可选)显示GPS位置Toast提示(如调试场景)
|
|
||||||
// ToastUtils.show("GPS更新:" + currentGpsPos.getLatitude() + "," + currentGpsPos.getLongitude());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 回调2:GPS状态变化(如开启/关闭、信号弱,提示用户)
|
// 回调2:GPS状态变化(如开启/关闭、信号弱,提示用户)
|
||||||
|
|||||||
@@ -72,10 +72,10 @@ public class PositionAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||||||
// =========================================================================
|
// =========================================================================
|
||||||
// 构造函数(Java 7 风格:初始化依赖+注册任务监听)
|
// 构造函数(Java 7 风格:初始化依赖+注册任务监听)
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
public PositionAdapter(Context context, ArrayList<PositionModel> cachedPositionList, MainService mainService) {
|
public PositionAdapter(Context context, MainService mainService) {
|
||||||
this.mContext = context;
|
this.mContext = context;
|
||||||
// 容错处理:避免传入null导致空指针
|
// 容错处理:避免传入null导致空指针
|
||||||
this.mCachedPositionList = (cachedPositionList != null) ? cachedPositionList : new ArrayList<PositionModel>();
|
this.mCachedPositionList = (mainService.getPositionList() != null) ? mainService.getPositionList() : new ArrayList<PositionModel>();
|
||||||
// 弱引用MainService:防止Adapter持有Service导致内存泄漏(Java 7 弱引用语法)
|
// 弱引用MainService:防止Adapter持有Service导致内存泄漏(Java 7 弱引用语法)
|
||||||
this.mMainServiceRef = new WeakReference<MainService>(mainService);
|
this.mMainServiceRef = new WeakReference<MainService>(mainService);
|
||||||
// 初始化距离控件缓存(线程安全集合,适配多线程更新场景)
|
// 初始化距离控件缓存(线程安全集合,适配多线程更新场景)
|
||||||
|
|||||||
Reference in New Issue
Block a user