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,16 +38,15 @@ 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; | ||||||
|     private boolean isServiceBound = false; |     private boolean isServiceBound = false; | ||||||
| 	 |  | ||||||
| 	// ---------------------- 新增:GPS监听核心变量 ---------------------- | 	// ---------------------- 新增:GPS监听核心变量 ---------------------- | ||||||
|     private MainService.GpsUpdateListener mGpsUpdateListener; // GPS监听实例 |     private MainService.GpsUpdateListener mGpsUpdateListener; // GPS监听实例 | ||||||
|     private PositionModel mCurrentGpsPos; // 缓存当前GPS位置(供页面使用) |     private PositionModel mCurrentGpsPos; // 缓存当前GPS位置(供页面使用) | ||||||
| 	 |  | ||||||
|  |  | ||||||
|     // 服务连接(Java 7 匿名内部类实现) |     // 服务连接(Java 7 匿名内部类实现) | ||||||
|     private ServiceConnection mServiceConnection = new ServiceConnection() { |     private ServiceConnection mServiceConnection = new ServiceConnection() { | ||||||
| @@ -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,18 +266,7 @@ 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状态变化(如开启/关闭、信号弱,提示用户) | ||||||
|             @Override |             @Override | ||||||
| @@ -292,10 +323,10 @@ public class LocationActivity extends Activity { | |||||||
|             unbindService(mServiceConnection); |             unbindService(mServiceConnection); | ||||||
|             LogUtils.d(TAG, "MainService解绑完成"); |             LogUtils.d(TAG, "MainService解绑完成"); | ||||||
|         } |         } | ||||||
| 		 |  | ||||||
| 		unregisterGpsListener(); | 		unregisterGpsListener(); | ||||||
|     } |     } | ||||||
| 	 |  | ||||||
| 	public static class LocalBinder extends android.os.Binder { | 	public static class LocalBinder extends android.os.Binder { | ||||||
|         // 持有 MainService 实例引用 |         // 持有 MainService 实例引用 | ||||||
|         private MainService mService; |         private MainService mService; | ||||||
|   | |||||||
| @@ -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
	 ZhanGSKen
					ZhanGSKen