@@ -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 ) ;
}
}