当前位置: 首页 > article >正文

Unity for Android使用蓝牙低功耗Bluetooth LE

Unity2021.3.35f1

插件:Bluetooth LE for iOS and Android v2.3.unitypackage

1、将插件资源包导入unity中

2.修改插件中的AndroidManifest文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" android:installLocation="preferExternal" android:versionCode="1" android:versionName="1.0">
  <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
  <uses-permission android:name="android.permission.BLUETOOTH" />
  <uses-feature android:name="android.hardware.bluetooth_le" android:required="false" />
  <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="true">
    <activity android:name="com.unity3d.player.UnityPlayerProxyActivity" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
    </activity>
    <activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    <activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
      <meta-data android:name="android.app.lib_name" android:value="unity" />
      <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
    </activity>
    <meta-data android:name="platform_high" android:value="1" />
    <meta-data android:name="enable_entitlementcheck" android:value="0" />
  </application>
</manifest>

3.编写UI

2个按钮:StartScanningBtn(扫描)、DisconnectBtn(断开连接)

2个Text

1个Container(带Vertical Layout Group),用于显示扫描到的终端

4.制作预制体DeviceInfo,一个Button一个Text,点击按钮可连接蓝牙终端

预制体上挂一个脚本DeviceInfo,代码始下

using UnityEngine;
using UnityEngine.UI;

public class DeviceInfo : MonoBehaviour
{
    public Button btnConnect;
    public Text textName;
    public Text textAddress;
}

5.编写BlueToothTest.cs代码

using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.UI;

public class BlueToothTest: MonoBehaviour
{
    //连接的蓝牙mac地址
    private string bleAddress;
    //表示是否开始扫描
    private bool isScanning;
    //表示是否已经蓝牙初始化
    private bool isInit;
    //设备信息预制体 当扫描到一个设备时就会创建一个实例并放到滚动视图中去
    public GameObject deviceInfoPrefab;
    //滚动视图的容器结点
    public Transform container;
    //提示的文本信息框  连接提示。。。
    public Text text;
    //提示的其他文本信息框  接受数据提示。。。
    public Text otherText;
    //断开连接按钮
    public Button disConnectBtn;
    //开始扫描按钮
    public Button startScanningBtn;
    //以设备名字做个存储,相同名字的就忽视不在扫描
    private HashSet<string> deviceHashSet = new HashSet<string>();
    //设备名、设备地址字典
    private Dictionary<string, string> deviceDictionary = new Dictionary<string, string>();

    void Start()
    {
        Input.location.Start(); //定位
        InitBluethood();
        startScanningBtn.onClick.AddListener(() =>
        {
            StartScnnning();
        });
        disConnectBtn.onClick.AddListener(() =>
        {
            DisConnect();
        });        
    }

    /// <summary>
    /// 初始化蓝牙设备
    /// </summary>
    private void InitBluethood()
    {
        if (!isInit)
        {
            BluetoothLEHardwareInterface.Initialize(true, false, () =>
            {
                Show("蓝牙初始化成功");//初始化成功执行回调
                isInit = true;
            },
           (error) =>
           {
               Show(error.ToString());//初始化失败的回调响应
           });
        }
    }
    /// <summary>
    /// 扫描设备
    /// </summary>
    private void StartScnnning()
    {
        if (!isScanning && isInit)
        {
            Show("扫描设备中");
            Input.location.Start(); //定位
            Invoke("FindDevice", 1f);
            isScanning = true;
        }
    }
    public void FindDevice()
    {
        BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(null, (address, name) =>
        {
            if (deviceHashSet.Contains(name)) return;
            CreationTextPrefab(address, name);
            //扫描处理,加入设备列表              
            AddPeripheral(name, address);
            deviceHashSet.Add(name);

        }, (address, name, rssi, advertisingInfo) =>
        {
            if (deviceHashSet.Contains(name)) return;
            CreationTextPrefab(address, name);
            AddPeripheral(name, address);
            deviceHashSet.Add(name);
        });
    }

    public void Show(string info)
    {
        text.text = info;
    }
    /// <summary>
    /// 创建提示信息预制件
    /// </summary>
    /// <param name="address"></param>
    /// <param name="name"></param>
    private void CreationTextPrefab(string address, string name)
    {
        GameObject game = Instantiate<GameObject>(deviceInfoPrefab);
        DeviceInfo info = game.GetComponent<DeviceInfo>();
        info.textName.text = name;
        info.textAddress.text = address;
        game.transform.localScale = Vector3.one;
        game.transform.SetParent(container);
        info.btnConnect.onClick.AddListener(() =>
        {
            if (deviceHashSet.Contains(name)) //找到名字一样的设备
            {
                BluetoothLEHardwareInterface.StopScan(); //停止扫描
                ConnectBluetooth(deviceDictionary[name]);  //开始连接
            }
        });
    }

    /// <summary>
    /// 更新存储要连接设备的名字,是否扫描到
    /// </summary>
    /// <param name="name"></param>
    /// <param name="address"></param>
    public void AddPeripheral(string name, string address)
    {
        deviceDictionary.Add(name, address);
    }
    /// <summary>
    /// 开始连接设备
    /// </summary>
    public void ConnectBluetooth(string adress)
    {
        Show("开始连接设备");
        try
        {
            BluetoothLEHardwareInterface.ConnectToPeripheral(adress, null, null, (address, serviceUUID, characteristicUUID) =>
            {
                otherText.text += "连接成功\n";
                SubscribeCharacteristicWithDeviceAddress(address, serviceUUID, characteristicUUID);
            });
        }
        catch (Exception e)
        {
            Show("连接失败");
        }
    }

    /// <summary>
    /// 连接成功的回调
    /// </summary>
    private void SubscribeCharacteristicWithDeviceAddress(string address, string serviceUUID, string characteristicUUID)
    {
        if(!string.IsNullOrEmpty(serviceUUID) && !string.IsNullOrEmpty(characteristicUUID))
        {
            otherText.text += "正在订阅消息:"+ serviceUUID + ":" + characteristicUUID + "\n"; 
            bleAddress = address;
            BluetoothLEHardwareInterface.SubscribeCharacteristicWithDeviceAddress(address, serviceUUID, characteristicUUID, delegate { }, OnCharacteristicNotification);

        }
    }
    /// <summary>
    /// 收到数据
    /// </summary>
    /// <param name="arg1"></param>
    /// <param name="arg2"></param>
    /// <param name="arg3"></param>
    private void OnCharacteristicNotification(string arg1, string arg2, byte[] arg3)
    {
        //Show("接收到数据");
        otherText.text = "连接成功" + "\narg1=" + arg1 + "\narg2=" + arg2 + "\n";
        Show(ByteArrayToString(arg3));
    }
    /// <summary>
    /// 断开连接
    /// </summary>
    public void DisConnect()
    {
        BluetoothLEHardwareInterface.DisconnectPeripheral(bleAddress, (bleAddress) =>
        {
            Show(bleAddress + "已经断开");
            otherText.text = "";
            isScanning = false;
        });
    }
    /// <summary>
    /// 字节组转换为字符串
    /// </summary>
    /// <param name="ba"></param>
    /// <returns></returns>
    public static string ByteArrayToString(byte[] ba)
    {
        string hex = BitConverter.ToString(ba);
        return hex.Replace("-", "");
    }
}

6.挂载脚本并赋值,打包apk运行

注:本文参考了Unity插件-适用于iOS,tvOS和Android的蓝牙LE(2.3)的测试使用方法_unity蓝牙-CSDN博客


http://www.kler.cn/a/308197.html

相关文章:

  • 【Hadoop实训】Hive 数据操作①
  • 服务号消息折叠折射出的腾讯傲慢:上云会不会也一样?
  • 【测试框架篇】单元测试框架pytest(1):环境安装和配置
  • 深入理解接口测试:实用指南与最佳实践5.0(二)
  • 应对JSON解析键值对乱序问题的实用解决方案
  • Python用CEEMDAN-LSTM-VMD金融股价数据预测及SVR、AR、HAR对比可视化
  • 十.在vue中,发送axios请求应该放在created里还是mounted里?详解
  • 书生大模型全链路开源体系,学习
  • 5G Multicast/Broadcast Services(MBS) (二) Multicast
  • Spring Boot-Session管理问题
  • CentOS7更换阿里云yum更新源
  • C# USB通信技术(通过LibUsbDotNet库)
  • linux-硬件与设备管理-设备挂载与管理
  • NLP:微调BERT进行文本分类
  • Java高级Day43-类加载
  • mysql 修改索引
  • 服务端接口性能优化有哪些方案?
  • 安卓在子线程中使用Toast
  • [Linux]:进程间通信(下)
  • vue2、vue3生成二维码
  • 算法 | 基础排序算法:插入排序、选择排序、交换排序、归并排序
  • xml重点笔记(尚学堂 3h)
  • 使用 GaLore 预训练LLaMA-7B
  • 72、结合无人机进行rk3588oak-lite跟踪目标物体进行识别、跟踪、保持距离
  • Java数据结构应用(力扣题20. 有效的括号)
  • Excel 基础知识-操作手册1