Android应用程序在调用Connect()调用Connect()时与ESP的蓝牙连接失败

发布于 2025-01-22 04:13:03 字数 5154 浏览 2 评论 0原文

我正在尝试使用Kotlin在Android Studio中构建Android应用程序,以在ESP32和Mobile通过蓝牙之间发送一些简单的数据。我一直在遵循许多教程,但似乎无法建立连接,设备的权限和扫描看起来正常工作。当我在插座上调用Connect()时,应用程序悬挂几秒钟,然后使用此错误崩溃:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.btleveller, PID: 28899
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { (has extras) }} to activity {com.example.btleveller/com.example.btleveller.MainActivity}: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5368)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5407)

etc... I can post the full output if it's helpful

我的ESP使用Nimble-Arduino代码运行了一些非常基本的Helloworld样式代码,该代码通过vscode通过vscode进行了Platformio Extension。我认为这一切都可以正常工作,因为我可以在我的手机上的“ NRF Connect”应用中看到该设备。扫描是通过CompanionDeviceManager库进行的:

”“在此处输入图像描述”

我以为我正在提供的UUID有问题,或者我需要为BLE进行更改,而不是常规蓝牙,但到目前为止我什么都没有在网上发现的效果。我还尝试使用“ createl2capchannel()”来创建套接字,但卡在PSM值上。这些是代码的相关位:


//private val ESP_UUID = UUID.fromString("0000dead-0000-1000-8000-00805F9B34FB")
private val ESP_UUID = UUID.fromString("0000baad-0000-1000-8000-00805F9B34FB")

...

// Look for connection, kicked off by button press
    fun lookForConn(view: View) {
        val deviceFilter: BluetoothDeviceFilter = BluetoothDeviceFilter.Builder()
            .setNamePattern(Pattern.compile("BLE"))
            .build()

        // The argument provided in setSingleDevice() determines whether a single
        // device name or a list of them appears.
        val pairingRequest: AssociationRequest = AssociationRequest.Builder()
            .addDeviceFilter(deviceFilter)
            .setSingleDevice(false)
            .build()

        // When the app tries to pair with a Bluetooth device, show the
        // corresponding dialog box to the user.
        deviceManager.associate(pairingRequest,
            object : CompanionDeviceManager.Callback() {

                override fun onDeviceFound(chooserLauncher: IntentSender) {
                    startIntentSenderForResult(chooserLauncher,
                        SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0)
                }

                override fun onFailure(error: CharSequence?) {
                    // Handle the failure.
                    Log.d("DEVHandler","failed to find dev?")
                }
            }, null)
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        when (requestCode) {
            SELECT_DEVICE_REQUEST_CODE -> when(resultCode) {
                Activity.RESULT_OK -> {
                    // The user chose to pair the app with a Bluetooth device.
                    val deviceToPair: BluetoothDevice? =
                        data?.getParcelableExtra(CompanionDeviceManager.EXTRA_DEVICE)

                    Log.d("DEVHandler","try to bond:" + deviceToPair?.name)

                    deviceToPair?.let { device ->
                        device.createBond()

                        val newConn = ConnectThread(deviceToPair).run()
                    }
                }
            }
            else -> super.onActivityResult(requestCode, resultCode, data)
        }
    }

    private inner class ConnectThread(device: BluetoothDevice) : Thread() {
        private var mHaveConn = false
        public fun IsConnected(): Boolean {
            return mHaveConn
        }

        private val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
            //device.createRfcommSocketToServiceRecord(ESP_UUID)
            device.createInsecureRfcommSocketToServiceRecord(ESP_UUID)
        }

        public override fun run() {
            // Cancel discovery because it otherwise slows down the connection.
            BTMan.mBTAdapter?.cancelDiscovery()

            mmSocket?.let { socket ->
                // Connect to the remote device through the socket. This call blocks
                // until it succeeds or throws an exception.

                if (socket == null)
                    Log.d("CONNThread", "Socket is null...")

                if (socket.isConnected == true)
                    Log.d("CONNThread", "Socket is already connected...")

                socket.connect()
                Log.d("CONNThread", "Made a connection")
                // The connection attempt succeeded. Perform work associated with
                // the connection in a separate thread.
                //manageMyConnectedSocket(socket)

                mHaveConn = true
            }
        }

        // Closes the client socket and causes the thread to finish.
        fun cancel() {
            try {
                mmSocket?.close()
            } catch (e: IOException) {
                Log.e("CONNThread", "Could not close the client socket", e)
            }
            mHaveConn = false
        }
    }

I'm trying to build an Android app in Android Studio using Kotlin to send some simple data between an ESP32 and a mobile over Bluetooth. I've been following along a number of tutorials but just can't seem to get the connection established, permissions and scanning for devices looks to be working correctly. When I call connect() on the socket the app hangs for a few seconds and then crashes with this error:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.btleveller, PID: 28899
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { (has extras) }} to activity {com.example.btleveller/com.example.btleveller.MainActivity}: java.io.IOException: read failed, socket might closed or timeout, read ret: -1
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5368)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5407)

etc... I can post the full output if it's helpful

My ESP is running some very basic helloworld style code using the NimBLE-Arduino code, programmed through VSCode with the PlatformIO extension. I think this side of it is all working correct as I can see the device in the "nRF Connect" app on my mobile. The scanning is done through the CompanionDeviceManager library:

enter image description here

I thought maybe there was a problem with the UUID I was supplying, or that I needed to make changes for BLE as opposed to regular Bluetooth but so far nothing I've found online has worked. I've also tried using "createL2capChannel()" to create the socket but got stuck on the PSM value. These are the relevant bits of code:


//private val ESP_UUID = UUID.fromString("0000dead-0000-1000-8000-00805F9B34FB")
private val ESP_UUID = UUID.fromString("0000baad-0000-1000-8000-00805F9B34FB")

...

// Look for connection, kicked off by button press
    fun lookForConn(view: View) {
        val deviceFilter: BluetoothDeviceFilter = BluetoothDeviceFilter.Builder()
            .setNamePattern(Pattern.compile("BLE"))
            .build()

        // The argument provided in setSingleDevice() determines whether a single
        // device name or a list of them appears.
        val pairingRequest: AssociationRequest = AssociationRequest.Builder()
            .addDeviceFilter(deviceFilter)
            .setSingleDevice(false)
            .build()

        // When the app tries to pair with a Bluetooth device, show the
        // corresponding dialog box to the user.
        deviceManager.associate(pairingRequest,
            object : CompanionDeviceManager.Callback() {

                override fun onDeviceFound(chooserLauncher: IntentSender) {
                    startIntentSenderForResult(chooserLauncher,
                        SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0)
                }

                override fun onFailure(error: CharSequence?) {
                    // Handle the failure.
                    Log.d("DEVHandler","failed to find dev?")
                }
            }, null)
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        when (requestCode) {
            SELECT_DEVICE_REQUEST_CODE -> when(resultCode) {
                Activity.RESULT_OK -> {
                    // The user chose to pair the app with a Bluetooth device.
                    val deviceToPair: BluetoothDevice? =
                        data?.getParcelableExtra(CompanionDeviceManager.EXTRA_DEVICE)

                    Log.d("DEVHandler","try to bond:" + deviceToPair?.name)

                    deviceToPair?.let { device ->
                        device.createBond()

                        val newConn = ConnectThread(deviceToPair).run()
                    }
                }
            }
            else -> super.onActivityResult(requestCode, resultCode, data)
        }
    }

    private inner class ConnectThread(device: BluetoothDevice) : Thread() {
        private var mHaveConn = false
        public fun IsConnected(): Boolean {
            return mHaveConn
        }

        private val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) {
            //device.createRfcommSocketToServiceRecord(ESP_UUID)
            device.createInsecureRfcommSocketToServiceRecord(ESP_UUID)
        }

        public override fun run() {
            // Cancel discovery because it otherwise slows down the connection.
            BTMan.mBTAdapter?.cancelDiscovery()

            mmSocket?.let { socket ->
                // Connect to the remote device through the socket. This call blocks
                // until it succeeds or throws an exception.

                if (socket == null)
                    Log.d("CONNThread", "Socket is null...")

                if (socket.isConnected == true)
                    Log.d("CONNThread", "Socket is already connected...")

                socket.connect()
                Log.d("CONNThread", "Made a connection")
                // The connection attempt succeeded. Perform work associated with
                // the connection in a separate thread.
                //manageMyConnectedSocket(socket)

                mHaveConn = true
            }
        }

        // Closes the client socket and causes the thread to finish.
        fun cancel() {
            try {
                mmSocket?.close()
            } catch (e: IOException) {
                Log.e("CONNThread", "Could not close the client socket", e)
            }
            mHaveConn = false
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文