#android #bluetooth #uuid
Вопрос:
Я хочу знать, каковы возможные причины, по которым приложение, которое у меня есть, не может подключиться к нужному устройству Bluetooth.
Приложение, которое у меня есть, я получил от группы фрилансеров, и мне поручено использовать его в некоторых тестах. Перед его доставкой они показали изображения теста, которые были сделаны, чтобы показать, что функция Bluetooth работает. Дело в том, что в их коде я заметил, что есть жестко закодированный UUID устройства, и я хочу знать, влияет ли это на процесс или нет.
class BluetoothController( val context : Context, val preferences: PreferencesProvider) { //Variable Contains the name of the class private val TAG = BluetoothController::class.java.simpleName // private val DEVICE_NAME = "MIT-TOOL" // private val DEVICE_NAME = "J 200" private val DEVICE_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB") // private val DEVICE_UUID = UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66") //Default by Google for insecure connections private lateinit var mBTSocket: BluetoothSocket private var bTAdapter: BluetoothAdapter? = null private lateinit var device: BluetoothDevice private lateinit var mConnectThread: ConnectThread private lateinit var mManageConnectionThread: ManageConnectionThread val isConnected:MutableLiveDatalt;Booleangt; = MutableLiveDatalt;Booleangt;(false) //init block, variable "isConnected" adds any detected bluetooth connections to the mutable live data //These are to be edited later init { isConnected.observeForever { EventBus.getDefault().post(BluetoothConnectionEvent(it)) if (it) Toast.makeText(context, "Connected.", Toast.LENGTH_SHORT).show() else Toast.makeText(context, "Not Connected.", Toast.LENGTH_SHORT).show() } } private var thread: Thread? = null private fun feedMultiple() { if (thread != null) thread!!.interrupt() val runnable = Runnable { Log.d(TAG, "feedMultiple: runnable" Thread.currentThread().name) EventBus.getDefault().post(ReadOnlinePlotsEvent()) } thread = Thread(Runnable { for (i in 0..99) { // Don't generate garbage runnables inside the loop. // bluetoothController.context.runOnUiThread(runnable) CoroutineScope(Dispatchers.Main).launch { Log.d(TAG, "feedMultiple:" Thread.currentThread().name) runnable.run() } try { Thread.sleep(1000) } catch (e: InterruptedException) { e.printStackTrace() } } }) thread!!.start() } //This method is responsible for initialising the bluetooth device and checking whethe rit is connected or not //For each connected device two pieces of data are stored in a Set //these being: Device Name amp; MAC Address fun initBTDevice() { // feedMultiple() bTAdapter = BluetoothAdapter.getDefaultAdapter() val pairedDevices: Setlt;BluetoothDevicegt;? = bTAdapter!!.bondedDevices pairedDevices?.forEach { it -gt; val deviceName = it.name val deviceHardwareAddress = it.address // MAC address Log.d(TAG, "initBTDevice: $deviceName") val DEVICE_NAME = preferences.getDeviceName() if (deviceName == DEVICE_NAME){ device = it connect() return } } isConnected.value = false // TODO notFound Toast.makeText(context, "Make sure that you connected and paired with the desired device.", Toast.LENGTH_LONG).show() } private fun connect() { Log.d(TAG, "startClient: Started.") //initprogress dialog mConnectThread = ConnectThread() mConnectThread.start() } fun disconnect(){ mManageConnectionThread.cancel() // mConnectThread.cancel() } private fun manageConnection() { Log.d(TAG, "connected: Starting.") // Start the thread to manage the connection and perform transmissions mManageConnectionThread = ManageConnectionThread() mManageConnectionThread.start() } /** * This thread runs while listening for incoming connections. It behaves * like a server-side client. It runs until a connection is accepted * (or until cancelled). */ inner class AcceptThread : Thread() { // The local server socket private val mmServerSocket: BluetoothServerSocket? override fun run() { try { // This is a blocking call and will only return on a // successful connection or an exception mBTSocket = mmServerSocket!!.accept() Log.d(TAG, "run: RFCOM server socket accepted connection.") } catch (e: IOException) { Log.e(TAG, "AcceptThread: IOException: " e.message) cancel() } //talk about this is in the 3rd manageConnection() CoroutineScope(Dispatchers.Main).launch { isConnected.value = true } } fun cancel() { Log.d(TAG, "cancel: Canceling AcceptThread.") try { CoroutineScope(Dispatchers.Main).launch { isConnected.value = false } mmServerSocket!!.close() } catch (e: IOException) { Log.e( TAG, "cancel: Close of AcceptThread ServerSocket failed. " e.message ) } } init { var tmp: BluetoothServerSocket? = null // Create a new listening server socket try { tmp = BluetoothAdapter.getDefaultAdapter()?.listenUsingInsecureRfcommWithServiceRecord("MiLink", DEVICE_UUID) Log.d(TAG, "AcceptThread: Setting up Server using: $DEVICE_UUID") } catch (e: IOException) { Log.e(TAG, "AcceptThread: IOException: " e.message) } mmServerSocket = tmp } } private inner class ConnectThread() : Thread() { // mBTSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) { // device.createRfcommSocketToServiceRecord(DEVICE_UUID) // } override fun run() { try { Log.d(TAG, "ConnectThread: Trying to create InsecureRfcommSocket using UUID: $DEVICE_UUID") mBTSocket = device.createRfcommSocketToServiceRecord(DEVICE_UUID) } catch (e: IOException) { Log.e(TAG, "ConnectThread: Could not create InsecureRfcommSocket " e.message) cancel() } // Cancel discovery because it otherwise slows down the connection. bTAdapter?.cancelDiscovery() try { // Connect to the remote device through the socket. This call blocks // until it succeeds or throws an exception. // This is a blocking call and will only return on a // successful connection or an exception mBTSocket.connect() Log.d(TAG, "run: ConnectThread connected.") CoroutineScope(Dispatchers.Main).launch { isConnected.value = true } manageConnection() } catch (e: IOException) { // Close the socket Log.d(TAG, e.message?: "run: ConnectThread: Could not connect to UUID: $DEVICE_UUID") cancel() } } // Closes the client socket and causes the thread to finish. fun cancel() { try { mBTSocket.close() CoroutineScope(Dispatchers.Main).launch { isConnected.value = false } Log.d(TAG, "ConnectThread: cancel(): Closed Socket.") } catch (e: IOException) { Log.e(TAG, "ConnectThread: Could not close the client socket", e) } } } private inner class ManageConnectionThread() : Thread() { private lateinit var mmInStream: InputStream private lateinit var mmOutStream: OutputStream init { Log.d(TAG, "ConnectedThread: Starting...") var tmpIn: InputStream? = null var tmpOut: OutputStream? = null //dismiss the progressdialog when connection is established try { mmInStream = mBTSocket.inputStream mmOutStream = mBTSocket.outputStream } catch (e: IOException) { e.printStackTrace() } } override fun run() { val buffer = ByteArray(1024) // buffer store for the stream var bytesLength: Int // bytes returned from read() // Keep listening to the InputStream until an exception occurs while (true) { // Read from the InputStream try { bytesLength = mmInStream.read(buffer) val incomingMessage = bytesToHexString(buffer) // val incomingMessage = String(buffer, 0, bytesLength, Charset.forName("UTF-8") ).trim() // CoroutineScope(Dispatchers.Main).launch { // Toast.makeText(context, incomingMessage, Toast.LENGTH_SHORT).show() // } Log.d(TAG , "InputStream: $incomingMessage") readIncomingMessages(incomingMessage) } catch (e: IOException) { Log.e(TAG, "write: Error reading Input Stream. " e.message) cancel() break } } } private fun bytesToHexString(bytes: ByteArray): String { val sb = java.lang.StringBuilder() for (i in bytes.indices) { sb.append(String.format("X ", bytes[i])) } return sb.toString() } fun hexStringToByteArray(s: String): ByteArray? { val len = s.length val data = ByteArray(len / 2) var i = 0 while (i lt; len) { data[i / 2] = ((Character.digit(s[i], 16) shl 4) Character.digit(s[i 1], 16)).toByte() i = 2 } return data } //Call this from the main activity to send data to the remote device fun write(message: String) { // val messageArray = message.split(" ").toTypedArray() // val bytes = ByteArray(messageArray.size) // messageArray.forEachIndexed { index, s -gt; // bytes[index] = s.toByte() // } val bytes = BigInteger(message.replace("\s".toRegex(), ""), 16).toByteArray(); // val text = String(bytes, Charset.defaultCharset()) CoroutineScope(Dispatchers.Main).launch { Toast.makeText(context, message, Toast.LENGTH_SHORT).show() } Log.d(TAG, "write: Writing to outputStream: $message") try { mmOutStream.write(bytes) } catch (e: IOException) { Log.e(TAG, "write: Error writing to output stream. " e.message) cancel() } } /* Call this from the main activity to shutdown the connection */ fun cancel() { try { mBTSocket.close() CoroutineScope(Dispatchers.Main).launch { isConnected.value = false } } catch (e: IOException) { } } }
Любой вклад приветствуется, так как я точно не знаю, в чем проблема