如何使用android原生BLE蓝牙进行操作?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用android原生BLE蓝牙进行操作?相关的知识,希望对你有一定的参考价值。

参考技术A

之前的涉及的物联网项目中使用的: BLE 低功耗蓝牙(蓝牙4.0), 支持android 4.3以上的手机
主从关系: BLE低功耗蓝牙只能做从端设备 ,一个蓝牙主端设备,可同时与7个蓝牙从端设备进行通讯

1)低功耗
低功耗的原理:
1\\低功耗蓝牙仅使用了3个广播通道,传统蓝牙技术采用 16~32 个频道
2\\每次广播开启时间也由传统的 22.5ms 减少到 0.6~1.2ms(毫秒)

2)传输距离极大提高
传统蓝牙传输距离为 2~10m,而蓝牙4.0的有效传输距离可达到 60~100m

3)安全性
使用AES-128 CCM加密算法进行数据包加密和认证。
更多BLE蓝牙的解析参考博客 : BLE4.0教程一 蓝牙协议连接过程与广播分析

添加权限
打开蓝牙
1.先拿到BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
2.再拿到BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
判断是否打开蓝牙
未打开弹出 系统弹框 ,除了 魅族手机 是打开系统设置

设备/手机都是蓝牙信号

在回调方法中:

一般在扫描的过程中,我们还会设置 设备过滤原则 (因为我只想要搜索到我们想要的设备,忽略无关设备)
如:从 scanRecord -- beacon -- beacon.type == 0xFF代表Manufacture,通过与嵌入式软件定义 自己的 Manufacture值即可

用BluetoothDevice得到BluetoothGatt:

断连:

关键问题:连接后一般要做什么事?

( 必须在刚连接成功后2秒内app写一个值给设备,否则会被设备断开连接)

主要是读写 characteristic
gatt.wirteCharacteristic(mCurrentcharacteristic);

gatt.readCharacteristic(characteristic);

bluetoothGatt.setCharacteristicNotification(data, true);

真实工作中使用的蓝牙库BlueToothKit请参考我的另一篇博客:
android蓝牙入门知识和优秀蓝牙第三方库BluetoothKit的使用

无法使用反应原生蓝牙

【中文标题】无法使用反应原生蓝牙【英文标题】:Unable to use react native Bluetoothel 【发布时间】:2019-09-12 18:28:06 【问题描述】:

我在我的应用程序中添加了 react-native-ble-plx。我还使用 react native link cmd 链接了它。我已按照 lib 文档中提供的所有必需步骤进行操作。但它不起作用。我从不要求用户许可,它给出了错误 Deivce is not authorized to use BluetoothLE。这是我的代码

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.smartdeviceiot">
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
   <uses-permission android:name="android.permission.INTERNET" />
   <uses-permission android:name="android.permission.BLUETOOTH"/>
   <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
   <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>
   <uses-sdk
                 android:minSdkVersion="18"
                 android:targetSdkVersion="23"/> 

DeviceSearch.js

从 '../constants/colors' 导入颜色; 从'../constants/images'导入图像; 导入 按钮、图标、文本、容器、标题、 左,正文,标题,右来自'native-base'; 从'./styles/home'导入 HomeStyle ; 从'react-native-ble-plx'导入 BleManager 类 DevicesSearch 扩展组件 静态导航选项 = 标题:“设备搜索” ; 构造函数(道具) 超级(道具); const manager = new BleManager(); 这个.state = ; 组件WillMount() 使成为() 返回 ( >this.props.navigation.navigate("DrawerOpen")> 设备搜索 搜索设备 ); 扫描与连接 = () => 警报('asd') console.log('cal'); this.manager.startDeviceScan(null, null, (error, device) => this.info("正在扫描..."); console.log(设备);

      if (error) 
        this.error(error.message);
        return
      

      if (device.name ==='MyDevice') 
        this.info("Connecting to Tappy");
        this.manager.stopDeviceScan();

        device.connect()
          .then((device) => 
            this.info("Discovering services and characteristics");
            return device.discoverAllServicesAndCharacteristics()
          )
          .then((device) => 
            this.info(device.id);
            device.writeCharacteristicWithResponseForService('12ab', '34cd',

'aGVsbG8gbWlzcyB0YXBweQ==') .then((特征) => this.info(characteristic.value); 返回 ) ) .catch((错误) => this.error(error.message) ) ); 函数 mapStateToProps(state) //传递提供者 返回 /* 将 Actions 映射到 Props */ function mapDispatchToProps(dispatch) > 返回 动作:bindActionCreators( , 派遣) ; 导出默认连接( mapStateToProps, mapDispatchToProps)(DevicesSearch);

如果我的蓝牙关闭代码控制台。记录我蓝牙已关闭,但当它打开时记录我该设备未授权使用蓝牙。我也厌倦了使用 AndroidPermission lib 但没有成功。它不需要用户的许可

【问题讨论】:

【参考方案1】:

您需要明确要求用户授予权限。我有同样的问题,我通过在一个单独的文件中添加这个代码来解决它:

export async function requestLocationPermission() 
  try 
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION, 
        title: 'Location permission for bluetooth scanning',
        message: 'wahtever',
        buttonNeutral: 'Ask Me Later',
        buttonNegative: 'Cancel',
        buttonPositive: 'OK',
      ,
    ); 
    if (granted === PermissionsAndroid.RESULTS.GRANTED) 
      console.log('Location permission for bluetooth scanning granted');
      return true;
     else 
      console.log('Location permission for bluetooth scanning revoked');
      return false;
    
   catch (err) 
    console.warn(err);
    return false;
  

然后当我需要扫描时,在实际扫描代码之前我会执行以下操作:

  scanAndConnect() 
    const permission = requestLocationPermission();
    if (permission)         
      ...here I scan because the user has given permission

【讨论】:

您可能需要等待 requestLocationPermission() 的小修正,并且 scanAndConnect 应该是异步的。而且,fine_location 对我们的工作并不粗糙【参考方案2】:

为了将来参考,在定位较新的 Android 设备时,您必须询问“ACCESS_FINE_LOCATION”而不是“ACCESS_COARSE_LOCATION”。

来源:https://developer.android.com/guide/topics/connectivity/bluetooth/permissions

【讨论】:

以上是关于如何使用android原生BLE蓝牙进行操作?的主要内容,如果未能解决你的问题,请参考以下文章

[yueqian_scut]蓝牙防丢器原理实现与Android BLE接口编程

Android BLE低功耗蓝牙开发极简系列(二)之读写操作

Android-Ble蓝牙开发Demo示例–扫描,连接,发送和接收数据,分包解包(附源码)

Android BLE为啥首次连接蓝牙设备比较慢

Android ble蓝牙使用注意

如何在 android 中将特征写入 BLE GATT 服务器?