using Android.App; using Android.Content; using Android.OS; using AndroidX.Core.App; using Android.Content.PM; using HeartRateMonitorAndroid.Services; using Microsoft.Extensions.DependencyInjection; using Java.Lang; using Android.Provider; using Android.App.Job; using Resource = Android.Resource; namespace HeartRateMonitorAndroid.Platforms.Android { [Service(Name = "com.nuanrmxi.heartratemonitor.HeartRateKeepAliveService", Enabled = true, Exported = false, ForegroundServiceType = ForegroundService.TypeDataSync | ForegroundService.TypeLocation)] public class HeartRateKeepAliveService : Service { private const int NOTIFICATION_ID = 1001; private const string CHANNEL_ID = "HeartRateMonitorChannel"; private const string CHANNEL_NAME = "心率监测服务"; private const int REPORT_INTERVAL_MS = 1000; // 1秒汇报间隔 private PowerManager.WakeLock _wakeLock; private WebSocketService.HeartRateWebSocketClient _webSocketClient; private BluetoothService _bluetoothService; private HeartRateDataService _dataService; private bool _isServiceRunning = false; // 定时汇报相关 private System.Threading.Timer _reportTimer; private int _latestHeartRate = 0; private readonly object _heartRateLock = new object(); public override void OnCreate() { base.OnCreate(); CreateNotificationChannel(); AcquireWakeLock(); InitializeServices(); } public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId) { if (!_isServiceRunning) { StartForegroundService(); _isServiceRunning = true; } // 返回START_STICKY确保服务被系统杀死后会重启 return StartCommandResult.Sticky; } public override IBinder OnBind(Intent intent) { return null; } private void CreateNotificationChannel() { if (Build.VERSION.SdkInt >= BuildVersionCodes.O) { var channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationImportance.Low) { Description = "心率监测后台服务通知" }; channel.SetShowBadge(false); channel.EnableLights(false); channel.EnableVibration(false); var notificationManager = GetSystemService(NotificationService) as NotificationManager; notificationManager?.CreateNotificationChannel(channel); } } private void StartForegroundService() { var intent = new Intent(this, typeof(MainActivity)); intent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop); var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Immutable); var notification = new NotificationCompat.Builder(this, CHANNEL_ID) .SetContentTitle("心率监测服务") .SetContentText("正在后台监测心率数据") .SetSmallIcon(Resource.Drawable.abc_dialog_material_background) .SetContentIntent(pendingIntent) .SetOngoing(true) .SetPriority(NotificationCompat.PriorityLow) .SetCategory(NotificationCompat.CategoryService) .Build(); StartForeground(NOTIFICATION_ID, notification); } private void AcquireWakeLock() { var powerManager = GetSystemService(PowerService) as PowerManager; _wakeLock = powerManager?.NewWakeLock(WakeLockFlags.Partial, "HeartRateMonitor::KeepAlive"); _wakeLock?.Acquire(); } private void InitializeServices() { try { System.Diagnostics.Debug.WriteLine("KeepAliveService: 开始初始化服务"); // 获取数据服务实例 _dataService = HeartRateDataService.Instance; _dataService.UpdateServiceStatus(false, "正在初始化服务...", false); // 初始化蓝牙服务 _bluetoothService = new BluetoothService(); _bluetoothService.StatusUpdated += OnBluetoothStatusUpdated; _bluetoothService.HeartRateUpdated += OnHeartRateDataReceived; _bluetoothService.DeviceDiscovered += OnDeviceDiscovered; System.Diagnostics.Debug.WriteLine("KeepAliveService: 蓝牙服务已初始化"); // 初始化WebSocket客户端 Task.Run(async () => await InitializeWebSocketAsync()); // 启动蓝牙连接 Task.Run(async () => await StartBluetoothMonitoringAsync()); } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"InitializeServices Error: {ex.Message}"); _dataService?.UpdateServiceStatus(false, "服务初始化失败", false); } } private async Task InitializeWebSocketAsync() { try { var serverUrl = GetServerUrl(); if (!string.IsNullOrEmpty(serverUrl)) { _webSocketClient = new WebSocketService.HeartRateWebSocketClient(serverUrl); await _webSocketClient.ConnectAsync(); _dataService?.UpdateServiceStatus(true, "后台服务运行中", true, serverUrl); System.Diagnostics.Debug.WriteLine($"KeepAliveService: WebSocket连接成功: {serverUrl}"); } else { _dataService?.UpdateServiceStatus(true, "后台服务运行中", false); System.Diagnostics.Debug.WriteLine("KeepAliveService: 无法获取服务器URL,WebSocket未连接"); } } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"KeepAliveService: WebSocket连接失败: {ex.Message}"); _dataService?.UpdateServiceStatus(true, "后台服务运行中", false); } } private async Task StartBluetoothMonitoringAsync() { try { System.Diagnostics.Debug.WriteLine("KeepAliveService: 开始蓝牙监测"); // 检查蓝牙状态 _bluetoothService.CheckBluetoothState(); if (_bluetoothService.IsBluetoothAvailable) { _dataService?.UpdateDeviceStatus(false, "", "正在扫描心率设备..."); // 开始扫描心率设备 await _bluetoothService.StartScanAsync(); System.Diagnostics.Debug.WriteLine("KeepAliveService: 蓝牙扫描已启动"); } else { _dataService?.UpdateDeviceStatus(false, "", "蓝牙不可用"); System.Diagnostics.Debug.WriteLine("KeepAliveService: 蓝牙不可用"); } } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"KeepAliveService: 蓝牙监测启动失败: {ex.Message}"); _dataService?.UpdateDeviceStatus(false, "", "蓝牙监测启动失败"); } } private void OnBluetoothStatusUpdated(string status) { System.Diagnostics.Debug.WriteLine($"KeepAliveService: 蓝牙状态更新: {status}"); _dataService?.UpdateDeviceStatus(false, "", status); } private void OnHeartRateDataReceived(int heartRate) { try { //System.Diagnostics.Debug.WriteLine($"KeepAliveService: 收到心率数据: {heartRate} bpm"); // 只更新最新心率值,不立即发送数据 lock (_heartRateLock) { _latestHeartRate = heartRate; } //System.Diagnostics.Debug.WriteLine($"KeepAliveService: 心率数据已更新: {heartRate} bpm"); } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"KeepAliveService: 处理心率数据失败: {ex.Message}"); } } private async void OnDeviceDiscovered(Plugin.BLE.Abstractions.Contracts.IDevice device) { try { System.Diagnostics.Debug.WriteLine($"KeepAliveService: 发现设备: {device.Name ?? "未知设备"}"); _dataService?.UpdateDeviceStatus(false, device.Name ?? "未知设备", $"发现设备: {device.Name ?? "未知设备"}"); // 尝试连接设备 await _bluetoothService.ConnectToDeviceAsync(device); if (_bluetoothService.ConnectedDevice != null) { System.Diagnostics.Debug.WriteLine($"KeepAliveService: 设备连接成功: {device.Name}"); _dataService?.UpdateDeviceStatus(true, device.Name ?? "未知设备", $"已连接: {device.Name ?? "未知设备"}"); _dataService?.ResetSessionData(); // 重置会话数据 // 启动定时汇报 StartPeriodicReporting(); } } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"KeepAliveService: 设备连接失败: {ex.Message}"); _dataService?.UpdateDeviceStatus(false, "", "设备连接失败"); } } /// /// 启动定时汇报(每秒一次) /// private void StartPeriodicReporting() { try { // 停止现有定时器 StopPeriodicReporting(); // 启动新的定时器 _reportTimer = new System.Threading.Timer(OnPeriodicReport, null, TimeSpan.FromMilliseconds(REPORT_INTERVAL_MS), TimeSpan.FromMilliseconds(REPORT_INTERVAL_MS)); System.Diagnostics.Debug.WriteLine("KeepAliveService: 定时汇报已启动,间隔1秒"); } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"KeepAliveService: 启动定时汇报失败: {ex.Message}"); } } /// /// 停止定时汇报 /// private void StopPeriodicReporting() { try { _reportTimer?.Dispose(); _reportTimer = null; System.Diagnostics.Debug.WriteLine("KeepAliveService: 定时汇报已停止"); } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"KeepAliveService: 停止定时汇报失败: {ex.Message}"); } } /// /// 定时汇报回调方法 /// private async void OnPeriodicReport(object state) { try { if (!_isServiceRunning) return; int currentHeartRate; lock (_heartRateLock) { currentHeartRate = _latestHeartRate; } // 无论心率数据是否更新,都进行汇报 //System.Diagnostics.Debug.WriteLine($"KeepAliveService: 定时汇报 - 心率: {currentHeartRate} bpm"); // 更新数据服务(触发UI更新) if (currentHeartRate > 0) { _dataService?.UpdateHeartRateData(currentHeartRate); } // 发送到WebSocket服务器 if (_webSocketClient != null) { await SendHeartRateToServerAsync(currentHeartRate); } // 更新通知 var message = currentHeartRate > 0 ? $"最新心率: {currentHeartRate} BPM" : "等待心率数据..."; UpdateNotification(message); } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"KeepAliveService: 定时汇报失败: {ex.Message}"); } } private async Task SendHeartRateToServerAsync(int heartRate) { try { if (_webSocketClient == null) return; var data = new WebSocketService.HeartRateData { HeartRate = heartRate, Timestamp = DateTime.Now, DeviceName = _bluetoothService?.ConnectedDevice?.Name ?? "未知设备" }; await _webSocketClient.SendHeartRateDataAsync(data); //System.Diagnostics.Debug.WriteLine($"KeepAliveService: 心率数据已发送到服务器: {heartRate} bpm"); } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"KeepAliveService: 发送心率数据失败: {ex.Message}"); _dataService?.UpdateServiceStatus(true, "后台服务运行中", false); } } private void UpdateNotification(string message) { try { var intent = new Intent(this, typeof(MainActivity)); var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.UpdateCurrent | PendingIntentFlags.Immutable); var notification = new NotificationCompat.Builder(this, CHANNEL_ID) .SetContentTitle("心率监测服务") .SetContentText(message) .SetSmallIcon(Resource.Drawable.abc_dialog_material_background) .SetContentIntent(pendingIntent) .SetOngoing(true) .Build(); var notificationManager = GetSystemService(NotificationService) as NotificationManager; notificationManager?.Notify(NOTIFICATION_ID, notification); } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"UpdateNotification Error: {ex.Message}"); } } private string GetServerUrl() { try { // 从资源文件读取服���器地址 using var stream = Assets.Open("server.txt"); using var reader = new System.IO.StreamReader(stream); return reader.ReadToEnd().Trim(); } catch { return "wss://ws.nuanr-mxi.com/ws"; // 默认服务器地址 } } public override void OnDestroy() { try { _isServiceRunning = false; // 停止定时汇报 StopPeriodicReporting(); // 清理资源 _bluetoothService?.Dispose(); _webSocketClient?.Dispose(); _wakeLock?.Release(); _dataService?.UpdateServiceStatus(false, "服务已停止", false); System.Diagnostics.Debug.WriteLine("KeepAliveService: 服务已停止"); } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"KeepAliveService: 服务停止时发生错误: {ex.Message}"); } base.OnDestroy(); } public override void OnTaskRemoved(Intent rootIntent) { // 当任务被移除时重启服务 var intent = new Intent(this, typeof(HeartRateKeepAliveService)); StartForegroundService(intent); base.OnTaskRemoved(rootIntent); } } }