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
+ }
+ }
}