#android #kotlin #bluetooth-lowenergy
#Android #kotlin #bluetooth-низкое энергопотребление
Вопрос:
У меня есть приемник службы, который обрабатывает обратные вызовы, связанные с событиями BLE GATT (подключение, отключение и т. Д.).
В ситуациях, когда я отключаю устройство BLE для имитации отключения, срабатывает событие отключения, и мой вызов завершается с context.unbindService(serviceConnection)
ошибкой. Я проверил несколько очевидных ошибок (разные контексты, нулевое подключение к службе и т. Д.) И Не могу найти ошибку. Почему я получаю это исключение?
Вот трассировка:
E / AndroidRuntime: ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: основной процесс: com.example.ktest, PID: 6372 java.lang.Исключение IllegalArgumentException: служба не зарегистрирована: com.example.ktest.ble.BLEConnectionManager $ServiceConnection $ 1 @ 493960 в android.app.LoadedApk.forgetServiceDispatcher(LoadedApk.java: 1602) в android.app.ContextImpl.unbindService(ContextImpl.java:1710) в android.content.ContextWrapper.unbindService(ContextWrapper.java:717) в com.example.ktest.ble.BLEConnectionManager.unbindService(BLEConnectionManager.kt:81) в com.example.ktest.foo.FooActivity.disconnect(FooActivity.kt: 268) в com.example.ktest.foo.FooActivity.access$disconnect(FooActivity.kt:47) в com.example.ktest.foo.FooActivity$gattUpdateReceiver$1$onReceive$ 1.run(FooActivity.kt:190) в android.os.Handler.handleCallback(Handler.java:873) в android.os.Handler.DispatchMessage(Handler.java:99) в android.os.Looper.loop(Looper.java:193) в android.app.ActivityThread.main(ActivityThread.java:6863) в java.lang.reflect.Method.invoke(собственный метод) в com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537) в com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Вот функция отключения, которая вызывается в соответствии с трассировкой:
private fun disconnect() {
BLEConnectionManager.unBindService(this@FooActivity) // FAILS HERE
unregisterServiceReceiver()
val intent = Intent(this, ConnectDeviceActivity::class.java)
startActivity(intent)
finish() // close activity
}
Служба была привязана с использованием того же контекста (из FooActivity.onStart()
):
BLEConnectionManager.bindService(this@FooActivity)
Таким образом, при вызове проблем нет BLEConnectionManager.bindService()
:
fun bindService(context: Context) {
if (serviceConnection != null amp;amp; isBound) {
Log.w(TAG, "Service is already bound")
} else {
val gattServiceIntent = Intent(context, BLEService::class.java)
if (context != null) {
isBound = context.bindService(
gattServiceIntent,
serviceConnection,
Context.BIND_AUTO_CREATE)
}
Log.i(TAG, "BLEService now bound, isBound is now $isBound")
}
}
Вот BLEConnectionManager.unBindService()
fun unBindService(context: Context) {
// NOTE I've logged the service and connection here, they're non-null and BLE works fine in this Activity
if (serviceConnection != null amp;amp; isBound) context.unbindService(serviceConnection)
}
Итак, что я пропустил, и что я делаю не так, что вызывает исключение?
Ответ №1:
Я вызывал unbind слишком много раз (для службы, которая ранее не была привязана и с тех пор не была привязана снова). Это произошло потому, что я забыл установить свой isBound
флаг BLEConnectionManager в методе unbind этого класса. Упс.