|
| 1 | +package ru.tetraquark.mpp.bluetooth |
| 2 | + |
| 3 | +import android.bluetooth.BluetoothSocket |
| 4 | +import java.io.IOException |
| 5 | +import java.util.concurrent.ConcurrentHashMap |
| 6 | +import java.util.concurrent.ExecutorService |
| 7 | +import java.util.concurrent.Executors |
| 8 | +import java.util.concurrent.atomic.AtomicBoolean |
| 9 | + |
| 10 | +actual class BluetoothConnection( |
| 11 | + actual val remoteDevice: BluetoothRemoteDevice, |
| 12 | + private val bluetoothSocket: BluetoothSocket, |
| 13 | + private val byteBufferLength: Int = 1024, |
| 14 | + private val connectionExecutor: ExecutorService = Executors.newSingleThreadExecutor() |
| 15 | +) { |
| 16 | + |
| 17 | + private val inputStream = bluetoothSocket.inputStream |
| 18 | + private val outputStream = bluetoothSocket.outputStream |
| 19 | + |
| 20 | + private val isRunning = AtomicBoolean(false) |
| 21 | + private val listenersMap = ConcurrentHashMap<Int, ConnectionListener>() |
| 22 | + |
| 23 | + init { |
| 24 | + runSocketObserver() |
| 25 | + } |
| 26 | + |
| 27 | + actual fun isConnected(): Boolean = isRunning.get() |
| 28 | + |
| 29 | + actual fun send(data: ByteArray) { |
| 30 | + outputStream.write(data) |
| 31 | + } |
| 32 | + |
| 33 | + actual fun close() { |
| 34 | + try { |
| 35 | + isRunning.set(false) |
| 36 | + connectionExecutor.shutdown() |
| 37 | + bluetoothSocket.close() |
| 38 | + |
| 39 | + notifyObservers { |
| 40 | + onClose() |
| 41 | + } |
| 42 | + } catch (ioException: IOException) { } |
| 43 | + } |
| 44 | + |
| 45 | + actual fun addConnectionListener(listener: ConnectionListener) { |
| 46 | + listenersMap[listener.hashCode()] = listener |
| 47 | + } |
| 48 | + |
| 49 | + actual fun removeConnectionListener(listener: ConnectionListener) { |
| 50 | + listenersMap.remove(listener.hashCode()) |
| 51 | + } |
| 52 | + |
| 53 | + private fun runSocketObserver() { |
| 54 | + isRunning.set(true) |
| 55 | + |
| 56 | + connectionExecutor.execute { |
| 57 | + while(isRunning.get()) { |
| 58 | + try { |
| 59 | + val buffer = ByteArray(byteBufferLength) |
| 60 | + inputStream.read(buffer) |
| 61 | + |
| 62 | + notifyObservers { |
| 63 | + onReceived(buffer) |
| 64 | + } |
| 65 | + } catch (ioException: IOException) { |
| 66 | + notifyObservers { |
| 67 | + onError(ioException) |
| 68 | + } |
| 69 | + } |
| 70 | + } |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + private inline fun notifyObservers(block: ConnectionListener.() -> Unit) { |
| 75 | + listenersMap.forEach { |
| 76 | + block(it.value) |
| 77 | + } |
| 78 | + } |
| 79 | + |
| 80 | +} |
0 commit comments