流程
获取蓝牙操作对象-BluetoothAdapter
开启蓝牙
通过intent,需要用户同意
mBluetoothAdapter.enable() 不用用户同意
查看自己配对信息 bondedDevices
开启可检测性-intent
搜索设备-广播监听、startDiscovery()
统一UUID
成为客户端(写出信息)- BluetoothSocket
成为服务端(读出信息)- BluetoothServerSocket
基础配置
获取蓝牙操作对象
private val mBluetoothAdapter by lazy {
BluetoothAdapter.getDefaultAdapter()
}123开启蓝牙
需要用户同意
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("蓝牙开启成功")
}
}1234567891011121314不需要用户同意
if (!mBluetoothAdapter.isEnabled) {
mBluetoothAdapter.enable()
} else {
mBluetoothAdapter.disable()
}12345查看自己配对信息
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()
}12345678910111213扫描设配(通过广播监听)
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()12345678910111213141516171819202122客户端
成为客户端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) {
}
}
}12345678910111213141516171819202122232425262728293031323334353637383940414243444546成功后写入数据(可以先把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) {
}
}
}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152服务端
开启扫描设配可检测性
val discoverableIntent = Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE) discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300) startActivity(discoverableIntent)123
成为服务端
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) {
}
}
}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647读取数据(通过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) {
}
}
}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950注意点
UUID:客户端和服务端必须保持一致才能连接成功
String转换:使用String(byteArrayOf)方式
数据读取一次后就需要重启一次蓝牙,这样还能重新发送数据
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦