Android 蓝牙开发与 12/S 系统适配

建议参考

  • 蓝牙通信方式
    1. 经典蓝牙(Bluetooth Classic)通信:
      • 经典蓝牙通信通常用于在较短的距离内传输大量数据,例如音频流、文件传输等。
      • 在 Android 中,你可以使用 BluetoothAdapter 和 BluetoothSocket 类来建立经典蓝牙连接,并进行数据传输。
      • 经典蓝牙通信通常需要进行配对和授权,以确保通信的安全性。
    2. 蓝牙低功耗(Bluetooth Low Energy,BLE)通信:
      • BLE 通信适用于低功耗设备和周期性数据传输场景,例如健康监测、传感器数据采集等。
      • 在 Android 中,BLE 通信通常使用 BluetoothLeScanner 和 BluetoothGatt 类来实现。
      • BLE 通信不需要配对,通常以连接为基础,并且支持广播、订阅通知等特性。

权限适配参考
https://juejin.cn/post/7320169878644031488
https://www.cnblogs.com/fly263/p/16715525.html
https://blog.csdn.net/qq_17189617/article/details/135291784

流写数据
https://cloud.tencent.com.cn/developer/article/2310635
https://www.jb51.net/article/263206.htm

  * 客户端设置
    * 单击事件
    * */
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        String s = arrayAdapter.getItem(position);
        String address = s.substring(s.indexOf(":") + 1).trim();//获取蓝牙IP
  
        try {
            if (bluetoothAdapter.isDiscovering()) {
                bluetoothAdapter.cancelDiscovery();//若当前蓝牙被使用,则关闭重新启用
            }
            try {
                if (device == null) {//若未连接,则获得远程设备
                    device = bluetoothAdapter.getRemoteDevice(address);
                }
                if (clientSocket == null) {
                    clientSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
                    clientSocket.connect();//连接蓝牙
                    os = clientSocket.getOutputStream();//客户端向服务端输出文本
  
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (os != null) {
                os.write("发送信息到其他设备".getBytes("utf-8"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

https://www.cnblogs.com/Free-Thinker/p/11507349.html

读写特征判断

  • 判断服务是否有读或者写权限 用或运算

      				// 获取特征的 UUID
                      val characteristicUUID = characteristic.uuid
                      // 检查特征的属性
                      val properties = characteristic.properties
                      // 判断特征是否可读写
                      if (properties and (BluetoothGattCharacteristic.PROPERTY_READ or BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
                          // 特征可读写,打印其 UUID
                          LogUtils.e("Characteristic UUID", characteristicUUID.toString())
                      } 
    
  • 判断服务是否有 读写 通知权限 这边用与运算

       @SuppressLint("MissingPermission")
      fun findGattService(gatt: BluetoothGatt?): BluetoothGattService? {
          var service: BluetoothGattService? = null
    
          if (gatt != null) {
              LogUtils.e("findGattService 当前设备:           ${gatt.device.name}")
              val bgsList = gatt.services
              label@ for (gattService in bgsList) {
                  val uuid = gattService!!.uuid.toString()
                  if (gattService.type == BluetoothGattService.SERVICE_TYPE_PRIMARY) {
    
                  }
                  LogUtils.e(" gattService服务UUID            $uuid               ${gattService.type}       ")
                  for (characteristic in gattService.characteristics) {
                      // 获取特征的 UUID
                      val characteristicUUID = characteristic.uuid
                      // 检查特征的属性
                      val properties = characteristic.properties
                      // 判断特征是否可读写
                      if (properties and (BluetoothGattCharacteristic.PROPERTY_READ or BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
                          // 特征可读写,打印其 UUID
                          LogUtils.e("Characteristic UUID", characteristicUUID.toString())
                      }
    
    
                      var isRead = (characteristic.properties and BluetoothGattCharacteristic.PROPERTY_READ) > 0
                      var isWrite = (characteristic.properties and BluetoothGattCharacteristic.PROPERTY_WRITE) > 0
                      var isNotify = (characteristic.properties and BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0
                      if (isRead) {
                          UUID_RECEIVE_CHARACTERISTIC = characteristic.uuid.toString()
                          LogUtils.e("写特征  $UUID_RECEIVE_CHARACTERISTIC")
                      }
                      if (isWrite) {
                          UUID_SEND_CHARACTERISTIC = characteristic.uuid.toString()
                          LogUtils.e("读特征  $UUID_SEND_CHARACTERISTIC")
                      }
                      if (isNotify) {
                          CLIENT_CHARACTERISTIC_CONFIG = characteristic.uuid.toString()
                          LogUtils.e("通知特征  $CLIENT_CHARACTERISTIC_CONFIG")
                      }
                      if (isWrite and isWrite and isNotify) {
                          UUID_GATT_SERVICE = gattService.uuid.toString()
                          service = gattService
                          break@label
                      }
                  }
              }
          }
          return service
      }
    
    

    特征判断参考
    https://blog.51cto.com/u_16213401/9599749

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android 12 中,由于安全性的考虑,应用程序访问本地文件系统的方式发生了变化。从 Android 12 开始,应用程序将无法访问 `file:///android_asset/` 目录。相反,您应该使用 `content://` URI 或将文件复制到应用程序专用目录中的 `files/` 目录。 以下是一些适用于 Android 12 的解决方案: 1. 使用 `AssetManager` 类来获取 `assets` 目录中的文件。例如,您可以使用以下代码从 `assets` 目录中读取文本文件: ``` try { InputStream inputStream = getAssets().open("filename.txt"); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = bufferedReader.readLine()) != null) { // process the line } bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } ``` 2. 将文件复制到应用程序专用目录中的 `files/` 目录,并使用 `FileProvider` 类来生成 `content://` URI。例如,您可以使用以下代码将文件复制到 `files/` 目录: ``` try { InputStream inputStream = getAssets().open("filename.txt"); FileOutputStream outputStream = openFileOutput("filename.txt", Context.MODE_PRIVATE); byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) > 0) { outputStream.write(buffer, 0, length); } outputStream.close(); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } ``` 然后,您可以使用以下代码生成 `content://` URI: ``` File file = new File(getFilesDir(), "filename.txt"); Uri contentUri = FileProvider.getUriForFile(this, "your.package.name.fileprovider", file); ``` 在此示例中,`your.package.name` 应该替换为您的应用程序的包名。 请注意,如果您的应用程序需要访问其他应用程序的文件,则需要使用 `ACTION_OPEN_DOCUMENT` 或 `ACTION_CREATE_DOCUMENT` 操作来请求用户授权。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值