Android蓝牙开发初识篇

流程

  1. 获取蓝牙操作对象-BluetoothAdapter
  2. 开启蓝牙
    1. 通过intent,需要用户同意
    2. mBluetoothAdapter.enable() 不用用户同意
  3. 查看自己配对信息 bondedDevices
  4. 开启可检测性-intent
  5. 搜索设备-广播监听、startDiscovery()
  6. 统一UUID
  7. 成为客户端(写出信息)- BluetoothSocket
  8. 成为服务端(读出信息)- BluetoothServerSocket

基础配置

  1. 获取蓝牙操作对象
 private val mBluetoothAdapter by lazy {
        BluetoothAdapter.getDefaultAdapter()
    }
  1. 开启蓝牙

需要用户同意

if (!mBluetoothAdapter.isEnabled) {
            startActivityForResult(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), START_BLUE)
        } else {
            toast("蓝牙已经开启了")
}


 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == START_BLUE && resultCode == Activity.RESULT_OK) {
            toast("蓝牙开启成功")
        }
    }

不需要用户同意

    if (!mBluetoothAdapter.isEnabled) {
            mBluetoothAdapter.enable()
        } else {
            mBluetoothAdapter.disable()
        }
  1. 查看自己配对信息
    val bondedDevices = mBluetoothAdapter.bondedDevices
        if (bondedDevices.isEmpty()) {
            toast("当前设备没有配对成功过")
        } else {
            val names = bondedDevices.map {
                it.name + "    " + it.address
            }
            alert {
                items(items = names) { dialogInterface: DialogInterface, i: Int ->
                    dialogInterface.dismiss()
                }
            }.show()
        }
  1. 扫描设配(通过广播监听)
  private val mReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val action = intent.action
            // When discovery finds a device
            if (BluetoothDevice.ACTION_FOUND == action) {
                // Get the BluetoothDevice object from the Intent
                val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
                // Add the name and address to an array adapter to show in a ListView
                mListAdapter.add(device.name + "-" + device.address)
            }
        }
    }


val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
registerReceiver(mReceiver, filter)

//开启该方法
 if (mBluetoothAdapter.isDiscovering) {
            mBluetoothAdapter.cancelDiscovery()
        }
        mBluetoothAdapter.startDiscovery()

客户端

  1. 成为客户端BluetoothSocket
不需要代码,默认就是客户端
  1. 连接连接端(根据服务端DeviceAddress)
ConnectThread(mBluetoothAdapter.getRemoteDevice(address)).start()

private inner class ConnectThread(val mmDevice: BluetoothDevice) : Thread() {
        private val mmSocket: BluetoothSocket?

        init {
            var tmp: BluetoothSocket? = null
            try {
                // MY_UUID is the app's UUID string, also used by the server code
                tmp = mmDevice.createRfcommSocketToServiceRecord(UUID.fromString("2987f694-71d4-4a08-885a-5d07bd3ca0c4"))
            } catch (e: IOException) {
            }
            mmSocket = tmp
        }

        override fun run() {
            // Cancel discovery because it will slow down the connection
            mBluetoothAdapter.cancelDiscovery()

            try {
                // Connect the device through the socket. This will block
                // until it succeeds or throws an exception
                mmSocket?.connect()
            } catch (connectException: IOException) {
                // Unable to connect; close the socket and get out
                try {
                    mmSocket?.close()
                } catch (closeException: IOException) {
                }

                return
            }

            // 开始写入数据
            manageWriteSocket(mmSocket)
        }

        /** Will cancel an in-progress connection, and close the socket  */
        fun cancel() {
            try {
                mmSocket!!.close()
            } catch (e: IOException) {
            }

        }
    }
  1. 成功后写入数据(可以先把String转成byte[])
private fun manageWriteSocket(mmSocket: BluetoothSocket?) {
        WriteThread(mmSocket).start()
    }


private inner class WriteThread(private val mmSocket: BluetoothSocket?) : Thread() {
        private val mmInStream: InputStream?
        private val mmOutStream: OutputStream?

        init {
            var tmpIn: InputStream? = null
            var tmpOut: OutputStream? = null

            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = mmSocket?.inputStream
                tmpOut = mmSocket?.outputStream
            } catch (e: IOException) {
            }

            mmInStream = tmpIn
            mmOutStream = tmpOut
        }

        override fun run() {
//            val buffer = ByteArray(1024)  // buffer store for the stream
            val buffer = byteArrayOf() // buffer store for the stream
            write("用户名|132000000|")
        }

        /* Call this from the main activity to send data to the remote device */
        fun write(bytes: String) {
            try {
                Log.e("shen", "发送:${bytes.toByteArray()}")
                mmOutStream?.write(bytes.toByteArray())
            } catch (e: IOException) {
                Log.e("shen", "1231")
            }

        }

        /* Call this from the main activity to shutdown the connection */
        fun cancel() {
            try {
                mmSocket?.close()
            } catch (e: IOException) {
            }

        }
    }

服务端

  1. 开启扫描设配可检测性
val discoverableIntent = Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE)
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300)
startActivity(discoverableIntent)
  1. 成为服务端
  private inner class AcceptThread : Thread() {
        private val mmServerSocket: BluetoothServerSocket?

        init {
            // Use a temporary object that is later assigned to mmServerSocket,
            // because mmServerSocket is final
            var tmp: BluetoothServerSocket? = null
            try {
                // MY_UUID is the app's UUID string, also used by the client code
                tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("test", UUID.fromString("2987f694-71d4-4a08-885a-5d07bd3ca0c4"))
            } catch (e: IOException) {
            }

            mmServerSocket = tmp
        }

        override fun run() {
            var socket: BluetoothSocket? = null
            Log.e("shen", "startReadThread")
            // Keep listening until exception occurs or a socket is returned
            //死循环进行数据接收
            while (true) {
                try {
                    socket = mmServerSocket?.accept()
                } catch (e: IOException) {
                    break
                }

                // If a connection was accepted
                if (socket != null) {
                    // Do work to manage the connection (in a separate thread)
                    manageReadSocket(socket)
                    mmServerSocket?.close()
                    break
                }
            }
        }

        /** Will cancel the listening socket, and cause the thread to finish  */
        fun cancel() {
            try {
                mmServerSocket!!.close()
            } catch (e: IOException) {
            }

        }
    }
  1. 读取数据(通过String(byteArrayOf)方式把byte[]转成String)
private fun manageReadSocket(socket: BluetoothSocket) {
        ReadThread(socket).start()
    }

private inner class ReadThread(private val mmSocket: BluetoothSocket) : Thread() {
        private val mmInStream: InputStream?

        //        private val mmOutStream: OutputStream?
        init {
            var tmpIn: InputStream? = null
            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = mmSocket.inputStream
            } catch (e: IOException) {
            }

            mmInStream = tmpIn
//            mmOutStream = tmpOut
        }

        override fun run() {
            val byteArrayOf = ByteArray(1024)
            var bytes: Int = 0 // bytes returned from read()
            Log.e("shen", "test")
            // Keep listening to the InputStream until an exception occurs
            while (true) {
                try {
                    bytes = mmInStream?.read(byteArrayOf) ?: 0
                    val toString = byteArrayOf.toString()
                    val string = String(byteArrayOf) //可以成功转换
                    Log.e("shen", "bytes===${byteArrayOf}")
                    Log.e("shen", "bytes===${toString}")
                    Log.e("shen", "bytes===${string}")
                    break
                } catch (e: Exception) {
//                    break
                }
            }
        }

        /* Call this from the main activity to shutdown the connection */
        fun cancel() {
            try {
                mmSocket.close()
            } catch (e: IOException) {
            }
        }
    }

注意点

  1. UUID:客户端和服务端必须保持一致才能连接成功
  2. String转换:使用String(byteArrayOf)方式
  3. 数据读取一次后就需要重启一次蓝牙,这样还能重新发送数据
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值