蓝牙基本功能实现(开启,扫描,配对,连接等)

最近有在学习Android蓝牙模块功能,包括开启,扫描,配对,连接等,在这里记录下相关功能的实现。后续会再做蓝牙电话apk的实现及蓝牙相关源码的分享。

Android 蓝牙基本功能详解

1
2
3
4
5
6
7
8
9
10
// 蓝牙所需要的权限
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-feature android:name="android.hardware.location.gps" />
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
// 蓝牙搜索从5.0后需要的权限,在Andoid 6.0后 需要动态申请
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

设备是否支持蓝牙功能

1
2
3
4
5
6
private BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

if (bluetoothAdapter == null) {
Toast.makeText(this, "不支持蓝牙模块", Toast.LENGTH_SHORT).show();
return;
}

蓝牙的打开

1
2
3
4
5
6
7
8
if (bluetoothAdapter.isEnabled()) {
// 蓝牙已打开
} else {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
// 打开蓝牙的同时想设置让自己手机蓝牙多少秒可见可以使用,默认120s,最多300s
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(intent);
}

蓝牙搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// 判断是否有locatioin权限
if (!checkLocationPermission()) {
return;
}
// 如果是在搜索的状态,则需要取消搜索
if (bluetoothadapter.isDiscovering()) {
bluetoothadapter.cancelDiscovery();
}

// 搜索蓝牙
bluetoothAdapter.startDiscovery();

// 蓝牙设备广播接收者
private BroadcastReceiver deviceReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
Log.e(TAG,"开始搜索");

} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
Log.e(TAG,"查找到设备完成");

} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
if (name != null) {
int rssi = intent.getExtras().getShort(BluetoothDevice.EXTRA_RSSI);
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
MyBlueToothDevice myDevice = new MyBlueToothDevice(device, name, rssi);
myBlueToothDevices.add(myDevice);
Log.e("=====","搜索到设备: " + name);
}

} else if (BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) {
int scanMode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE,0);
if (scanMode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Log.e(TAG,"设备可见监听");
} else {
Log.e(TAG,"设备不可见监听");
}

} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
BluetoothDevice remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (remoteDevice == null) {
Log.e(TAG,"没有绑定设备");
return;
}

int status = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,0);
if (status == BluetoothDevice.BOND_BONDED) {
Log.e(TAG,"绑定设备完成: " + remoteDevice.getName());
} else if (status == BluetoothDevice.BOND_BONDING) {
Log.e(TAG,"绑定设备中: " + remoteDevice.getName());
} else if (status == BluetoothDevice.BOND_NONE) {
Log.e(TAG,"取消绑定: ");
}
} else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
isBluetoothConnected = true;
changeBluetoothStatus();
Log.e(TAG,"已经连接上");
} else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
Log.e(TAG,"断开连接");
isBluetoothConnected = false;
changeBluetoothStatus();
}
}
};

// 蓝牙状态广播接收者
private BroadcastReceiver statusReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int status = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
switch (status) {
case BluetoothAdapter.STATE_OFF:
Log.e(TAG, "蓝牙已关闭");
break;
case BluetoothAdapter.STATE_ON:
Log.e(TAG, "蓝牙已打开");
startDiscovery();
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Log.e(TAG, "蓝牙关闭中...");
break;
case BluetoothAdapter.STATE_TURNING_ON:
Log.e(TAG, "蓝牙打开中...");
break;
default:
break;
}
}
};

// 注册广播
IntentFilter deviceIntentFilter = new IntentFilter();
deviceIntentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
deviceIntentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
deviceIntentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
deviceIntentFilter.addAction(BluetoothDevice.ACTION_FOUND);
deviceIntentFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
deviceIntentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
deviceIntentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
deviceIntentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
registerReceiver(deviceReceiver, deviceIntentFilter);

IntentFilter stateIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(statusReceiver, stateIntentFilter);

// 取消注册广播
unregisterReceiver(deviceReceiver);
unregisterReceiver(statusReceiver);

蓝牙连接

1
2
// device: BluetoothDevice
boolean bond = device.createBond();

蓝牙断开连接

1
2
3
// device: BluetoothDevice
Method method = BluetoothDevice.class.getMethod("removeBond");
method.invoke(device);

获取本地蓝牙属性

1
2
3
4
// 本地蓝牙名称
String name = bluetoothadapter.getName();
// 本地蓝牙地址
String address = bluetoothadapter.getAddress();

获取已绑定设备列表

1
bluetoothAdapter.getBondedDevices()

判断是否已连接蓝牙设备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static boolean isConnected() {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
try {
Method getConnectionState = adapter.getClass().getMethod("getConnectionState");
int state = (int) getConnectionState.invoke(adapter);
Log.e(TAG, "isConnected: " + (state == STATE_CONNECTED));
return state == STATE_CONNECTED;
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return false;
}

获取已连接蓝牙设备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public static BluetoothDevice getConnectedDevice() {
if (!isConnected()) {
return null;
}

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> bondedDevices = adapter.getBondedDevices();

try {
Method isConnectedMethod = BluetoothDevice.class.getMethod("isConnected");
for (BluetoothDevice device : bondedDevices) {
boolean isConnected = (boolean) isConnectedMethod.invoke(device);
if (isConnected) {
return device;
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}

return null;
}