Compare commits
5 Commits
377ec4de09
...
positions
| Author | SHA1 | Date | |
|---|---|---|---|
| 2d3cee1121 | |||
|
|
2be6d5e122 | ||
| 6376ff4ccf | |||
|
|
dd20060754 | ||
|
|
298b337392 |
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#Created by .winboll/winboll_app_build.gradle
|
||||||
#Tue Oct 28 13:36:57 HKT 2025
|
#Tue Oct 28 20:03:59 HKT 2025
|
||||||
stageCount=16
|
stageCount=18
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=15.0
|
baseVersion=15.0
|
||||||
publishVersion=15.0.15
|
publishVersion=15.0.17
|
||||||
buildCount=0
|
buildCount=0
|
||||||
baseBetaVersion=15.0.16
|
baseBetaVersion=15.0.18
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="cc.winboll.studio.positions">
|
package="cc.winboll.studio.positions">
|
||||||
|
|
||||||
|
<!-- 1. 声明GPS权限 -->
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
|
||||||
<!-- 前台服务权限(可选,提升后台定位稳定性,避免服务被回收) -->
|
<!-- 前台服务权限(可选,提升后台定位稳定性,避免服务被回收) -->
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
@@ -61,6 +64,17 @@
|
|||||||
<service android:name=".services.AssistantService"/>
|
<service android:name=".services.AssistantService"/>
|
||||||
|
|
||||||
<service android:name=".services.DistanceRefreshService"/>
|
<service android:name=".services.DistanceRefreshService"/>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 2. 注册运动状态Receiver -->
|
||||||
|
<receiver
|
||||||
|
android:name="cc.winboll.studio.positions.receivers.MotionStatusReceiver"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="cc.winboll.studio.positions.ACTION_MOTION_STATUS" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
package cc.winboll.studio.positions.receivers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -111,17 +111,15 @@ public class DistanceCalculatorUtil {
|
|||||||
LogUtils.d(TAG, "传入坐标参数为空,退出函数。");
|
LogUtils.d(TAG, "传入坐标参数为空,退出函数。");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mGpsPositionCalculated == null) {
|
|
||||||
mGpsPositionCalculated = currentGpsPosition;
|
|
||||||
LogUtils.d(TAG, "最后计算位置记录为空,现在使用新坐标为初始化。");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算频率控制模块
|
// 计算频率控制模块
|
||||||
//
|
//
|
||||||
// 计算与最近一次GPS计算的时间间隔
|
// 计算与最近一次GPS计算的时间间隔
|
||||||
long nCalculatedTimeBettween = System.currentTimeMillis() - mLastCalculatedTime;
|
long nCalculatedTimeBettween = System.currentTimeMillis() - mLastCalculatedTime;
|
||||||
// 计算跳跃距离
|
// 计算跳跃距离
|
||||||
double jumpDistance = calculateHaversineDistance(mGpsPositionCalculated.getLatitude(), mGpsPositionCalculated.getLongitude(), currentGpsPosition.getLatitude(), currentGpsPosition.getLongitude());
|
double gpsPositionCalculatedLatitude = mGpsPositionCalculated == null ?0.0f: mGpsPositionCalculated.getLatitude();
|
||||||
|
double gpsPositionCalculatedLongitude = mGpsPositionCalculated == null ?0.0f: mGpsPositionCalculated.getLongitude();
|
||||||
|
double jumpDistance = calculateHaversineDistance(gpsPositionCalculatedLatitude, gpsPositionCalculatedLongitude, currentGpsPosition.getLatitude(), currentGpsPosition.getLongitude());
|
||||||
if (jumpDistance < mMinjumpDistance) {
|
if (jumpDistance < mMinjumpDistance) {
|
||||||
LogUtils.d(TAG, String.format("checkAllTaskTriggerCondition:跳跃距离%f,小于50米。", jumpDistance));
|
LogUtils.d(TAG, String.format("checkAllTaskTriggerCondition:跳跃距离%f,小于50米。", jumpDistance));
|
||||||
// 跳跃距离小于最小有效跳跃值
|
// 跳跃距离小于最小有效跳跃值
|
||||||
@@ -132,22 +130,33 @@ public class DistanceCalculatorUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogUtils.d(TAG, String.format("checkAllTaskTriggerCondition:跳跃距离%f,与上次计算间隔%d,启动任务数据计算。", jumpDistance, nCalculatedTimeBettween));
|
if (mGpsPositionCalculated == null) {
|
||||||
|
mGpsPositionCalculated = currentGpsPosition;
|
||||||
|
LogUtils.d(TAG, "最后计算位置记录为空,现在使用新坐标为初始化。");
|
||||||
|
}
|
||||||
|
|
||||||
|
LogUtils.d(TAG, String.format("checkAllTaskTriggerCondition:跳跃距离%f,与上次计算间隔%d,现在启动任务数据计算。", jumpDistance, nCalculatedTimeBettween));
|
||||||
|
|
||||||
// 获取位置任务基础数据
|
// 获取位置任务基础数据
|
||||||
MainService mainService = MainService.getInstance(mContext);
|
MainService mainService = MainService.getInstance(mContext);
|
||||||
mPositionList = mainService.getPositionList();
|
mPositionList = mainService.getPositionList();
|
||||||
mAllTasks = mainService.getAllTasks();
|
mAllTasks = mainService.getAllTasks();
|
||||||
|
|
||||||
// 任务为空,跳过校验。
|
// 位置数据为空,跳过校验。
|
||||||
if (mPositionList.isEmpty() || mAllTasks.isEmpty()) {
|
if (mPositionList.isEmpty()) {
|
||||||
LogUtils.d(TAG, "checkAllTaskTriggerCondition:任务数据为空,跳过校验。");
|
LogUtils.d(TAG, "checkAllTaskTriggerCondition:位置数据为空,跳过距离计算。");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新所有位置点的位置距离数据
|
// 更新所有位置点的位置距离数据
|
||||||
refreshRealPositionDistance(currentGpsPosition);
|
refreshRealPositionDistance(currentGpsPosition);
|
||||||
|
|
||||||
|
// 任务数据为空,跳过校验。
|
||||||
|
if (mAllTasks.isEmpty()) {
|
||||||
|
LogUtils.d(TAG, "checkAllTaskTriggerCondition:任务数据为空,跳过任务提醒检查计算。");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 迭代器遍历任务(Java 7 安全遍历,避免并发修改异常)
|
// 迭代器遍历任务(Java 7 安全遍历,避免并发修改异常)
|
||||||
Iterator<PositionTaskModel> taskIter = mAllTasks.iterator();
|
Iterator<PositionTaskModel> taskIter = mAllTasks.iterator();
|
||||||
while (taskIter.hasNext()) {
|
while (taskIter.hasNext()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user