蓝牙透传
关于蓝牙透传,基本步骤如下:
1、设置蓝牙权限
2、打开蓝牙
3、蓝牙搜索
4、蓝牙连接与通讯
测试使用android4.4版本手机与蓝牙4.0硬件模块;
1、设置蓝牙权限(android6.0以下)
蓝牙权限在AndroidManifest.xml中加入如下代码:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
如果想要只在支持BLE的安卓设备上运行则需要再加如下:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
2、打开蓝牙
//打开蓝牙
public void ble_open() {
//获取蓝牙适配器实例
BluetoothAdapter ble_adapter = BluetoothAdapter.getDefaultAdapter();
if(ble_adapter !=null){
//判断蓝牙是否已打开
if (!ble_adapter.isEnabled()) {
//打开蓝牙,强制打开,不安全
//ble_adapter.enable();
//弹窗询问是否打开,推荐,可以重新onActivityResult确认是否打开
Intent ble_intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(ble_intent,0);
}
}else
Toast.makeText(this, "该设备不支持蓝牙", Toast.LENGTH_SHORT).show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 0){
switch (resultCode){
case RESULT_OK:
//蓝牙打开成功
break;
case RESULT_CANCELED:
//蓝牙打开失败
break;
}
}
}
3、蓝牙搜索
搜索蓝牙设备有三种方法:
1、startLeScan(LeScanCallback)此方法适用于4.3以上版本,扫描结果通过实现BluetoothAdapter.LeScanCallback接口方法onLeScan来接收
2、此外startScan(ScanCallbackcallback)适用于5.0以上;
3、ble_adapter.startDiscovery()虽然说是兼容经典蓝牙和低功耗蓝牙,但有些设备无法检测到低功耗蓝牙;startDiscovery是一个异步方法,其过程:系统发送BluetoothAdapter.ACTIOINDISCOVERYSTARTED的广播 ,然后搜到一个蓝牙设备就发送一个BluetoothDevice.ACTIONFOUND的广播,结束发送BluetoothAdapter.ACTIONFINISHED的广播,整个过程耗时12s,这也说明搜索结果需要注册一个广播来接收;
public void ble_scan(View view) {
//判断是否处于扫描状态
if (isScan)
return;
//扫描时间设为10s
handler.postDelayed(new Runnable() {
@Override
public void run() {
ble_adapter.stopLeScan(MainActivity.this);
isScan = false;
}
}, 10000);
//开始扫描
if (ble_adapter.isEnabled()) {
ble_adapter.startLeScan(this);
isScan = true;
text_list.setVisibility(View.VISIBLE);
}
}
/**
* 返回扫描结果的回调
* @param device 蓝牙信息相关类,可以获取蓝牙名称,地址,绑定状态等
* @param rssi 蓝牙设备信号值,正常为负值,值越大信号越强
* @param scanRecord 远程设备提供的配对号
*/
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
if (device.getName().equals(ble_name)) {
BleDevice bleDevice = new BleDevice(device, rssi, false);
if (!ble_list.contains(bleDevice))
ble_list.add(bleDevice);
sendMSG(FIND_BLE_DEVICE);
ble_adapter.stopLeScan(this);
}
}
4、蓝牙连接与通讯
//连接设备
public void ble_connect(String address, final int position) {
BluetoothDevice device = ble_adapter.getRemoteDevice(address);
ble_gatt = device.connectGatt(this, true, new BluetoothGattCallback() {
//连接状态改变回调
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
ble_list.get(position).setConnect(true);
sendMSG(CONNECT_SUCCESS);
//连接成功,开始搜索服务,一定要调用此方法,否则获取不到服务
gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
ble_list.get(position).setConnect(false);
sendMSG(CONNECT_FAILED);
ble_gatt.close();
}
}
//发现服务时,调用回调,表示可以通信了
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
UUID service_UUID = Constants.CX21_SERVICE_UUID;
UUID characteristic_UUID = Constants.CX21_CHARACTERISTIC_UUID;
//通过UUID找到服务
ble_GattService = gatt.getService(service_UUID);
//找到服务后在通过UUID找到特征
ble_Characteristic = ble_GattService.getCharacteristic(characteristic_UUID);
if (ble_Characteristic != null) {
//启用onCharacteristicChanged(),用于接收数据
Boolean isTrue = gatt.setCharacteristicNotification(ble_Characteristic, true);
BluetoothGattDescriptor descriptor = ble_Characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
sendMSG(SERVICE_DISCOVERED);
} else {
sendMSG(SERVICE_DISCOVERED_FAILED);
return;
}
}
//由于远程特征通知而触发的回调
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
//使用的蓝牙设备发送的是16进制,需要处理,否则会乱码
receive = bytesToHexString(characteristic.getValue());
sendMSG(RECEIVE_MSG);
}
//写入成功的回调
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
if (BluetoothGatt.GATT_SUCCESS == status) {
sendMSG(WRITE_SUCCESS);
}
}
//读取成功回调
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
if (BluetoothGatt.GATT_SUCCESS == status) {
String receive = "";
for (int i = 0; i < characteristic.getValue().length; i++) {
int v = characteristic.getValue()[i] & 0xFF;
receive += Integer.toHexString(v);
}
Log.e("connect", "read:" + receive);
}
}
});
}
1)、向蓝牙模块写数据如下:
String writeData = "00801001015A";
ble_Characteristic.setValue(getHexBytes(writeData));
gatt.writeCharacteristic(ble_Characteristic);
如果写入成功会回调onCharacteristicWrite方法;
2)、读数据:
gatt.readCharacteristic(ble_Characteristic);
如果读取成功,可以在onCharacteristicRead中获取到数据;
版权声明:本文为qq_38757742原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。