From 2be6d5e122aaf8982e220bdcffa520564bd2a9f8 Mon Sep 17 00:00:00 2001 From: ZhanGSKen Date: Tue, 28 Oct 2025 19:59:33 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=BF=90=E5=8A=A8=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=A3=80=E6=B5=8B=EF=BC=8C=E8=BF=90=E5=8A=A8=E5=AE=9E?= =?UTF-8?q?=E6=97=B6=E7=9B=91=E5=90=ACGPS=E4=BD=8D=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E9=9D=99=E6=AD=A2=E6=97=B6=E6=AF=8F=E4=B8=80=E5=88=86=E9=92=9F?= =?UTF-8?q?=E7=9B=91=E5=90=AC=E4=B8=80=E6=AC=A1GPS=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- positions/build.properties | 4 +- positions/src/main/AndroidManifest.xml | 14 + .../receivers/MotionStatusReceiver.java | 124 ++++ .../positions/services/MainService.java | 547 ++++++++---------- 4 files changed, 389 insertions(+), 300 deletions(-) create mode 100644 positions/src/main/java/cc/winboll/studio/positions/receivers/MotionStatusReceiver.java diff --git a/positions/build.properties b/positions/build.properties index 0c9f1ccb..b32e0e65 100644 --- a/positions/build.properties +++ b/positions/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Tue Oct 28 14:17:09 HKT 2025 +#Tue Oct 28 12:00:20 GMT 2025 stageCount=17 libraryProject= baseVersion=15.0 publishVersion=15.0.16 -buildCount=0 +buildCount=8 baseBetaVersion=15.0.17 diff --git a/positions/src/main/AndroidManifest.xml b/positions/src/main/AndroidManifest.xml index d3022109..72ceca0f 100644 --- a/positions/src/main/AndroidManifest.xml +++ b/positions/src/main/AndroidManifest.xml @@ -3,6 +3,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" package="cc.winboll.studio.positions"> + + + @@ -61,6 +64,17 @@ + + + + + + + + diff --git a/positions/src/main/java/cc/winboll/studio/positions/receivers/MotionStatusReceiver.java b/positions/src/main/java/cc/winboll/studio/positions/receivers/MotionStatusReceiver.java new file mode 100644 index 00000000..c3f6e89e --- /dev/null +++ b/positions/src/main/java/cc/winboll/studio/positions/receivers/MotionStatusReceiver.java @@ -0,0 +1,124 @@ +package cc.winboll.studio.positions.receivers; + +/** + * @Author ZhanGSKen&豆包大模型 + * @Date 2025/10/28 19:07 + * @Describe MotionStatusReceiver + */ +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Build; +import android.text.TextUtils; +import cc.winboll.studio.libappbase.LogUtils; +import cc.winboll.studio.positions.services.MainService; +import cc.winboll.studio.positions.utils.ServiceUtil; + +/** + * 运动状态监听Receiver + * 功能:接收运动状态广播,控制GPS权限申请与GPS监听开关 + */ +public class MotionStatusReceiver extends BroadcastReceiver { + public static final String TAG = "MotionStatusReceiver"; + + // 运动状态广播Action(需与运动状态发送方保持一致,如传感器服务) + public static final String ACTION_MOTION_STATUS = "cc.winboll.studio.positions.ACTION_MOTION_STATUS"; + // 运动状态Extra键:0=静止/低运动,1=行走/高运动 + public static final String EXTRA_MOTION_STATUS = "EXTRA_MOTION_STATUS"; + // 静止时GPS定时获取间隔(单位:分钟,可配置) + public static final long GPS_STATIC_INTERVAL = 1; + + @Override + public void onReceive(Context context, Intent intent) { + if (context == null || intent == null || !TextUtils.equals(intent.getAction(), ACTION_MOTION_STATUS)) { + LogUtils.w(TAG, "无效广播:Action不匹配或上下文为空"); + return; + } + + // 1. 获取运动状态(0=静止/低运动,1=行走/高运动) + int motionStatus = intent.getIntExtra(EXTRA_MOTION_STATUS, 0); + LogUtils.d(TAG, "接收运动状态:" + (motionStatus == 1 ? "行走中" : "静止/低运动")); + + // 2. 绑定并获取MainService实例(确保服务已启动) + MainService mainService = getMainService(context); + if (mainService == null) { + LogUtils.e(TAG, "MainService未启动,无法控制GPS状态"); + return; + } + + // 3. 根据运动状态处理GPS逻辑 + if (motionStatus == 1) { + // 3.1 行走中:申请GPS权限(若未授予)+ 开启持续GPS监听 + handleWalkingStatus(mainService, context); + } else { + // 3.2 静止/低运动:关闭持续GPS监听 + 启动定时GPS获取 + handleStaticStatus(mainService); + } + } + + /** + * 处理行走状态:申请GPS权限+开启持续GPS监听 + */ + private void handleWalkingStatus(MainService mainService, Context context) { + // 检查GPS权限(Android 6.0+动态权限) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && + context.checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) + != PackageManager.PERMISSION_GRANTED) { + // 发送权限申请广播(由Activity接收并发起申请,Receiver无法直接申请权限) + Intent permissionIntent = new Intent("cc.winboll.studio.positions.ACTION_REQUEST_GPS_PERMISSION"); + permissionIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + context.sendBroadcast(permissionIntent); + LogUtils.d(TAG, "行走中:GPS权限未授予,已发送权限申请广播"); + return; + } + + // 权限已授予:开启持续GPS监听(调用MainService原有方法) + if (!mainService.isGpsListening()) { // 需在MainService中新增isGpsListening()方法 + mainService.startGpsLocation(); + LogUtils.d(TAG, "行走中:已开启持续GPS监听"); + } + + // 停止静止时的GPS定时任务(避免重复获取) + mainService.stopGpsStaticTimer(); + } + + /** + * 处理静止状态:关闭持续GPS监听+启动定时GPS获取 + */ + private void handleStaticStatus(MainService mainService) { + // 关闭持续GPS监听(避免耗电) + if (mainService.isGpsListening()) { + mainService.stopGpsLocation(); + LogUtils.d(TAG, "静止中:已关闭持续GPS监听"); + } + + // 启动定时GPS获取(获取一次后关闭,间隔GPS_STATIC_INTERVAL分钟) + mainService.startGpsStaticTimer(GPS_STATIC_INTERVAL); + } + + /** + * 获取MainService实例(通过绑定服务或单例,确保线程安全) + */ + private MainService getMainService(Context context) { + // 方式1:若MainService单例有效,直接获取(推荐) + MainService singleton = MainService.getInstance(context); + if (singleton != null && singleton.isServiceRunning()) { + return singleton; + } + + // 方式2:若单例无效,尝试绑定服务(备用,需处理绑定回调) + if (!ServiceUtil.isServiceAlive(context, MainService.class.getName())) { + // 启动服务(若未运行) + context.startService(new Intent(context, MainService.class)); + // 等待服务启动(短延时,实际项目建议用ServiceConnection异步绑定) + try { + Thread.sleep(500); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + return MainService.getInstance(context); + } +} + diff --git a/positions/src/main/java/cc/winboll/studio/positions/services/MainService.java b/positions/src/main/java/cc/winboll/studio/positions/services/MainService.java index 59b4bc0c..773d288a 100644 --- a/positions/src/main/java/cc/winboll/studio/positions/services/MainService.java +++ b/positions/src/main/java/cc/winboll/studio/positions/services/MainService.java @@ -3,7 +3,7 @@ package cc.winboll.studio.positions.services; /** * @Author ZhanGSKen * @Date 2024/07/19 14:30:57 - * @Describe 应用主要服务组件类 + * @Describe 应用主要服务组件类(适配运动状态GPS控制) */ import android.app.Service; import android.content.ComponentName; @@ -35,37 +35,40 @@ import java.util.Iterator; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; // 新增:定时器时间单位依赖 +import java.util.concurrent.TimeUnit; public class MainService extends Service { public static final String TAG = "MainService"; + public static final String EXTRA_IS_SETTING_TO_ENABLE = "EXTRA_IS_SETTING_TO_ENABLE"; - public static final String EXTRA_IS_SETTING_TO_ENABLE = "EXTRA_IS_SETTING_TO_ENABLE"; - - // ---------------------- 新增:定时器相关变量 ---------------------- + // ---------------------- 定时器相关变量 ---------------------- private ScheduledExecutorService taskCheckTimer; // 任务校验定时器 private static final long TASK_CHECK_INTERVAL = 1; // 定时间隔(1分钟) - private static final long TASK_CHECK_INIT_DELAY = 1; // 初始延迟(1分钟:立即启动) + private static final long TASK_CHECK_INIT_DELAY = 1; // 初始延迟(1分钟) + // 新增:静止时GPS定时任务变量(Java 7 显式声明) + private ScheduledExecutorService gpsStaticTimer; // 静止时GPS定时获取线程池 + private volatile boolean isGpsListening = false; // GPS是否处于持续监听状态 + private static final long GPS_STATIC_DURATION = 3; // 静止时GPS单次获取超时时间(秒) - // GPS监听接口(Java 7 标准接口定义,无Lambda依赖) + // GPS监听接口(Java 7 标准接口定义) public interface GpsUpdateListener { void onGpsPositionUpdated(PositionModel currentGpsPos); void onGpsStatusChanged(String status); } - // 任务更新监听接口(Java 7 风格,供Adapter监听任务变化) + // 任务更新监听接口(Java 7 风格) public interface TaskUpdateListener { void onTaskUpdated(); } - // 监听管理(弱引用+线程安全集合,适配Java 7,避免内存泄漏+并发异常) + // 监听管理(弱引用+线程安全集合,适配Java 7) private final Set> mGpsListeners = new HashSet>(); private final Set> mTaskListeners = new HashSet>(); - private final Object mListenerLock = new Object(); // 监听操作锁,保证线程安全 + private final Object mListenerLock = new Object(); // 监听操作锁 - // 原有核心变量(Java 7 显式初始化,无Java 8+语法) - private LocalBinder mLocalBinder; //持有 LocalBinder 实例(用于暴露服务) + // 原有核心变量(Java 7 显式初始化) + private LocalBinder mLocalBinder; // 持有 LocalBinder 实例 private LocationManager mLocationManager; private LocationListener mGpsLocationListener; private static final long GPS_UPDATE_INTERVAL = 2000; // GPS更新间隔:2秒 @@ -73,83 +76,173 @@ public class MainService extends Service { private boolean isGpsEnabled = false; // GPS是否启用标记 private boolean isGpsPermissionGranted = false; // 定位权限是否授予标记 - // 数据存储集合(Java 7 基础集合,避免Stream/forEach等Java 8+特性) + // 数据存储集合(Java 7 基础集合) private final ArrayList mPositionList = new ArrayList(); // 位置数据列表 private final ArrayList mAllTasks = new ArrayList();// 任务数据列表 private static PositionModel _mCurrentGpsPosition; // 当前GPS定位数据 - // 服务相关变量(Java 7 显式声明,保持原逻辑) + // 服务相关变量(Java 7 显式声明) MyServiceConnection mMyServiceConnection; volatile static boolean _mIsServiceRunning; // 服务运行状态(volatile保证可见性) AppConfigsUtil mAppConfigsUtil; - private ScheduledExecutorService distanceExecutor = Executors.newSingleThreadScheduledExecutor(); // 单线程池处理距离计算 + private ScheduledExecutorService distanceExecutor = Executors.newSingleThreadScheduledExecutor(); // 距离计算线程池 private final Set mVisiblePositionIds = new HashSet(); // 可见位置ID集合 - // 单例+应用上下文(Java 7 静态变量,保证服务实例唯一+上下文安全) + // 单例+应用上下文(Java 7 静态变量) private static volatile MainService sInstance; private static Context sAppContext; // ========================================================================= - // 新增:定时器初始化方法(创建单线程定时器,每1分钟调用任务校验) + // 定时器初始化方法(任务校验+静止GPS定时) // ========================================================================= - private void initTaskCheckTimer() { - // 先销毁旧定时器(避免重复创建导致多线程问题) + /*private void initTaskCheckTimer() { + // 先销毁旧定时器(避免重复创建) if (taskCheckTimer != null && !taskCheckTimer.isShutdown()) { taskCheckTimer.shutdown(); } - // 创建单线程定时器(确保任务串行执行,避免并发异常) + // 创建单线程定时器(任务串行执行) taskCheckTimer = Executors.newSingleThreadScheduledExecutor(); - // 定时任务:初始延迟1分钟,每1分钟执行一次 taskCheckTimer.scheduleAtFixedRate(new Runnable() { @Override public void run() { LogUtils.d(TAG, "定时任务触发:开始校验任务(间隔1分钟)"); - // 调用任务校验核心方法(与GPS位置变化时逻辑一致) DistanceCalculatorUtil.getInstance(MainService.this).checkAllTaskTriggerCondition(MainService._mCurrentGpsPosition); } }, TASK_CHECK_INIT_DELAY, TASK_CHECK_INTERVAL, TimeUnit.MINUTES); LogUtils.d(TAG, "任务校验定时器已启动(间隔:" + TASK_CHECK_INTERVAL + "分钟)"); - } + }*/ - // ========================================================================= - // 新增:定时器销毁方法(服务销毁时调用,避免内存泄漏) - // ========================================================================= - private void destroyTaskCheckTimer() { + /*private void destroyTaskCheckTimer() { if (taskCheckTimer != null && !taskCheckTimer.isShutdown()) { - taskCheckTimer.shutdown(); // 优雅关闭:等待已提交任务执行完成 + taskCheckTimer.shutdown(); // 优雅关闭 try { - // 等待1秒,若未终止则强制关闭 if (!taskCheckTimer.awaitTermination(1, TimeUnit.SECONDS)) { - taskCheckTimer.shutdownNow(); // 强制终止未完成任务 + taskCheckTimer.shutdownNow(); // 强制关闭 } } catch (InterruptedException e) { - taskCheckTimer.shutdownNow(); // 捕获中断异常,强制关闭 - Thread.currentThread().interrupt(); // 恢复线程中断状态 + taskCheckTimer.shutdownNow(); + Thread.currentThread().interrupt(); // 恢复中断状态 } finally { - taskCheckTimer = null; // 置空,避免重复操作 + taskCheckTimer = null; LogUtils.d(TAG, "任务校验定时器已销毁"); } } + }*/ + + // 新增:启动静止时GPS定时获取(Java 7 语法,无Lambda) + public void startGpsStaticTimer(long interval) { + // 先销毁旧定时器(避免重复创建) + stopGpsStaticTimer(); + + // 创建单线程定时器 + gpsStaticTimer = Executors.newSingleThreadScheduledExecutor(); + gpsStaticTimer.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + LogUtils.d(TAG, "静止时GPS定时任务触发:开始单次GPS获取"); + startSingleGpsRetrieve(); // 单次GPS获取 + } + }, 0, interval, TimeUnit.MINUTES); // 立即执行第一次,之后按间隔执行 + + LogUtils.d(TAG, "静止时GPS定时任务已启动(间隔:" + interval + "分钟)"); + } + + // 新增:停止静止时GPS定时任务 + public void stopGpsStaticTimer() { + if (gpsStaticTimer != null && !gpsStaticTimer.isShutdown()) { + gpsStaticTimer.shutdown(); + try { + if (!gpsStaticTimer.awaitTermination(1, TimeUnit.SECONDS)) { + gpsStaticTimer.shutdownNow(); + } + } catch (InterruptedException e) { + gpsStaticTimer.shutdownNow(); + Thread.currentThread().interrupt(); + } finally { + gpsStaticTimer = null; + LogUtils.d(TAG, "静止时GPS定时任务已销毁"); + } + } } + // 新增:单次GPS获取(获取后关闭监听,Java 7 匿名内部类) + private void startSingleGpsRetrieve() { + if (!checkGpsReady()) { + LogUtils.w(TAG, "单次GPS获取:GPS未就绪,跳过"); + return; + } + + try { + // 注册临时GPS监听(仅获取一次位置) + mLocationManager.requestSingleUpdate( + LocationManager.GPS_PROVIDER, + new LocationListener() { + @Override + public void onLocationChanged(Location location) { + // 获取到位置:同步数据+关闭监听 + if (location != null) { + PositionModel gpsPos = new PositionModel(); + gpsPos.setLatitude(location.getLatitude()); + gpsPos.setLongitude(location.getLongitude()); + gpsPos.setPositionId("CURRENT_GPS_POS"); + gpsPos.setMemo("静止时单次GPS位置"); + syncCurrentGpsPosition(gpsPos); + LogUtils.d(TAG, "单次GPS获取成功:纬度=" + location.getLatitude()); + } + // 移除监听(避免内存泄漏) + mLocationManager.removeUpdates(this); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) {} + + @Override + public void onProviderEnabled(String provider) {} + + @Override + public void onProviderDisabled(String provider) { + mLocationManager.removeUpdates(this); // 禁用时移除监听 + } + }, + Looper.getMainLooper() + ); + + // 超时处理:指定时间内未获取则强制关闭 + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + // 移除所有临时监听 + mLocationManager.removeUpdates(new LocationListener() { + @Override public void onLocationChanged(Location location) {} + @Override public void onStatusChanged(String provider, int status, Bundle extras) {} + @Override public void onProviderEnabled(String provider) {} + @Override public void onProviderDisabled(String provider) {} + }); + LogUtils.d(TAG, "单次GPS获取超时(" + GPS_STATIC_DURATION + "秒),已强制关闭监听"); + } + }, GPS_STATIC_DURATION * 1000); + + } catch (SecurityException e) { + LogUtils.e(TAG, "单次GPS获取失败(权限异常):" + e.getMessage()); + } catch (Exception e) { + LogUtils.e(TAG, "单次GPS获取失败:" + e.getMessage()); + } + } + + // ========================================================================= - // 任务操作核心接口(Java 7 实现,全迭代器遍历,无ConcurrentModificationException) + // 任务操作核心接口(Java 7 实现) // ========================================================================= - /** - * 新增任务(Adapter调用,通过MainService统一管理任务,保证数据一致性) - * @param newTask 待新增的任务模型 - */ public void addTask(PositionTaskModel newTask) { - // 参数校验(Java 7 基础判断,无Optional等Java 8+特性) if (newTask == null || TextUtils.isEmpty(newTask.getPositionId())) { LogUtils.w(TAG, "addPositionTask:任务为空或未绑定位置ID,新增失败"); return; } - // 任务去重(Java 7 迭代器遍历,避免增强for循环删除/新增导致的并发异常) + // 任务去重(Java 7 迭代器遍历) boolean isDuplicate = false; Iterator taskIter = mAllTasks.iterator(); while (taskIter.hasNext()) { @@ -164,25 +257,19 @@ public class MainService extends Service { return; } - // 新增任务+持久化+通知刷新(全Java 7 语法) mAllTasks.add(newTask); saveAllTasks(); - notifyTaskUpdated(); // 通知所有监听者(如Adapter)任务已更新 + notifyTaskUpdated(); LogUtils.d(TAG, "addPositionTask:成功(位置ID=" + newTask.getPositionId() + ",任务ID=" + newTask.getTaskId() + ")"); } - /** - * 获取指定位置的所有任务(Adapter显示任务数量用,数据来源唯一) - * @param positionId 位置ID - * @return 该位置绑定的所有任务(返回新列表,避免外部修改原数据) - */ public ArrayList getTasksByPositionId(String positionId) { ArrayList posTasks = new ArrayList(); if (TextUtils.isEmpty(positionId) || mAllTasks.isEmpty()) { return posTasks; } - // 筛选任务(Java 7 迭代器遍历,安全筛选) + // 筛选任务(Java 7 迭代器遍历) Iterator taskIter = mAllTasks.iterator(); while (taskIter.hasNext()) { PositionTaskModel task = taskIter.next(); @@ -193,55 +280,45 @@ public class MainService extends Service { return posTasks; } - /** - * 获取所有任务(Adapter全量刷新用,返回拷贝避免原数据被外部修改) - * @return 所有任务的拷贝列表 - */ public ArrayList getAllTasks() { - return mAllTasks; // Java 7 集合拷贝方式 + return mAllTasks; } - public void updateTask(PositionTaskModel updatedTask) { + public void updateTask(PositionTaskModel updatedTask) { if (updatedTask == null || updatedTask.getTaskId() == null) return; for (int i = 0; i < mAllTasks.size(); i++) { PositionTaskModel task = mAllTasks.get(i); if (updatedTask.getTaskId().equals(task.getTaskId())) { - mAllTasks.set(i, updatedTask); // 替换为更新后的任务 + mAllTasks.set(i, updatedTask); break; } - } - saveAllTasks(); // 持久化更新后的数据 + } + saveAllTasks(); } - // 4. 仅更新任务启用状态(优化性能,避免全量字段更新) public void updateTaskStatus(PositionTaskModel task) { if (task == null || task.getTaskId() == null) return; for (PositionTaskModel item : mAllTasks) { if (task.getTaskId().equals(item.getTaskId())) { - item.setIsEnable(task.isEnable()); // 只更新启用状态字段 + item.setIsEnable(task.isEnable()); break; } } - saveAllTasks(); // 持久化状态变更 + saveAllTasks(); } - - /** - * 删除任务(Adapter调用,通过迭代器安全删除,避免并发异常) - * @param taskId 待删除任务的ID - */ public void deleteTask(String taskId) { if (TextUtils.isEmpty(taskId) || mAllTasks.isEmpty()) { LogUtils.w(TAG, "deletePositionTask:任务ID为空或列表为空,删除失败"); return; } - // 迭代器删除(Java 7 唯一安全删除集合元素的方式) + // 迭代器删除(Java 7 安全方式) Iterator taskIter = mAllTasks.iterator(); while (taskIter.hasNext()) { PositionTaskModel task = taskIter.next(); if (taskId.equals(task.getTaskId())) { - taskIter.remove(); // 迭代器安全删除,无ConcurrentModificationException + taskIter.remove(); saveAllTasks(); notifyTaskUpdated(); LogUtils.d(TAG, "deletePositionTask:成功(任务ID=" + taskId + ")"); @@ -250,24 +327,16 @@ public class MainService extends Service { } } - /** - * 注册任务更新监听(Java 7 弱引用管理,避免内存泄漏) - * @param listener 任务更新监听者(如Adapter) - */ public void registerTaskUpdateListener(TaskUpdateListener listener) { if (listener == null) { LogUtils.w(TAG, "registerTaskUpdateListener:监听者为空,跳过"); return; } - synchronized (mListenerLock) { // 加锁保证多线程注册安全 + synchronized (mListenerLock) { mTaskListeners.add(new WeakReference(listener)); } } - /** - * 反注册任务更新监听(Java 7 迭代器清理,避免内存泄漏) - * @param listener 待反注册的监听者 - */ public void unregisterTaskUpdateListener(TaskUpdateListener listener) { if (listener == null) { LogUtils.w(TAG, "unregisterTaskUpdateListener:监听者为空,跳过"); @@ -277,7 +346,6 @@ public class MainService extends Service { Iterator> iter = mTaskListeners.iterator(); while (iter.hasNext()) { WeakReference ref = iter.next(); - // 清理目标监听者或已被回收的弱引用 if (ref.get() == listener || ref.get() == null) { iter.remove(); } @@ -285,16 +353,13 @@ public class MainService extends Service { } } - /** - * 通知所有任务监听者更新(Java 7 匿名内部类实现主线程回调,无Lambda) - */ private void notifyTaskUpdated() { synchronized (mListenerLock) { Iterator> iter = mTaskListeners.iterator(); while (iter.hasNext()) { final WeakReference ref = iter.next(); if (ref.get() != null) { - // 判断是否在主线程,不在则切换(Java 7 匿名Runnable,无Lambda) + // 主线程判断+切换(Java 7 匿名Runnable) if (Looper.myLooper() == Looper.getMainLooper()) { ref.get().onTaskUpdated(); } else { @@ -306,7 +371,7 @@ public class MainService extends Service { }); } } else { - iter.remove(); // 清理已回收的弱引用,避免内存泄漏 + iter.remove(); // 清理已回收弱引用 } } } @@ -314,19 +379,14 @@ public class MainService extends Service { // ========================================================================= - // 原有基础方法(Java 7 语法调整:移除所有Lambda/方法引用,用匿名内部类替代) + // 原有基础方法(Java 7 语法适配) // ========================================================================= - /** - * 获取服务单例(Java 7 静态同步方法,保证线程安全) - * @param context 上下文 - * @return MainService实例(未绑定成功时返回null) - */ public static synchronized MainService getInstance(Context context) { if (sInstance == null) { - if (AppConfigsUtil.getInstance(context).isEnableMainService(true)) { - Intent intent = new Intent(context.getApplicationContext(), MainService.class); - context.getApplicationContext().startService(intent); - } + if (AppConfigsUtil.getInstance(context).isEnableMainService(true)) { + Intent intent = new Intent(context.getApplicationContext(), MainService.class); + context.getApplicationContext().startService(intent); + } return null; } if (sAppContext == null) { @@ -335,18 +395,11 @@ public class MainService extends Service { return sInstance; } - /** - * 服务绑定回调(Java 7 基础实现,无默认方法等Java 8+特性) - */ @Override - public IBinder onBind(Intent intent) { - // 返回 LocalBinder,使Activity能通过Binder获取MainService实例 - return mLocalBinder; - } + public IBinder onBind(Intent intent) { + return mLocalBinder; // 返回LocalBinder暴露服务 + } - /** - * 服务创建回调(初始化单例、上下文、配置、服务连接等) - */ @Override public void onCreate() { LogUtils.d(TAG, "onCreate"); @@ -354,89 +407,76 @@ public class MainService extends Service { sInstance = this; sAppContext = getApplicationContext(); - // 初始化 LocalBinder(关键:将MainService实例传入Binder) - mLocalBinder = new LocalBinder(this); + // 初始化LocalBinder + mLocalBinder = new LocalBinder(this); _mIsServiceRunning = false; mAppConfigsUtil = AppConfigsUtil.getInstance(this); - // 初始化服务连接(Java 7 显式判断,无Optional) + // 初始化服务连接 if (mMyServiceConnection == null) { mMyServiceConnection = new MyServiceConnection(); } - if (mAppConfigsUtil.isEnableMainService(true)) { - run(); // 启动服务核心逻辑 - } + if (mAppConfigsUtil.isEnableMainService(true)) { + run(); // 启动服务核心逻辑 + } } - /** - * 服务核心逻辑(启动前台服务、初始化GPS、加载数据等) - * 【关键修改】新增定时器初始化,每1分钟调用任务校验 - */ public void run() { if (mAppConfigsUtil.isEnableMainService(true)) { if (!_mIsServiceRunning) { - _mIsServiceRunning = true; + _mIsServiceRunning = true; wakeupAndBindAssistant(); // 唤醒并绑定辅助服务 - // 启动前台服务(Java 7 显式调用,无方法引用) + // 启动前台服务 String initialStatus = "[ Positions ] is in Service."; NotificationUtil.createForegroundServiceNotification(this, initialStatus); startForeground(NotificationUtil.FOREGROUND_SERVICE_NOTIFICATION_ID, NotificationUtil.createForegroundServiceNotification(this, initialStatus)); - // 初始化GPS相关(Java 7 基础API调用) + // 初始化GPS相关 mLocationManager = (LocationManager) sInstance.getApplicationContext().getSystemService(Context.LOCATION_SERVICE); initGpsLocationListener(); startGpsLocation(); - // 加载本地数据(Java 7 静态方法调用,无方法引用) + // 加载本地数据 PositionModel.loadBeanList(MainService.this, mPositionList, PositionModel.class); PositionTaskModel.loadBeanList(MainService.this, mAllTasks, PositionTaskModel.class); - // 提示与日志(Java 7 基础调用) + // 提示与日志 ToastUtils.show(initialStatus); LogUtils.i(TAG, initialStatus); - // ---------------------- 关键新增:启动任务校验定时器 ---------------------- - //checkAllTaskTriggerCondition(); - initTaskCheckTimer(); + // 启动任务校验定时器 + //initTaskCheckTimer(); } } } - /** - * 获取服务运行状态 - * @return true=运行中,false=未运行 - */ public boolean isServiceRunning() { return _mIsServiceRunning; } - /** - * 服务销毁回调(清理资源、停止GPS、清空数据、反注册监听等) - * 【关键修改】新增定时器销毁,避免内存泄漏 - */ @Override public void onDestroy() { super.onDestroy(); sInstance = null; - // 清理资源(Java 7 顺序调用,无Stream等特性) + // 清理资源 stopGpsLocation(); clearAllData(); stopForeground(true); - // 清理所有监听者(Java 7 加锁+清空,避免内存泄漏) + // 清理所有监听者 synchronized (mListenerLock) { mGpsListeners.clear(); mTaskListeners.clear(); } - // ---------------------- 关键新增:销毁任务校验定时器 ---------------------- - destroyTaskCheckTimer(); - // 销毁距离计算线程池(原有逻辑,补充确保线程安全) + // 销毁所有定时器与线程池 + //destroyTaskCheckTimer(); + stopGpsStaticTimer(); // 新增:销毁静止时GPS定时任务 if (distanceExecutor != null && !distanceExecutor.isShutdown()) { distanceExecutor.shutdown(); } @@ -444,39 +484,33 @@ public class MainService extends Service { // 重置状态变量 _mIsServiceRunning = false; isGpsEnabled = false; + isGpsListening = false; // 新增:重置GPS监听状态 mLocationManager = null; } // ========================================================================= - // 位置操作方法(Java 7 语法,全迭代器/基础循环,无Java 8+特性) + // 位置操作方法(Java 7 语法) // ========================================================================= - /** - * 获取所有位置数据(返回原列表,供外部读取) - * @return 位置列表 - */ public ArrayList getPositionList() { return mPositionList; } - /** - * 获取当前GPS位置 - * @return 当前GPS定位模型(未获取时返回null) - */ public PositionModel getCurrentGpsPosition() { return _mCurrentGpsPosition; } - /** - * 删除指定位置(Java 7 迭代器安全删除) - * @param targetPosId 待删除位置的ID - */ + // 新增:判断GPS是否处于持续监听状态(给Receiver调用) + public boolean isGpsListening() { + return isGpsListening; + } + public void removePosition(String targetPosId) { if (TextUtils.isEmpty(targetPosId) || mPositionList.isEmpty()) { LogUtils.w(TAG, "removePosition:参数无效"); return; } - // 迭代器遍历删除(Java 7 安全方式) + // 迭代器遍历删除 Iterator iter = mPositionList.iterator(); while (iter.hasNext()) { PositionModel pos = iter.next(); @@ -488,16 +522,12 @@ public class MainService extends Service { } } - /** - * 更新位置数据(Java 7 基础for循环,无Stream筛选) - * @param updatedPos 更新后的位置模型 - */ public void updatePosition(PositionModel updatedPos) { if (updatedPos == null || TextUtils.isEmpty(updatedPos.getPositionId()) || mPositionList.isEmpty()) { LogUtils.w(TAG, "updatePosition:参数无效"); return; } - // 基础for循环查找并更新(Java 7 标准写法) + // 基础for循环查找并更新 for (int i = 0; i < mPositionList.size(); i++) { PositionModel oldPos = mPositionList.get(i); if (updatedPos.getPositionId().equals(oldPos.getPositionId())) { @@ -508,32 +538,23 @@ public class MainService extends Service { } } - /** - * 同步所有位置任务(全量替换,用于批量更新) - * @param newTaskList 新的任务列表 - */ public void syncAllPositionTasks(ArrayList newTaskList) { if (newTaskList == null) { LogUtils.w(TAG, "syncAllPositionTasks:新列表为空"); return; } - // 全量替换+持久化+通知(Java 7 基础集合操作) mAllTasks.clear(); mAllTasks.addAll(newTaskList); saveAllTasks(); notifyTaskUpdated(); } - /** - * 新增位置(Java 7 增强for循环去重,无Stream) - * @param newPos 待新增的位置模型 - */ public void addPosition(PositionModel newPos) { if (newPos == null) { LogUtils.w(TAG, "addPosition:位置为空"); return; } - // 位置去重(Java 7 增强for循环,无Stream.filter) + // 位置去重(增强for循环) boolean isDuplicate = false; for (PositionModel pos : mPositionList) { if (newPos.getPositionId().equals(pos.getPositionId())) { @@ -547,25 +568,16 @@ public class MainService extends Service { } } - /** - * 持久化位置数据(Java 7 静态方法调用,保持原逻辑) - */ void savePositionList() { LogUtils.d(TAG, String.format("savePositionList : size=%d", mPositionList.size())); PositionModel.saveBeanList(MainService.this, mPositionList, PositionModel.class); } - /** - * 持久化任务数据(Java 7 静态方法调用,保持原逻辑) - */ public void saveAllTasks() { LogUtils.d(TAG, String.format("saveTaskList : size=%d", mAllTasks.size())); PositionTaskModel.saveBeanList(MainService.this, mAllTasks, PositionTaskModel.class); } - /** - * 清空所有数据(位置+任务+GPS缓存,Java 7 集合clear方法) - */ public void clearAllData() { mPositionList.clear(); mAllTasks.clear(); @@ -573,10 +585,6 @@ public class MainService extends Service { LogUtils.d(TAG, "clearAllData:已清空所有数据"); } - /** - * 同步当前GPS位置(更新缓存+通知监听者+同步通知栏,全Java 7 语法) - * @param position 最新GPS位置模型 - */ public void syncCurrentGpsPosition(PositionModel position) { if (position == null) { LogUtils.w(TAG, "syncCurrentGpsPosition:位置为空"); @@ -586,27 +594,24 @@ public class MainService extends Service { LogUtils.d(TAG, "syncCurrentGpsPosition:成功(纬度=" + position.getLatitude() + ",经度=" + position.getLongitude() + ")"); notifyAllGpsListeners(position); - // 服务运行中才同步通知栏状态 + // 服务运行中同步通知栏状态 if (_mIsServiceRunning) { syncGpsStatusToNotification(); } } - /** - * 同步GPS状态到前台通知(Java 7 匿名Runnable切换主线程,无Lambda) - */ private void syncGpsStatusToNotification() { if (!_mIsServiceRunning || _mCurrentGpsPosition == null) { return; } - // 格式化通知内容(Java 7 String.format,无String.join等Java 8+方法) + // 格式化通知内容 final String gpsStatus = String.format( "GPS位置:北纬%.4f° 东经%.4f° | 可见位置:%d个", _mCurrentGpsPosition.getLatitude(), _mCurrentGpsPosition.getLongitude(), mVisiblePositionIds.size() ); - // 主线程判断+切换(Java 7 匿名内部类) + // 主线程切换 if (Looper.myLooper() == Looper.getMainLooper()) { NotificationUtil.updateForegroundServiceStatus(this, gpsStatus); } else { @@ -620,54 +625,43 @@ public class MainService extends Service { } - - // ========================================================================= - // 服务生命周期+辅助服务相关(Java 7 语法,无Lambda/方法引用) + // 服务生命周期+辅助服务相关(Java 7 语法) // ========================================================================= - /** - * 服务启动命令(每次startService调用时触发,重启服务核心逻辑) - */ @Override public int onStartCommand(Intent intent, int flags, int startId) { - boolean isSettingToEnable = false; - if (intent != null) { - isSettingToEnable = intent.getBooleanExtra(EXTRA_IS_SETTING_TO_ENABLE, false); - if (isSettingToEnable) { - run(); // 重启服务核心逻辑(保证服务启动后进入运行状态) - } - } + boolean isSettingToEnable = false; + if (intent != null) { + isSettingToEnable = intent.getBooleanExtra(EXTRA_IS_SETTING_TO_ENABLE, false); + if (isSettingToEnable) { + run(); // 重启服务核心逻辑 + } + } - // 如果被设置为自启动就返回START_STICKY:服务被异常杀死后,系统会尝试重启(原逻辑保留) - // 否则就启动默认参数 + // 根据是否自启动返回对应启动模式 return isSettingToEnable ? Service.START_STICKY : super.onStartCommand(intent, flags, startId); } - /** - * 服务连接内部类(Java 7 静态内部类,避免持有外部类强引用导致内存泄漏) - */ + // 服务连接内部类 private class MyServiceConnection implements ServiceConnection { @Override public void onServiceConnected(ComponentName name, IBinder service) { - // 原逻辑保留(空实现,如需绑定辅助服务可补充具体逻辑) + // 空实现(如需绑定辅助服务可补充逻辑) } @Override public void onServiceDisconnected(ComponentName name) { - // 辅助服务断开时,重新唤醒绑定(原逻辑保留) + // 辅助服务断开时重新绑定 if (mAppConfigsUtil.isEnableMainService(true)) { wakeupAndBindAssistant(); } } } - /** - * 唤醒并绑定辅助服务(检查服务状态,未存活则启动+绑定) - */ void wakeupAndBindAssistant() { - // 检查辅助服务是否存活(Java 7 静态方法调用,无方法引用) + // 检查辅助服务是否存活 if (!ServiceUtil.isServiceAlive(getApplicationContext(), AssistantService.class.getName())) { - // 启动+绑定辅助服务(Java 7 显式Intent,无Lambda) + // 启动+绑定辅助服务 startService(new Intent(MainService.this, AssistantService.class)); bindService(new Intent(MainService.this, AssistantService.class), mMyServiceConnection, Context.BIND_IMPORTANT); } @@ -675,45 +669,38 @@ public class MainService extends Service { // ========================================================================= - // GPS相关核心方法(Java 7 语法,匿名内部类实现LocationListener,无Lambda) + // GPS相关核心方法(Java 7 语法,匿名内部类实现) // ========================================================================= - /** - * 构造函数(Java 7 显式初始化线程池+GPS监听器,无默认构造函数简化) - */ public MainService() { distanceExecutor = Executors.newSingleThreadScheduledExecutor(); initGpsLocationListener(); } - /** - * 初始化GPS监听器(Java 7 匿名内部类实现LocationListener,无Lambda) - */ private void initGpsLocationListener() { LogUtils.d(TAG, "initGpsLocationListener"); mGpsLocationListener = new LocationListener() { @Override public void onLocationChanged(Location location) { if (location != null) { - // 封装GPS位置为PositionModel(Java 7 显式setter调用) + // 封装GPS位置 PositionModel gpsPos = new PositionModel(); gpsPos.setLatitude(location.getLatitude()); gpsPos.setLongitude(location.getLongitude()); gpsPos.setPositionId("CURRENT_GPS_POS"); gpsPos.setMemo("实时GPS位置"); - // 同步GPS位置+刷新距离+日志(原逻辑保留) + // 同步位置+校验任务 syncCurrentGpsPosition(gpsPos); - DistanceCalculatorUtil.getInstance(MainService.this).checkAllTaskTriggerCondition(gpsPos); + DistanceCalculatorUtil.getInstance(MainService.this).checkAllTaskTriggerCondition(gpsPos); LogUtils.d(TAG, "GPS位置更新:纬度=" + location.getLatitude() + ",经度=" + location.getLongitude()); } } @Override public void onStatusChanged(String provider, int status, Bundle extras) { - // 仅处理GPS_PROVIDER状态变化(Java 7 基础判断) if (provider.equals(LocationManager.GPS_PROVIDER)) { String statusDesc = ""; - // 状态枚举判断(Java 7 switch,无增强switch) + // Java 7 基础switch switch (status) { case LocationProvider.AVAILABLE: statusDesc = "GPS状态:已就绪(可用)"; @@ -733,7 +720,6 @@ public class MainService extends Service { @Override public void onProviderEnabled(String provider) { - // GPS启用时更新状态+通知+重启定位(Java 7 基础逻辑) if (provider.equals(LocationManager.GPS_PROVIDER)) { isGpsEnabled = true; String statusDesc = "GPS已开启(用户手动打开)"; @@ -746,9 +732,9 @@ public class MainService extends Service { @Override public void onProviderDisabled(String provider) { - // GPS禁用时清空状态+通知+提示(Java 7 基础逻辑) if (provider.equals(LocationManager.GPS_PROVIDER)) { isGpsEnabled = false; + isGpsListening = false; // 新增:GPS禁用时重置监听状态 _mCurrentGpsPosition = null; String statusDesc = "GPS已关闭(用户手动关闭)"; LogUtils.w(TAG, statusDesc); @@ -760,23 +746,19 @@ public class MainService extends Service { }; } - /** - * 检查GPS就绪状态(权限+启用状态,Java 7 基础权限判断,无Stream) - * @return true=GPS就绪,false=未就绪 - */ private boolean checkGpsReady() { - // 检查定位权限(Java 7 基础权限API,无权限请求框架依赖) + // 检查定位权限 isGpsPermissionGranted = checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; - // 初始化LocationManager(Java 7 显式判断,无Optional) + // 初始化LocationManager if (mLocationManager == null) { - mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); + mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); } - // 检查GPS是否启用(系统LocationManager API,Java 7 兼容) + // 检查GPS是否启用 isGpsEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); - // 权限未授予:提示+日志+通知 + // 权限未授予处理 if (!isGpsPermissionGranted) { String tip = "GPS准备失败:缺少精确定位权限"; LogUtils.e(TAG, tip); @@ -785,7 +767,7 @@ public class MainService extends Service { ToastUtils.show("请授予定位权限,否则无法获取GPS位置"); return false; } - // GPS未启用:提示+日志+通知 + // GPS未启用处理 if (!isGpsEnabled) { String tip = "GPS准备失败:系统GPS未开启"; LogUtils.e(TAG, tip); @@ -799,16 +781,13 @@ public class MainService extends Service { return true; } - /** - * 启动GPS定位(Java 7 异常处理,无try-with-resources,显式捕获SecurityException) - */ - private void startGpsLocation() { + public void startGpsLocation() { if (!checkGpsReady()) { return; } try { - // 注册GPS位置更新(Java 7 标准LocationManager API,指定Looper为主线程) + // 注册GPS位置更新 mLocationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, GPS_UPDATE_INTERVAL, @@ -817,7 +796,10 @@ public class MainService extends Service { Looper.getMainLooper() ); - // 获取最后已知GPS位置(缓存位置,避免首次定位等待) + // 新增:标记GPS进入持续监听状态 + isGpsListening = true; + + // 获取最后已知GPS位置 Location lastKnownLocation = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (lastKnownLocation != null) { PositionModel lastGpsPos = new PositionModel(); @@ -834,25 +816,22 @@ public class MainService extends Service { } } catch (SecurityException e) { - // 定位权限异常(Java 7 显式捕获,无Lambda异常处理) String error = "启动GPS失败(权限异常):" + e.getMessage(); LogUtils.e(TAG, error); notifyAllGpsStatusListeners(error); isGpsPermissionGranted = false; + isGpsListening = false; // 新增:异常时重置监听状态 updateNotificationGpsStatus("定位权限异常,无法获取GPS"); } catch (Exception e) { - // 其他异常(如LocationManager为空、系统服务异常等) String error = "启动GPS失败:" + e.getMessage(); LogUtils.e(TAG, error); notifyAllGpsStatusListeners(error); + isGpsListening = false; // 新增:异常时重置监听状态 updateNotificationGpsStatus("GPS启动失败,尝试重试..."); } } - /** - * 停止GPS定位(Java 7 异常处理,移除监听器避免内存泄漏) - */ - private void stopGpsLocation() { + public void stopGpsLocation() { // 校验参数:避免空指针+权限未授予时调用 if (mLocationManager != null && mGpsLocationListener != null && isGpsPermissionGranted) { try { @@ -860,26 +839,23 @@ public class MainService extends Service { String tip = "GPS定位已停止(移除监听器)"; LogUtils.d(TAG, tip); notifyAllGpsStatusListeners(tip); + isGpsListening = false; // 新增:停止监听时重置状态 } catch (Exception e) { String error = "停止GPS失败:" + e.getMessage(); LogUtils.e(TAG, error); notifyAllGpsStatusListeners(error); + isGpsListening = false; // 新增:异常时重置状态 } } } - /** - * 发送任务触发通知(更新前台通知+显示Toast,Java 7 匿名Runnable切换主线程) - * @param task 触发的任务 - * @param bindPos 任务绑定的位置 - * @param currentDistance 当前距离 - */ + // 发送任务触发通知 public void sendTaskTriggerNotification(final PositionTaskModel task, PositionModel bindPos, double currentDistance) { - /*if (!_mIsServiceRunning) { - return; - }*/ + if (!_mIsServiceRunning) { + return; + } - // 格式化通知内容(Java 7 String.format,无TextBlock等Java 15+特性) + // 格式化通知内容 final String triggerContent = String.format( "任务触发:%s\n位置:%s\n当前距离:%.1f米(条件:%s%d米)", task.getTaskDescription(), @@ -889,13 +865,13 @@ public class MainService extends Service { task.getDiscussDistance() ); - // 更新前台通知(主线程判断+切换) + // 更新前台通知 updateNotificationGpsStatus(triggerContent); - // 显示Toast(主线程安全调用,Java 7 匿名内部类) + // 显示Toast(主线程安全) if (Looper.myLooper() == Looper.getMainLooper()) { ToastUtils.show(triggerContent); - NotificationUtil.show(MainService.this, task.getTaskId(), task.getPositionId(), task.getTaskDescription()); + NotificationUtil.show(MainService.this, task.getTaskId(), task.getPositionId(), task.getTaskDescription()); } else { new Handler(Looper.getMainLooper()).post(new Runnable() { @Override @@ -908,14 +884,10 @@ public class MainService extends Service { LogUtils.i(TAG, "任务触发通知:" + triggerContent); } - - /** - * 更新前台通知的GPS状态(Java 7 主线程切换,匿名Runnable实现) - * @param statusText 通知显示的状态文本 - */ + // 更新前台通知的GPS状态 void updateNotificationGpsStatus(final String statusText) { if (_mIsServiceRunning) { - // 判断当前线程是否为主线程,避免UI操作在子线程 + // 主线程判断+切换 if (Looper.myLooper() == Looper.getMainLooper()) { NotificationUtil.updateForegroundServiceStatus(this, statusText); } else { @@ -931,12 +903,8 @@ public class MainService extends Service { // ========================================================================= - // GPS监听通知相关方法(Java 7 迭代器遍历弱引用集合,避免内存泄漏) + // GPS监听通知相关方法(Java 7 语法) // ========================================================================= - /** - * 通知所有GPS监听者位置更新(Java 7 迭代器+弱引用管理,无Stream) - * @param currentGpsPos 当前最新GPS位置 - */ public void notifyAllGpsListeners(PositionModel currentGpsPos) { if (currentGpsPos == null || mGpsListeners.isEmpty()) { return; @@ -949,17 +917,12 @@ public class MainService extends Service { if (listener != null) { notifySingleListener(listener, currentGpsPos); } else { - iter.remove(); // 清理已被GC回收的监听者,避免内存泄漏 + iter.remove(); // 清理已回收监听者 } } } } - /** - * 通知单个GPS监听者位置更新(主线程安全,Java 7 匿名Runnable) - * @param listener 单个监听者 - * @param currentGpsPos 当前GPS位置 - */ private void notifySingleListener(final GpsUpdateListener listener, final PositionModel currentGpsPos) { if (Looper.myLooper() == Looper.getMainLooper()) { listener.onGpsPositionUpdated(currentGpsPos); @@ -973,10 +936,6 @@ public class MainService extends Service { } } - /** - * 通知所有GPS监听者状态变化(如GPS开启/关闭、信号弱等,Java 7 迭代器) - * @param status GPS状态描述文本 - */ private void notifyAllGpsStatusListeners(final String status) { if (status == null || mGpsListeners.isEmpty()) { return; @@ -987,7 +946,7 @@ public class MainService extends Service { WeakReference ref = iter.next(); final GpsUpdateListener listener = ref.get(); if (listener != null) { - // 主线程切换,避免监听者在子线程处理UI + // 主线程切换,避免UI异常 if (Looper.myLooper() == Looper.getMainLooper()) { listener.onGpsStatusChanged(status); } else { @@ -1005,10 +964,6 @@ public class MainService extends Service { } } - /** - * 注册GPS更新监听(Java 7 弱引用添加,避免监听者内存泄漏) - * @param listener GPS更新监听者(如Activity/Adapter) - */ public void registerGpsUpdateListener(GpsUpdateListener listener) { if (listener == null) { LogUtils.w(TAG, "registerGpsUpdateListener:监听者为空"); @@ -1017,17 +972,13 @@ public class MainService extends Service { synchronized (mListenerLock) { mGpsListeners.add(new WeakReference(listener)); LogUtils.d(TAG, "GPS监听注册成功,当前数量:" + mGpsListeners.size()); - // 注册后立即推送当前GPS位置(避免监听者错过初始数据) + // 注册后推送当前GPS位置(避免监听者遗漏初始数据) if (_mCurrentGpsPosition != null) { notifySingleListener(listener, _mCurrentGpsPosition); } } } - /** - * 反注册GPS更新监听(Java 7 迭代器清理,避免内存泄漏) - * @param listener 待反注册的GPS监听者 - */ public void unregisterGpsUpdateListener(GpsUpdateListener listener) { if (listener == null) { LogUtils.w(TAG, "unregisterGpsUpdateListener:监听者为空"); @@ -1037,7 +988,6 @@ public class MainService extends Service { Iterator> iter = mGpsListeners.iterator(); while (iter.hasNext()) { WeakReference ref = iter.next(); - // 匹配目标监听者或已回收的弱引用,直接移除 if (ref.get() == listener || ref.get() == null) { iter.remove(); LogUtils.d(TAG, "GPS监听反注册成功,当前数量:" + mGpsListeners.size()); @@ -1047,20 +997,21 @@ public class MainService extends Service { } } - // 补全 LocalBinder 定义(与 LocationActivity 中的 LocalBinder 保持一致) - // 注意:若 LocationActivity 已定义 LocalBinder,此处可删除;建议统一在 MainService 中定义,避免重复 - public class LocalBinder extends android.os.Binder { - private MainService mService; - public LocalBinder(MainService service) { - this.mService = service; - } + // ========================================================================= + // LocalBinder 定义(与Activity绑定用,Java 7 内部类) + // ========================================================================= + public class LocalBinder extends android.os.Binder { + private MainService mService; - public MainService getService() { - return mService; - } - } + public LocalBinder(MainService service) { + this.mService = service; + } + public MainService getService() { + return mService; // 暴露MainService实例给绑定的Activity + } + } }