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è)備,但一個外圍設(shè)備只能連接一個中央設(shè)備,Android手機(jī)可以作為中央設(shè)備也可以作為外圍設(shè)備。
1.6藍(lán)牙相關(guān)常量
- 中央設(shè)備
- 開關(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)閉中 |
- 掃描狀態(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 | 查詢掃描和頁面掃描都有效 |
- 連接狀態(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è)備
- 配對狀態(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)牙常用方法
- 判斷設(shè)備是否支持藍(lán)牙
//設(shè)備是否支持藍(lán)牙
public static boolean isSupportBluetooth(){
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(bluetoothAdapter!=null){
return true;
}
return false;
}
- 如果設(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;
}
- 如果藍(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
- 如果藍(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;
}
- 獲取遠(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();
}
- 判斷已配對的遠(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;
}
- 如果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á)功率的絕對值,計算公式為
P為接收到的信號功率,單位W(瓦)
【例1】如果發(fā)射功率P為1mW,折算為dbm后為0dbm
【例2】對于發(fā)射功率40W,按其計算公式得46dbm