当前位置:   article > 正文

Android 子线程使用ble,Android Bluetooth 使用总结

android bl蓝牙扫描在ui线程

前言

本文主要讲解经典蓝牙和BLE(低功耗蓝牙)的使用流程

一.获取蓝牙适配器

BluetoothAdapter 为蓝牙适配器,所有对蓝牙的操作都是通过它完成的.

BluetoothManager bluetoothManager =(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);

BluetoothAdapter mAdapter = bluetoothManager.getAdapter();

或者

BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();

以上两种实际一样.

二.开启蓝牙

友好界面的开启,在onActivityResult中获取开启结果

if (!mAdapter.isEnabled()){//先判断是否已开启

Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(intent,REQUEST_CODE);

}

简单粗暴的开启,当然这个也是异步开启的.

if (!mAdapter.isEnabled()){//先判断是否已开启

mAdapter.enable();

}

由于上面是该方式为异步开启,如果想监听则要注册广播,如下

//注册广播

private void registerBluetoothReceiver() {

IntentFilter filter = new IntentFilter();

filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//蓝牙状态改变的广播

filter.addAction(BluetoothDevice.ACTION_FOUND);//找到设备的广播

filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成的广播

filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//开始扫描的广播

filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//状态改变

registerReceiver(mReceive, intentFilter);

}

//注销广播

private void unregisterBluetoothReceiver() {

if (mReceive != null) {

unregisterReceiver(mReceive);

mReceive = null;

}

}

private BroadcastReceiver mReceive = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if (action == null) {

return;

}

switch (action) {

case BluetoothAdapter.ACTION_STATE_CHANGED:

int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);

if(BluetoothAdapter.STATE_OFF == state) {

//蓝牙关闭

}else if(BluetoothAdapter.STATE_ON == state) {

//蓝牙开启,开始扫描蓝牙

}

break;

case BluetoothDevice.ACTION_ACL_CONNECTED:

break;

case BluetoothDevice.ACTION_BOND_STATE_CHANGED:

//绑定状态返回

break;

case BluetoothDevice.ACTION_FOUND:

//扫描到的设备

BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

break;

}

}

};

三.扫描蓝牙

金典蓝牙和BLE蓝牙扫描方试上有区别了.

1.经典蓝牙扫描

经典蓝牙获取到的设备需要到上面注册的广播中获取.

if (mAdapter.isDiscovering()){

mAdapter.cancelDiscovery();

}

mAdapter.startDiscovery();

2.BLE蓝牙扫描

BLE扫描到的蓝牙直接回调得到设备

public void startScanDevice() {

BluetoothLeScanner bluetoothLeScanner = mAdapter.getBluetoothLeScanner();

bluetoothLeScanner.startScan(mLocalScanCallback);

}

ScanCallback mLocalScanCallback = new ScanCallback() {

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

@Override

public void onScanResult(int callbackType, ScanResult result) {

BluetoothDevice device = result.getDevice();

//扫描到的设备

}

@Override

public void onScanFailed(int errorCode) {

}

};

四.连接蓝牙

获取扫描到的BluetoothDevice(蓝牙设备)后即可连接.

1.经典蓝牙

配对

该方法为异步调用,返回true为正在绑定,同样需要在上面注册的广播中获取结果

boolean bond = device.createBond();

连接

客户端

连接操作为耗时过程,应该到子线程中进行,代码中的uuid可以理解为http中的端口号,这是一个唯一标识.

if (mAdapter.isDiscovering()) {

mAdapter.cancelDiscovery();

}

ParcelUuid parcelUuid = device.getUuids()[0];

BluetoothSocket mBluetoothSocket = device.createRfcommSocketToServiceRecord(parcelUuid.getUuid());

if (!mBluetoothSocket.isConnected()) {

mBluetoothSocket.connect();

}

服务端

/**

* 开启服务端

*/

public void startBluetoothService() {

while (true) {

try {

BluetoothServerSocket bluetoothServerSocket = mAdapter.listenUsingRfcommWithServiceRecord("zcx", UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));

BluetoothSocket bluetoothSocket = bluetoothServerSocket.accept();

if (bluetoothSocket != null) {

bluetoothServerSocket .close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

2.BLE蓝牙

//连接蓝牙

bluetoothGatt = device.connectGatt(getApplicationContext(), false, new BluetoothGattCallback() {

@ThreadChange

@Override

public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {

//发现服务

bluetoothGatt.discoverServices();

if (newState == BluetoothProfile.STATE_CONNECTED) {

} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {

} else if (newState == BluetoothProfile.STATE_CONNECTING) {

} else if (newState == BluetoothProfile.STATE_DISCONNECTING) {

}

}

@Override

public void onServicesDiscovered(BluetoothGatt gatt, int status) {

super.onServicesDiscovered(gatt, status);

BluetoothGattService service = bluetoothGatt.getService(UUID.fromString(SERVICE_UUID));

BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(Characteristic_uuid));

//设置接收通知

bluetoothGatt.setCharacteristicNotification(characteristic, true);

//00002902-0000-1000-8000-00805f9b34fb为系统接受通知自带的UUID

BluetoothGattDescriptor dsc = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));

dsc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);

//设置BluetoothGattDescriptor 使蓝牙设备发送通知信号时回调onCharacteristicChanged方法

boolean success = bluetoothGatt.writeDescriptor(dsc);

Log.d(TAG, "writing enabledescriptor:" + success);

}

@Override

public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {

}

@Override

public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {

super.onCharacteristicWrite(gatt, characteristic, status);

}

@Override

public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {

//接收到的通知

}

});

break;

}

四.通讯

1.经典蓝牙

//接收消息,需要用个子线程

public void receiveMessage(){

if (bluetoothSocket == null){

return;

}

try {

InputStream inputStream = bluetoothSocket.getInputStream();

BufferedReader bff = new BufferedReader(new InputStreamReader(inputStream));

String message;

while (true) {

while ((message= bff.readLine()) != null) {

//获取到的数据

}

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

//发送文本消息

public static void sendMessage(String message) {

if (bluetoothSocket == null || TextUtils.isEmpty(message)){

return;

}

try {

message += "\r\n";

OutputStream outputStream = bluetoothSocket.getOutputStream();

outputStream.write(message.getBytes("utf-8"));

outputStream.flush();

} catch (IOException e) {

e.printStackTrace();

}

2.BLE蓝牙

ble接收消息在连接时的onCharacteristicChanged方法中可以接收到,这里需要发送的方法

//发送文本消息

public boolean sendMessage(String message) {

if (bluetoothGatt == null) return false;

BluetoothGattCharacteristic gc = bluetoothGatt.getService(UUID.fromString(SERVICE_UUID)).getCharacteristic(UUID.fromString(Characteristic_uuid));

gc.setValue(message.getBytes());

bluetoothGatt.writeCharacteristic(gc);

return true;

}

android蓝牙到这里就结束了,可以愉快的使用蓝牙了

总结

这里总结一下这两种蓝牙区别吧

金典蓝牙: 3.0版本以下的蓝牙,功耗高、传输数据量大、传输距离只有10米。

BLE(低功耗)蓝牙 4.0及以上版本的蓝牙,低功耗、数据量小、距离50米左右。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/956227
推荐阅读
相关标签
  

闽ICP备14008679号