蓝牙连接之无需配对的低速传输数据方式

本文介绍了如何通过UUID建立一条无需配对的蓝牙低速通道。蓝牙利用UUID区分不同服务,设备间通过特定UUID连接并进行数据传输。文中详细解释了蓝牙协议、UUID的作用以及在Android中实现蓝牙连接的关键代码,包括server端的listenUsingRfcommWithServiceRecord和client端的createRfcommSocketToServiceRecord方法。整个过程不涉及传统的socket连接,而是先建立蓝牙层面的连接,再进行socket通信。
摘要由CSDN通过智能技术生成

基于UUID去建立一条低速的无需配对的蓝牙通道
一、原理
蓝牙是一种使用无线电通信的技术完成设备与设备间通讯与数据交换
UUID是什么:不同的服务用不同的UUID区分。
服务是什么:能提供的功能
UUID的详细解释:俩中国人用汉语交流,汉语就是俩中国人的UUID,交流就是服务。蓝牙技术联盟SIG定义UUID共用了一个基本的UUID:0x0000xxxx-0000-1000-8000-00805F9B34FB。总共128位,为了进一步简化基本UUID,每一个蓝牙技术联盟定义的属性有一个唯一的16位UUID,以代替上面的基本UUID的‘x’部分。使用16位的UUID便于记忆和操作,如SIG定义了“Device Information”的16位UUID为0x180A。
补充:很多厂家其实都没有用标准的UUID,都是自己定义的。这样其实很混乱,你要基于UUID去创建通道,首先要保证,你的这个UUID能被遍历到。

蓝牙是一个很有趣的东西,这里贴一个蓝牙协议《bluetooth_Core_v4.2.pdf》下载地址(白嫖):
https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=286439

使用下面代码创建的蓝牙低速通道,实际上会创建一个ACL链路:
两个蓝牙设备的配对,先建立一条ACL通道。随后,会进行L2CAP的一些交互,获取信息,但需要基于SDP profile获取信息时,L2CAP就会建立一条SDP逻辑链路(由Channel ID标识,这个可以理解成socket通信的端口号),SDP的交互就在L2CAP建立的Channel上进行,SDP交互完成后,会断开SDP的逻辑链路,若后面没有其它再需要交互的,ACL链路也会断开,但由于已经配对过,上层会保存ACL配对的信息。

附一个简单的图解:
在这里插入图片描述

二、代码核心解释
server端就是通过原生APIlistenUsingRfcommWithServiceRecord或者listenUsingInsecureRfcommWithServiceRecord来监听这个UUID,方便client来连。这俩方法就是安全/不安全的连接,可以去官网查看相关定义。
通过监听,当监听到之后,就返回一个BluetoothSocket对象,直接accept,等待client来connect(和普通socket一样,但是不存在子类父类关系哦~)
client端也是通过原生API,createRfcommSocketToServiceRecord或者createInsecureRfcommSocketToServiceRecord,根据UUID去连这个服务,同样返回的也是一个BluetoothSocket,然后基于这个socket去调用connect。
随后数据传输就是socket通信,无需赘述。
难点就是要理解,listenUsingRfcommWithServiceRecord和createRfcommSocketToServiceRecord,是蓝牙层面上的连接,并非是socket的连接,只有这个连接建立好了,再去搞socket连接,然后流通信。

三、代码

client端

package com.mythsun.frcommclient;

import androidx.appcompat.app.AppCompatActivity;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "client-demo";

    private Button button1, button2;
    private TextView textView1;

    private final BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    // use
    private BluetoothSocket client;

    private class ConnectThread extends Thread {
        private final String UUID_STRING = "你自己的uuid";
        private final UUID UUID_BR = UUID.fromString(UUID_STRING);

        private final boolean isSecure;

        public ConnectThread(BluetoothDevice device, boolean isSecure) {
            this.isSecure = isSecure;
            BluetoothSocket tmp = null;
            try {
                if (this.isSecure) {
                    tmp = device.createRfcommSocketToServiceRecord(UUID_BR);
                    Log.d(TAG, "isSecure:true");
                } else {
                    tmp = device.createInsecureRfcommSocketToServiceRecord(UUID_BR);
                    Log.d(TAG, "isSecure:false");
              
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值