我正在尝试构建一个 Android 服务,该服务继续从我的 jetpack compose 应用程序进行蓝牙低功耗扫描,该应用程序与 ble 信标交互。我现在的目标只是在将应用程序置于后台后启动前台服务。我的代码编译后,跟踪进程的日志语句正常显示在我的 logcat 中,但服务进程在启动时就结束了,并且通知从未出现在状态栏上。
这是我的蓝牙服务类代码
@AndroidEntryPoint
class BluetoothScanService : Service() {
@Inject lateinit var bluetoothUtils: BluetoothUtils
@Inject lateinit var sharedDataManager: SharedDataManager
@Inject lateinit var bleScanCallback: BleScanCallback
override fun onCreate() {
super.onCreate()
// Initialize your BluetoothUtils, SharedDataManager, and ScanCallback here
Log.i("foreground", "Inside onCreate in Bluetooth Service")
val notification = createForegroundNotification()
startForeground(1, notification)
Log.i("foreground", "BluetoothUtils: $bluetoothUtils")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (intent == null) {
Log.e("foreground", "Received null intent in onStartCommand")
return START_NOT_STICKY // or return an appropriate value
}
Log.i("foreground", "Inside onStartCommand in Bluetooth Service")
// Start the Bluetooth scan in the foreground service
bluetoothUtils.startScanning(bleScanCallback)
return START_NOT_STICKY
}
private fun createForegroundNotification(): Notification {
val channelId = "BluetoothScanChannel"
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Create notification channel for Android 8.0 and above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
channelId,
"Bluetooth Scan",
NotificationManager.IMPORTANCE_DEFAULT
)
notificationManager.createNotificationChannel(channel)
}
// Create the notification
val notification = NotificationCompat.Builder(this, channelId)
.setContentTitle("Bluetooth Scanning")
.setContentText("Bluetooth scanning is running in the background.")
//.setSmallIcon(R.drawable.ic_bluetooth)
.build()
return notification
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
}
这就是我从 MainActivity 中调用 onPause() 和 onResume() 中的服务的方式(我只有一个活动,因为我正在使用 Jetpack compose。我的应用程序中的每个屏幕都是可组合的)。
override fun onPause(){
super.onPause()
Log.i("foreground", "Inside onPause in MainActivity")
val intent = Intent(this, BluetoothScanService::class.java)
Log.i("foreground", "the intent ${intent}")
startService(intent)
}
override fun onResume() {
super.onResume()
Log.i("foreground", "Inside onResume in MainActivity")
val intent = Intent(this, BluetoothScanService::class.java)
stopService(intent)
}
这是我的 logcat 结果
2025-01-21 13:49:32.544 32677-32677 foreground com.myApp.bleApp I Inside onPause in MainActivity
2025-01-21 13:49:32.545 32677-32677 foreground com.myApp.bleApp I the intent Intent { cmp=com.myApp.bleApp/.common.foregroundServices.BluetoothScanService }
2025-01-21 13:49:32.590 32677-32677 foreground com.myApp.bleApp I Inside onCreate in Bluetooth Service
2025-01-21 13:49:32.691 32677-32677 foreground com.myApp.bleApp I BluetoothUtils: com.myApp.bleApp.hardware.bluetooth.BluetoothUtils@7da3008
2025-01-21 13:49:32.693 32677-32677 foreground com.myApp.bleApp I Inside onStartCommand in Bluetooth Service
---------------------------- PROCESS ENDED (32677) for package com.myApp.bleApp ----------------------------
如果我使用 return START_STICKY 而不是 return START_NOT_STICKY,该过程仍然会结束,但会以空意图重新启动,并且通知会出现在我的状态栏中。这些是我的 logcat 结果
2025-01-21 13:51:45.677 1960-1960 foreground com.myApp.bleApp I Inside onPause in MainActivity
2025-01-21 13:51:45.678 1960-1960 foreground com.myApp.bleApp I the intent Intent { cmp=com.myApp.bleApp/.common.foregroundServices.BluetoothScanService }
2025-01-21 13:51:45.739 1960-1960 foreground com.myApp.bleApp I Inside onCreate in Bluetooth Service
2025-01-21 13:51:45.809 1960-1960 foreground com.myApp.bleApp I BluetoothUtils: com.myApp.bleApp.hardware.bluetooth.BluetoothUtils@eaa3f16
2025-01-21 13:51:45.811 1960-1960 foreground com.myApp.bleApp I Inside onStartCommand in Bluetooth Service
---------------------------- PROCESS ENDED (1960) for package com.myApp.bleApp ----------------------------
---------------------------- PROCESS STARTED (2496) for package com.myApp.bleApp ----------------------------
2025-01-21 13:51:49.731 2496-2496 foreground com.myApp.bleApp I Inside onCreate in Bluetooth Service
2025-01-21 13:51:49.741 2496-2496 foreground com.myApp.bleApp I BluetoothUtils: com.myApp.bleApp.hardware.bluetooth.BluetoothUtils@861bce1
2025-01-21 13:51:49.742 2496-2496 foreground com.myApp.bleApp E Received null intent in onStartCommand
这是进程结束时出现的错误
致命异常:主要 进程:com.myApp.bleApp,PID:7298 java.lang.StackOverflowError:堆栈大小8188KB 在 com.myapp.bleApp.hardware.bluetooth.bleScanner.BleScanCallback.onScanFailed(BleScanCallback.kt:237)
这就是我的 bleScanCallback 类 onScanFailed(errorCode) 发生错误的地方
override fun onScanFailed(errorCode: Int) {
super.onScanFailed(errorCode)
// Handle scan failure
onScanFailed(errorCode)
}
我现在唯一想要发生的事情是,当应用程序在后台时,服务保持活动状态,并且我希望看到通知出现在状态栏中。 我该如何解决这个问题?
这非常元!问题是函数正在调用自身并且可能处于无限循环中,这会导致 StackOverflowError。
override fun onScanFailed(errorCode: Int) {
super.onScanFailed(errorCode)
// Handle scan failure
onScanFailed(errorCode) // Do you really want to call recursively?
}