1. 设备扫描
1.1和ble 设备一样,首先都需要获取蓝牙设备管理器
BluetoothManager bluetoothManager =
(BluetoothManager) mContext.getSystemService (Context.BLUETOOTH_SERVICE);
BluetoothAdapter mAdapter = bluetoothManager.getAdapter ();
1.2 设备搜索
- 搜索先先判断是否连接,如果没有连接,可以通过代码将蓝牙打开
if (mAdapter == null || !mAdapter.isEnabled ()) {
if (!mAdapter.isEnabled ()) {
LogS.d (TAG, "蓝牙未开启,开始开启蓝牙");
mAdapter.enable ();
}
}
这里需要注意,开启蓝牙是一个异步操作,执行打开操作后,立马去搜索可能会搜索不到,这里有两种思路:
1.监控蓝牙开关广播状态
2.加个延时,然后搜索,且适当延长搜索时间。
- 判断是否正在搜索,如果正在搜索,就停止搜索
if (mAdapter.isDiscovering ()) {
mAdapter.cancelDiscovery ();
}
- 每次扫描之前都先判断一下是否存在已经配对过的设备
Set<BluetoothDevice> paireDevices = mAdapter.getBondedDevices ();
if (paireDevices.size () > 0) {
for (BluetoothDevice device : paireDevices) {
LogS.d (TAG, "将设备信息存入数组中" + device .getAddress ());
}
}
如果已经有我们之前配对过的设备,可以根据自身业务直接去连接。
- 开始扫描设备
mAdapter.startDiscovery ();
- 通过广播监控扫描结果
5.1 注册广播
public void registerReceiverBle() {
IntentFilter filter = new IntentFilter ();
filter.addAction (BluetoothDevice.ACTION_FOUND);
filter.addAction (BluetoothDevice.ACTION_BOND_STATE_CHANGED);
filter.addAction (BluetoothDevice.ACTION_ACL_DISCONNECTED);
filter.addAction (BluetoothDevice.ACTION_ACL_CONNECTED);
filter.addAction (BluetoothDevice.ACTION_ACL_DISCONNECTED);
filter.addAction (BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
mContext.registerReceiver (receiver, filter);
}
5.2 数据状态监听广播
private BroadcastReceiver receiver = new BroadcastReceiver () {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction ();
if (TextUtils.isEmpty (action)) {
LogS.d (TAG, "onReceive intent.getAction == null!");
return;
}
switch (action) {
// Remote device discovered
case BluetoothDevice.ACTION_FOUND://找到设备
BluetoothDevice device = intent.getParcelableExtra (BluetoothDevice.EXTRA_DEVICE);
LogS.d (TAG, "找到设备"+ device.getName () +"---"+ device.getBondState ());
}
break;
case BluetoothDevice.ACTION_ACL_DISCONNECTED://蓝牙断开
LogS.d (TAG, "蓝牙断开");
break;
case BluetoothDevice.ACTION_ACL_CONNECTED://蓝牙链接
LogS.d (TAG, "蓝牙链接");
break;
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
LogS.d (TAG, "蓝牙设备连接状态变化");
processDeviceBondedStateChanged (intent);
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
LogS.d (TAG, "扫描结束------扫描到的总设备" );
break;
}
}
};
通过监听到的广播信息 BluetoothDevice.ACTION_FOUND监听搜索到的所有设备。
2.设备绑定配对
2.1 通过搜索到的设备或者本地保存的设备信息获取设备对象
BluetoothDevice device = mAdapter.getRemoteDevice (deviceInfo.getAddress ());
2.2 判断设备绑定状态
device.getBondState ()
有三种状太分别是
- {@link #BOND_NONE}, 未绑定 10
- {@link #BOND_BONDING}, 绑定中 11
- {@link #BOND_BONDED}. 已绑定 12
2.3 开始发起与远程绑定
boolean isStartBind = device.createBond ();
如果绑定出错返回false ,发起绑定成功为true,然后等待绑定成功广播
蓝牙设备配对和解除配对时发送
private void processDeviceBondedStateChanged (Intent intent){
action: BluetoothDevice.ACTION_BOND_STATE_CHANGED 广播
BluetoothDevice device = intent.getParcelableExtra (BluetoothDevice.EXTRA_DEVICE);
int state= device.getBondState ()
switch (state) {
case BluetoothDevice.BOND_NONE:
// 删除配对
break;
case BluetoothDevice.BOND_BONDING:
// 正在配对
break;
case BluetoothDevice.BOND_BONDED:
// 配对成功
break;
}
}
3.设备解绑
public boolean removeBond( BluetoothDevice device) {
try {
Method m = device.getClass().getMethod("removeBond", (Class[]) null);
m.setAccessible(true);
m.invoke(device, (Object[]) null);
} catch (Exception e) {
Log.e("ble",e.toString());
}
return true;
}
这里的参数可以根据自己的业务需求来定,大多数都是我们本地保存了一个设备对象,解绑时再通过这个设备对象的Address 获取到一个设备对象。
BluetoothDevice device=mAdapter.getRemoteDevice (address ());
然后通过这个device 对象来解绑设备。
4.设备的连接
通过uuid 获取socket对象并连接
BluetoothSocket bluetoothSocket = device.createRfcommSocketToServiceRecord (UUID.fromString (“00001101-0000-1000-8000-00805F9B34FB”));
bluetoothSocket.connect ();
判断是否已连接: bluetoothSocket.isConnected ()
这里的uuid 是一个标准公用蓝牙串口服务的uuid
5.数据发送
1.获取一个输出流对象
OutputStream outputStream = bluetoothSocket.getOutputStream ();
2.写入数据
outputStream.write(bytes)
这步最好通过一个线程单独来做。
5.数据的接收
1.获取输入流
InputStream inputStream = bluetoothSocket.getInputStream ();
2.定义一个接收数的缓冲区
public int MAX_BUFFER_SIZE = 512;
byte[] buffer = new byte[MAX_BUFFER_SIZE];
3.读取数据必须放在一个子线程中
while (bluetoothSocket.isConnected ()) {
try {
InputStream inputStream = bluetoothSocket.getInputStream ();
int readL = inputStream.read (buffer);
if (readL != -1) {
if (readL < 8) {
//根据自己业务处理
LogS.e (TAG, "读取非法数据" + readL);
break;
}
byte[] data = new byte[readL];
System.arraycopy (buffer, 0, data, 0, readL);
//分发消息。。。。
}
} catch (IOException e) {
e.printStackTrace ();
}
}
5.关闭连接
public static void disConnectDevice(){
if (bluetoothSocket != null) {
try {
bluetoothSocket.close ();
} catch (IOException e) {
e.printStackTrace ();
}
}
}
写在最后:
传统蓝牙区别与ble 低功耗蓝牙,需要先通过设备的认证绑定,再连接,而ble 只需知道mac 地址或者搜索到设备通过mac 地址即可直接连接。