package com.github.antweb.donkey import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic import android.os.Environment import java.io.BufferedInputStream import java.io.File import java.io.FileInputStream import java.nio.ByteBuffer class FileTransfer( private val gatt: BluetoothGatt, private val dataCharacteristic: BluetoothGattCharacteristic, private val mtu: Int ) { private val filePath = "/Download/SEND.txt" private val iterator = openFile().iterator() private var offset: Int = 0 private fun openFile(): ByteArray { // TODO: Don't listen to Android Docs, use stuff that is not deprecated val file = File( Environment.getExternalStorageDirectory() .absolutePath, filePath ) val size = file.length() val bytes = ByteArray(size.toInt()) val buf = BufferedInputStream(FileInputStream(file)) buf.read(bytes, 0, bytes.size) buf.close() return bytes } fun sendFile() { // Send first chunk sendNext() } fun sendNext() { if (!iterator.hasNext()) { return } gatt?.beginReliableWrite() val chunk = mutableListOf() for (i in 0 until (mtu - 5)) { chunk.add(iterator.next()) } // Our packet: // 4 byte header + chunk val header = offset offset += chunk.size val sendBuffer = ByteBuffer.allocate(chunk.size + 4) sendBuffer.putInt(header) sendBuffer.put(chunk.toByteArray()) dataCharacteristic?.value = sendBuffer.array() gatt?.writeCharacteristic(dataCharacteristic) // This will trigger the onCharacteristicWrite callback once the other side ACKs // In there, we can call the actual gatt?.executeReliableWrite() } }