Android藍(lán)牙相關(guān)知識

1 藍(lán)牙基礎(chǔ)知識

1.1 藍(lán)牙相關(guān)的權(quán)限

<!--想要用藍(lán)牙進(jìn)行通信則要申明bluetooth權(quán)限-->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<!--bluetooth_admin用來操作藍(lán)牙,官方建議除非是用戶請求修改藍(lán)牙設(shè)置的-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

<!--掃描藍(lán)牙后會觸發(fā)廣播,如果觸發(fā)廣播需要添加下面權(quán)限-->
<uses-permission android:name="android.permission.Access_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

1.2 BluetoothAdapter兩種獲取對象的方法

//第一種
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

//第二種
BluetoothManager manager = (BluetoothManager) sContext.getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter mBluetoothAdapter = manager.getAdapter();

1.3 藍(lán)牙相關(guān)廣播

  • ACTION_DISCOVERY_STARTED
public static final String ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED";

藍(lán)牙適配器開始搜索后,會先有12秒的查詢掃描(12s內(nèi)可見),查詢掃描后進(jìn)行頁面掃描(主動搜索),需要BLUETOOTH權(quán)限;如果搜索到藍(lán)牙設(shè)備,就會收到BluetoothDevice.ACTION_FOUND廣播,可以從Intent中獲取存放在其中的BluetoothDevice對象,intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);設(shè)備查找非常消耗資源,已經(jīng)存在的連接也會限制帶寬,因此,如果想要執(zhí)行除查找外的其它操作,之前最好調(diào)用cancelDiscovery()

  • ACTION_DISCOVERY_FINISHED
public static final String ACTION_DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED";

藍(lán)牙適配器完成搜索時發(fā)出的廣播需要BLUETOOTH權(quán)限。

1.4 中央設(shè)備與外圍設(shè)備

藍(lán)牙中有兩種角色Central和Peripheral,也就是中央設(shè)備與外圍設(shè)備。中央設(shè)備可以主動連接外圍設(shè)備,外圍設(shè)備發(fā)送廣播然后中央設(shè)備搜索到該廣播并連接,廣播中帶有外圍設(shè)備自身的相關(guān)信息。


中央設(shè)備與外圍設(shè)備關(guān)系圖

一個中央設(shè)備可以連接多個外圍設(shè)備,但一個外圍設(shè)備只能連接一個中央設(shè)備,Android手機(jī)可以作為中央設(shè)備也可以作為外圍設(shè)備。

1.6藍(lán)牙相關(guān)常量

  • 中央設(shè)備
  1. 開關(guān)狀態(tài)
常量 描述
BluetoothAdapter.STATE_OFF 10 藍(lán)牙模塊處于關(guān)閉狀態(tài)
BluetoothAdapter.STATE_TURNING_ON 11 藍(lán)牙模塊正在開啟中
BluetoothAdapter.STATE_ON 12 藍(lán)牙模塊處于開啟狀態(tài)
BluetoothAdapter.STATE_TURNING_OFF 13 藍(lán)牙模塊正在關(guān)閉中
  1. 掃描狀態(tài)
常量 描述
BluetoothAdapter.SCAN_MODE_NONE 20 查詢掃描和頁面掃描都失效,該狀態(tài)下藍(lán)牙模塊既不能掃描其它設(shè)備,也不可見。
BluetoothAdapter.SCAN_MODE_CONNECTABLE 21 查詢掃描失效,頁面掃描有效,該狀態(tài)下藍(lán)牙模塊可以掃描其它設(shè)備,從可見性來說只對已配對的藍(lán)牙設(shè)備可見,只有配對的設(shè)備才能主動連接本設(shè)備
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE 23 查詢掃描和頁面掃描都有效
  1. 連接狀態(tài)
    在Android中,兩個類里面都有連接狀態(tài),一個是BluetoothAdapter里面,一個是BluetoothProfile里面。

BluetoothProfile是一個接口,

public interface BluetoothProfile {
    ...
//以下連接狀態(tài)一般用于遠(yuǎn)端設(shè)備(即外圍設(shè)備)
    int STATE_DISCONNECTED = 0;
    int STATE_DISCONNECTING = 1;
    int STATE_CONNECTED = 2;
    int STATE_DISCONNECTING = 3
    ...
}

在BluetoothAdapter中

//藍(lán)牙處于已斷開狀態(tài),一般值為0
public static final int STATE_DISCONNECTED = BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTED;
//藍(lán)牙正在連接,一般值為1
public static final int STATE_CONNECTING = BluetoothProtoEnums.CONNECTION_STATE_CONNECTING;
//藍(lán)牙處于已連接狀態(tài),一般值為2
public static final int STATE_CONNECTED = BluetoothProtoEnums.CONNECTION_STATE_CONNECTED;
//藍(lán)牙處于正在斷開連接,一般值為3
pubilc static final int STATE_DISCONNECTING = BluetoothProtoEnums.CONNECTION_STATE_DISCONNECTING;
  • 外圍設(shè)備
  1. 配對狀態(tài)
常量 描述
BluetoothDevice.BOND_NONE 10 遠(yuǎn)端設(shè)備沒有配對
BluetoothDevice.BOND_BONDING 11 正在和遠(yuǎn)端設(shè)備進(jìn)行配對
BluetoothDevice.BOND_BONDED 12 遠(yuǎn)端設(shè)備已經(jīng)配對

1.7 常用類

類名 描述
BluetoothDevice 表示遠(yuǎn)程的藍(lán)牙設(shè)備,與中央設(shè)備建立連接后,可以查詢設(shè)備的名稱,地址,配對狀態(tài),連接狀態(tài),電量等等
BluetoothProfile 表示藍(lán)牙配置文件的接口。藍(lán)牙配置文件是適用于藍(lán)牙通信的布線接口規(guī)范,兩個設(shè)備之間具有相同的Profile才能互相連接
BluetoothHeadset 提供藍(lán)牙耳機(jī)支持,以便與手機(jī)配合使用。其中包括藍(lán)牙耳機(jī)和免提(1.5版)配置文件
BluetoothA2dp 定義高質(zhì)量音頻如何通過藍(lán)牙連接和流式傳輸,從一臺設(shè)備傳輸?shù)搅硪慌_設(shè)備。“A2DP”代表高級音頻分發(fā)配置文件,是BluetoothProfile的實現(xiàn)類,一般無線藍(lán)牙耳機(jī)都實現(xiàn)了該配置文件
BluetoothHealth 表示用于控制藍(lán)牙服務(wù)的健康設(shè)備配置文件,是BluetoothProfile的實現(xiàn)類
BluetoothGatt BluetoothProfile的實現(xiàn)類,與低功耗藍(lán)牙通信有關(guān)的配置文件

配置文件(profile)類型

配置文件類型 描述
BluetoothProfile.HEADSET 1 耳機(jī)和免提配置文件
BluetoothProfile.A2DP 2 藍(lán)牙音頻傳輸模型協(xié)定。A2DP規(guī)定了使用藍(lán)牙非同步傳輸信道方式,傳輸高質(zhì)量音樂文件數(shù)據(jù)的協(xié)議。基于該協(xié)議能通過藍(lán)牙方式傳輸高品質(zhì)音樂,這個技術(shù)以廣泛用于藍(lán)牙耳機(jī)
BluetoothProfile.HEALTH 3 此常熟在API級別29中已被棄用,不再使用Health設(shè)備配置文件(HDP)和MCAP協(xié)議。新的應(yīng)用程序應(yīng)該使用基于藍(lán)牙低功耗的解決方案
BluetoothProfile.HID_DEVICE 19 HID設(shè)備,一般有藍(lán)牙鍵盤、藍(lán)牙鼠標(biāo)、藍(lán)牙游戲手柄等
BluetoothProfile.HEARING_AID 21 助聽器
BluetoothProfile.PAN 5 應(yīng)用于手機(jī)

2 藍(lán)牙常用方法

  1. 判斷設(shè)備是否支持藍(lán)牙
//設(shè)備是否支持藍(lán)牙
public static boolean isSupportBluetooth(){
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if(bluetoothAdapter!=null){
        return true;
    }
    return false;
}
  1. 如果設(shè)備支持藍(lán)牙則判斷藍(lán)牙是否已打開
//藍(lán)牙是否已經(jīng)啟動
public static boolean isBluetoothOpen(){
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if(bluetoothAdapter!=null){
        return bluetoothAdapter.isEnabled();
    }
    return false;
}
  1. 如果藍(lán)牙沒有打開則打開藍(lán)牙
public static void openBluetooth(){
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if(isSupportBluetooth()){
        bluetoothAdapter.enable();
    }
}

如果手機(jī)是root狀態(tài),可以通過adb命令打開藍(lán)牙

adb shell svc bluetooth enable
  1. 如果藍(lán)牙打開則獲取已配對列表
//查詢配對設(shè)備
public static List<BluetoothDevice> checkDevices(){
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    List<BluetoothDevice> devices = new ArrayList<>();
    if(bluetoothAdapter!=null){
        Set<BluetoothDevice>pairedDevices = bluetoothAdapter.getBondedDevices();
        if(pairedDevices!=null&&pairedDevices.size()>0){
            for(BluetoothDevice device : pairedDevices){
                devices.add(device);
            }
        }
    }
    return devices;
}
  1. 獲取遠(yuǎn)端的Profile對象
private void setBluetoothProfile(){
    ConditionVariable variable = new ConditionVariable();
    mBluetoothAdapter.getProfileProxy(sContext,new BluetoothProfile.ServiceListener(){
        @Override
        public void onServiceConnected(int profile,BluetoothProfile proxy){
            mBluetoothA2dp  = (BluetoothA2dp)proxy;
            if(variable!=null){
                variable.open();
            }
        }
        @Override
        public void onServiceDisconnected(int profilel){
            if(variable!=null){
                variable.open();
            }
        }
    },BluetoothProfile.A2DP);
    variable.block(5000);
    variable.close();
}
  1. 判斷已配對的遠(yuǎn)端設(shè)備中是否有指定profile類型
private BluetoothDevice getRemoteBluetoothDevice(){
    BluetoothDevice remoteDevice = null;
    //checkDevices()方法在上面
    List<BluetoothDevice>bondedDeviceList = checkDevices();
    for(BluetoothDevice device : bondedDeviceList){
        if(device.getBluetoothClass!=null){
            //可以通過下面方法判斷遠(yuǎn)端設(shè)備是什么類型設(shè)備
            if(device.getBluetoothClass().getMajorDeviceClass() == BluetoothClass.Major.AUDIO_VIDEO){
                remoteDevice = device;
            }
        }
    }
    return remoteDevice;
}
  1. 如果BluetoothA2dp類型沒有連接上,可以通過以下方法進(jìn)行連接
//以下方法是不能實現(xiàn)的,因為BluetoothA2dp下的connect方法是hide方法,可以通過反射來調(diào)用
mBluetoothA2dp.connect(remoteDevice);

3 藍(lán)牙設(shè)備類型

public final class BluetoothClass implements Parcelable{
    ...
    public static class Device {
        private static final int BITMASK = 0x1FFC;

        /**
         * Defines all major device class constants.
         * <p>See {@link BluetoothClass.Device} for minor classes.
         */
        public static class Major {
            private static final int BITMASK = 0x1F00;//比特掩碼

            public static final int MISC = 0x0000;//麥克風(fēng)
            public static final int COMPUTER = 0x0100;//電腦
            public static final int PHONE = 0x0200;//電話
            public static final int NETWORKING = 0x0300;//網(wǎng)絡(luò)
            public static final int AUDIO_VIDEO = 0x0400;//音頻
            public static final int PERIPHERAL = 0x0500;//外部設(shè)備
            public static final int IMAGING = 0x0600;//鏡像,映像
            public static final int WEARABLE = 0x0700;//穿戴設(shè)備
            public static final int TOY = 0x0800;//玩具
            public static final int HEALTH = 0x0900;//健康
            public static final int UNCATEGORIZED = 0x1F00;//未分類的、未知的
        }

        // Devices in the COMPUTER major class
        public static final int COMPUTER_UNCATEGORIZED = 0x0100;
        public static final int COMPUTER_DESKTOP = 0x0104;
        public static final int COMPUTER_SERVER = 0x0108;
        public static final int COMPUTER_LAPTOP = 0x010C;
        public static final int COMPUTER_HANDHELD_PC_PDA = 0x0110;
        public static final int COMPUTER_PALM_SIZE_PC_PDA = 0x0114;
        public static final int COMPUTER_WEARABLE = 0x0118;

        // Devices in the PHONE major class
        public static final int PHONE_UNCATEGORIZED = 0x0200;
        public static final int PHONE_CELLULAR = 0x0204;
        public static final int PHONE_CORDLESS = 0x0208;
        public static final int PHONE_SMART = 0x020C;
        public static final int PHONE_MODEM_OR_GATEWAY = 0x0210;
        public static final int PHONE_ISDN = 0x0214;

        // Minor classes for the AUDIO_VIDEO major class
        public static final int AUDIO_VIDEO_UNCATEGORIZED = 0x0400;
        public static final int AUDIO_VIDEO_WEARABLE_HEADSET = 0x0404;
        public static final int AUDIO_VIDEO_HANDSFREE = 0x0408;
        //public static final int AUDIO_VIDEO_RESERVED              = 0x040C;
        public static final int AUDIO_VIDEO_MICROPHONE = 0x0410;
        public static final int AUDIO_VIDEO_LOUDSPEAKER = 0x0414;
        public static final int AUDIO_VIDEO_HEADPHONES = 0x0418;
        public static final int AUDIO_VIDEO_PORTABLE_AUDIO = 0x041C;
        public static final int AUDIO_VIDEO_CAR_AUDIO = 0x0420;
        public static final int AUDIO_VIDEO_SET_TOP_BOX = 0x0424;
        public static final int AUDIO_VIDEO_HIFI_AUDIO = 0x0428;
        public static final int AUDIO_VIDEO_VCR = 0x042C;
        public static final int AUDIO_VIDEO_VIDEO_CAMERA = 0x0430;
        public static final int AUDIO_VIDEO_CAMCORDER = 0x0434;
        public static final int AUDIO_VIDEO_VIDEO_MONITOR = 0x0438;
        public static final int AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 0x043C;
        public static final int AUDIO_VIDEO_VIDEO_CONFERENCING = 0x0440;
        //public static final int AUDIO_VIDEO_RESERVED              = 0x0444;
        public static final int AUDIO_VIDEO_VIDEO_GAMING_TOY = 0x0448;

        // Devices in the WEARABLE major class //穿戴設(shè)備細(xì)分
        public static final int WEARABLE_UNCATEGORIZED = 0x0700;
        public static final int WEARABLE_WRIST_WATCH = 0x0704;
        public static final int WEARABLE_PAGER = 0x0708;
        public static final int WEARABLE_JACKET = 0x070C;
        public static final int WEARABLE_HELMET = 0x0710;
        public static final int WEARABLE_GLASSES = 0x0714;

        // Devices in the TOY major class 玩具細(xì)分
        public static final int TOY_UNCATEGORIZED = 0x0800;
        public static final int TOY_ROBOT = 0x0804;
        public static final int TOY_VEHICLE = 0x0808;
        public static final int TOY_DOLL_ACTION_FIGURE = 0x080C;
        public static final int TOY_CONTROLLER = 0x0810;
        public static final int TOY_GAME = 0x0814;

        // Devices in the HEALTH major class 健康設(shè)備細(xì)分
        public static final int HEALTH_UNCATEGORIZED = 0x0900;
        public static final int HEALTH_BLOOD_PRESSURE = 0x0904;
        public static final int HEALTH_THERMOMETER = 0x0908;
        public static final int HEALTH_WEIGHING = 0x090C;
        public static final int HEALTH_GLUCOSE = 0x0910;
        public static final int HEALTH_PULSE_OXIMETER = 0x0914;
        public static final int HEALTH_PULSE_RATE = 0x0918;
        public static final int HEALTH_DATA_DISPLAY = 0x091C;

        // Devices in PERIPHERAL major class
        /**
         * @hide
         */
        public static final int PERIPHERAL_NON_KEYBOARD_NON_POINTING = 0x0500;
        /**
         * @hide
         */
        public static final int PERIPHERAL_KEYBOARD = 0x0540;
        /**
         * @hide
         */
        public static final int PERIPHERAL_POINTING = 0x0580;
        /**
         * @hide
         */
        public static final int PERIPHERAL_KEYBOARD_POINTING = 0x05C0;
    }
     ...
}

使用方式

int deviceType = device.getBluetoothClass().getMajorDeviceClass();
if(deviceType == BluetoothClass.Device.Major.PHONE){
    ...
}

注:需要注意的是,device.getBluetoothClass().getMajorDeviceClass()有時候獲取不到正確的值,這應(yīng)該跟遠(yuǎn)端設(shè)備的硬件有關(guān)。手機(jī)與手機(jī)連接,其中一個需要打開“藍(lán)牙共享網(wǎng)絡(luò)”或“藍(lán)牙網(wǎng)絡(luò)共享”,不同手機(jī)名稱可能不一樣。打開“藍(lán)牙網(wǎng)絡(luò)共享”的手機(jī)則為中央設(shè)備,可以被多個手機(jī)連接。

4 重要方法

4.1 getProfileProxy

    mBluetoothAdapter.getProfileProxy(sContext,new BluetoothProfile.ServiceListener(){
        @Override
        public void onServiceConnected(int profile,BluetoothProfile proxy){
            mBluetoothA2dp  = (BluetoothA2dp)proxy;
            if(variable!=null){
                variable.open();
            }
        }
        @Override
        public void onServiceDisconnected(int profilel){
            if(variable!=null){
                variable.open();
            }
        }
    },BluetoothProfile.A2DP);

可以看到源碼:

public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,
            int profile) {
        if (context == null || listener == null) {
            return false;
        }

        if (profile == BluetoothProfile.HEADSET) {
            BluetoothHeadset headset = new BluetoothHeadset(context, listener);
            return true;
        } else if (profile == BluetoothProfile.A2DP) {
            BluetoothA2dp a2dp = new BluetoothA2dp(context, listener);
            return true;
        } else if (profile == BluetoothProfile.A2DP_SINK) {
            BluetoothA2dpSink a2dpSink = new BluetoothA2dpSink(context, listener);
            return true;
        } else if (profile == BluetoothProfile.AVRCP_CONTROLLER) {
            BluetoothAvrcpController avrcp = new BluetoothAvrcpController(context, listener);
            return true;
        } else if (profile == BluetoothProfile.HID_HOST) {
            BluetoothHidHost iDev = new BluetoothHidHost(context, listener);
            return true;
        } else if (profile == BluetoothProfile.PAN) {
            BluetoothPan pan = new BluetoothPan(context, listener);
            return true;
        } else if (profile == BluetoothProfile.HEALTH) {
            BluetoothHealth health = new BluetoothHealth(context, listener);
            return true;
        } else if (profile == BluetoothProfile.MAP) {
            BluetoothMap map = new BluetoothMap(context, listener);
            return true;
        } else if (profile == BluetoothProfile.HEADSET_CLIENT) {
            BluetoothHeadsetClient headsetClient = new BluetoothHeadsetClient(context, listener);
            return true;
        } else if (profile == BluetoothProfile.SAP) {
            BluetoothSap sap = new BluetoothSap(context, listener);
            return true;
        } else if (profile == BluetoothProfile.PBAP_CLIENT) {
            BluetoothPbapClient pbapClient = new BluetoothPbapClient(context, listener);
            return true;
        } else if (profile == BluetoothProfile.MAP_CLIENT) {
            BluetoothMapClient mapClient = new BluetoothMapClient(context, listener);
            return true;
        } else if (profile == BluetoothProfile.HID_DEVICE) {
            BluetoothHidDevice hidDevice = new BluetoothHidDevice(context, listener);
            return true;
        } else if (profile == BluetoothProfile.HEARING_AID) {
            BluetoothHearingAid hearingAid = new BluetoothHearingAid(context, listener);
            return true;
        } else {
            return false;
        }
    }

可以看到,它是一個代理方法,通過Profile數(shù)值來得到指定的BluetoothProfile對象,通過回調(diào)的方式提供給使用者。getProfileProxy最終操作的是AIDL文件,因此回調(diào)里的代碼可能比回調(diào)外的代碼晚執(zhí)行,所以需要做同步操作。

BluetoothAdapter中還有一個關(guān)閉代理的方法,在使用結(jié)束時應(yīng)該調(diào)用close方法。

public void closeProfileProxy(int profile,BluetoothProfile proxy){
    ...
}

4.2 setPriority

    /**
     * Set priority of the profile
     *
     * <p> The device should already be paired.
     * Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
     * {@link #PRIORITY_OFF},
     *
     * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
     * permission.
     *
     * @param device Paired bluetooth device
     * @param priority
     * @return true if priority is set, false on error
     * @hide
     */
    public boolean setPriority(BluetoothDevice device, int priority) {
        ...
    }

每個BluetoothProfile的實現(xiàn)類中都有該方法,該方法priority值只能設(shè)置0和100,其它值會返回false。而且該方法的調(diào)用必須是藍(lán)牙設(shè)備處于配對狀態(tài)。profile=0時,會停用該profile對應(yīng)的一切相關(guān)功能。

4.3 getProfileConnectionState和getConnectionState

 //只針對藍(lán)牙設(shè)備的某個profile
int state = mBluetoothAdapter.getProfileConnectionState(A2DP);
//只要藍(lán)牙設(shè)備有一種profile處于連接狀態(tài),則返回連接狀態(tài)的state,該方法是hide方法,需要通過反射獲得
int state = mBluetoothAdapter.getConnectionState();

5 Profile

從3.0版本開始,藍(lán)牙才開始支持BluetoothProfile。BluetoothProfile是藍(lán)牙設(shè)備間數(shù)據(jù)通信的無線接口規(guī)范。想要使用藍(lán)牙無線技術(shù),設(shè)備必須能夠翻譯特定藍(lán)牙配置文件。配置文件定義了可能的應(yīng)用,藍(lán)牙的一個很重要的特性就是藍(lán)牙產(chǎn)品無需實現(xiàn)全部的藍(lán)牙規(guī)范。為了更容易的保持藍(lán)牙設(shè)備之間的兼容,藍(lán)牙規(guī)范中定義了profile,一個藍(lán)牙設(shè)備可以包含多個profile。profile定義了設(shè)備如何實現(xiàn)一種連接或者應(yīng)用,可以把profile理解為連接層或者應(yīng)用層協(xié)議。兩個藍(lán)牙設(shè)備具有相同的profile,這兩個設(shè)備才能相互連接。這里指的是具有相同的profile,并不是說實現(xiàn)了相同profile的功能或應(yīng)用。

6 藍(lán)牙UUID

UUID是根據(jù)一定算法,計算得到的一長串?dāng)?shù)字,這串?dāng)?shù)字不會重復(fù),每次生成都會產(chǎn)生不一樣的序列,所以可以用來作為唯一標(biāo)識。在藍(lán)牙協(xié)議中,UUID被用來標(biāo)識藍(lán)牙設(shè)備所提供的服務(wù),并非是標(biāo)識藍(lán)牙設(shè)備本身,一個藍(lán)牙設(shè)備可以提供多種服務(wù),比如A2DP(藍(lán)牙音頻傳輸),HEADFREE(免提)、PBAP(電話本)、SPP(串口通信)等待,每種服務(wù)都對應(yīng)一個UUID,其中在藍(lán)牙協(xié)議棧里,這些默認(rèn)提供的profile是都有對應(yīng)的UUID,也就是默認(rèn)的UUID,比如SPP,00001101-0000-1000-8000-00805F9B34FB就是一個非常知名的UUID,基本上所有的藍(lán)牙板不修改的話都是這個值,所以如果是與一個藍(lán)牙開發(fā)板進(jìn)行串口通信,而藍(lán)牙側(cè)又不是自己可以控制的,可以試試這個值。

7 RSSI

接收信息強(qiáng)度指示(RSSI,Received Signal Strength Indicator)無線發(fā)送層的可選部分,用來判定連接質(zhì)量,以及是否增大廣播發(fā)送強(qiáng)度。

dBm用于表達(dá)功率的絕對值,計算公式為
RSSI = 10*lg(P/0.001)
P為接收到的信號功率,單位W(瓦)
【例1】如果發(fā)射功率P為1mW,折算為dbm后為0dbm
【例2】對于發(fā)射功率40W,按其計算公式得46dbm

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容