Loading... 目录 Unity Android 之 获取蓝牙Bluetooth 的状态,设置的蓝牙Bluetooth 的开关状态,并监听蓝牙Bluetooth 的状态变化方法整理 一、简单介绍 二、实现原理 三、注意事项 四、效果预览 五、实现步骤 Android 端: Unity 端 六、关键代码 Android 端 Unity 端 一、简单介绍 Unity Android 开发上会用到的技术简单整理,方便自己日后查看,能帮助到大家就更好了。 本节介绍,Unity 开发中,把从 Android 获取手机设备的蓝牙Bluetooth的状态,并设置蓝牙Bluetooth开关,监听蓝牙Bluetooth的状态变化的方法整理封装给Unity调用,方法不唯一,欢迎指正。 二、实现原理 1、获取蓝牙适配器 BluetoothAdapter.getDefaultAdapter() 2、bluetoothAdapter.isEnabled() 获取蓝牙的状态 3、bluetoothAdapter.enable()/bluetoothAdapter.disable() 设置蓝牙开关状态 4、使用广播监听 BluetoothAdapter.ACTION_STATE_CHANGED 蓝牙状态变化 5、打包成 aar ,Unity 调用 aar 的封装好的接口 三、注意事项 1、添加蓝牙权限 <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> 四、效果预览 五、实现步骤 Android 端: 1、新建一个Android Library 模块,其他默认设置就好 2、在模块中新建两个脚本,BluetoothStateUtil 封装各个功能,BluetoothStateInterface 一个接口函数,蓝牙状态变化的接口 3、脚本编辑 OK,Build - Make Module ‘xxxx’,打包 aar 4、打包成功,build 文件夹outputs/aar中就会 有对应的 aar 生成 Unity 端 1、把 Android 打包的 aar 导入 Unity 2、在场景中布局UI,Toggle 显示设置 蓝牙状态 3、在 Unity工程中,新建脚本,编辑对应功能 4、把 TestBluetoothStateWrapper 挂载到场景中,并对应赋值 5、运行场景,没有问题,即可打包到真机上测试 6、真机上的测试效果如上 六、关键代码 Android 端 1、BluetoothStateUtil package com.example.bluetoothstatewrapper; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.util.Log; import android.widget.Toast; public class BluetoothStateUtil { private static final String TAG = "Main_BluetoothStateUtil"; private BluetoothAdapter bluetoothAdapter; private BluetoothStateBroadcastReceive mReceive; private Context mContext; private BluetoothStateInterface mBluetoothStateInterface; /** * 初始化 */ public void Init(BluetoothStateInterface bluetoothStateInterface){ // 获得蓝牙适配器对象 bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); mContext = getActivity(); mBluetoothStateInterface = bluetoothStateInterface; } /** * 获取蓝牙状态 * @return */ public boolean getBlueToothState() { // 获取蓝牙状态 return bluetoothAdapter.isEnabled(); } /** * 开启蓝牙 * @return */ public boolean openBlueTooth() { if (getBlueToothState()) return true; // 打开蓝牙 return bluetoothAdapter.enable(); } /** * 关闭蓝牙 * @return */ public boolean colseBlueTooth() { if (!getBlueToothState()) return true; // 关闭蓝牙 return bluetoothAdapter.disable(); } // 调用系统的请求打开蓝牙 public void gotoSystem(Context context){ Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); context.startActivity(intent); } /** * 注册监听蓝牙变化 */ public void registerBluetoothReceiver(){ if(mReceive == null){ mReceive = new BluetoothStateBroadcastReceive(); } IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); intentFilter.addAction("android.bluetooth.BluetoothAdapter.STATE_OFF"); intentFilter.addAction("android.bluetooth.BluetoothAdapter.STATE_ON"); mContext.registerReceiver(mReceive, intentFilter); } /** * 取消监听蓝牙变化 */ public void unregisterBluetoothReceiver(){ if(mReceive != null){ mContext.unregisterReceiver(mReceive); mReceive = null; } } /** * 蓝牙状态变化监听 */ class BluetoothStateBroadcastReceive extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); switch (action){ case BluetoothDevice.ACTION_ACL_CONNECTED: //Toast.makeText(context , "蓝牙设备:" + device.getName() + "已连接", Toast.LENGTH_SHORT).show(); Log.i(TAG, "onReceive: "+"蓝牙设备:" + device.getName() + "已连接"); break; case BluetoothDevice.ACTION_ACL_DISCONNECTED: //Toast.makeText(context , "蓝牙设备:" + device.getName() + "已断开", Toast.LENGTH_SHORT).show(); Log.i(TAG, "onReceive: "+"蓝牙设备:" + device.getName() + "已断开"); break; case BluetoothAdapter.ACTION_STATE_CHANGED: int blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0); switch (blueState){ case BluetoothAdapter.STATE_OFF: //Toast.makeText(context , "蓝牙已关闭", Toast.LENGTH_SHORT).show(); Log.i(TAG, "onReceive: "+"蓝牙已关闭:" ); mBluetoothStateInterface.onBluetoothStateOFF(); break; case BluetoothAdapter.STATE_ON: //Toast.makeText(context , "蓝牙已开启" , Toast.LENGTH_SHORT).show(); Log.i(TAG, "onReceive: "+"蓝牙已开启:"); mBluetoothStateInterface.onBluetoothStateON(); break; } break; } } } // 设置一个 Activity 参数 private Activity _unityActivity; // 通过反射获取 Unity 的 Activity 的上下文 Activity getActivity(){ if(null == _unityActivity){ try{ Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer"); Activity activity = (Activity) classtype.getDeclaredField("currentActivity").get(classtype); _unityActivity = activity; }catch (ClassNotFoundException e){ e.printStackTrace(); }catch (IllegalAccessException e){ e.printStackTrace(); }catch (NoSuchFieldException e){ e.printStackTrace(); } } return _unityActivity; } } 2、BluetoothStateInterface package com.example.bluetoothstatewrapper; public interface BluetoothStateInterface { void onBluetoothStateON(); void onBluetoothStateOFF(); } 3、AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.bluetoothstatewrapper" > <uses-permission android:name="android.permission.BLUETOOTH"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> </manifest> Unity 端 1、BluetoothStateWrapper using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace AndroidWrapper { /// <summary> /// 蓝牙状态封装 /// 使用说明 /// 1、首先初始化,绑定监听事件 /// 2、可获取蓝牙状态,设置蓝牙状态 /// 3、获得监听结果 /// </summary> public class BluetoothStateWrapper : MonoSingleton<BluetoothStateWrapper> { /// <summary> /// 初始化 /// </summary> /// <param name="VoiceVolumnChangedListener"></param> public void Init(Action OnBluetoothStateONListener, Action OnBluetoothStateOFFListener) { #if UNITY_EDITOR #else MAndroidJavaObject.Call("Init",new BluetoothStateInterface(OnBluetoothStateONListener, OnBluetoothStateOFFListener)); registerBluetoothReceiver(); #endif } /// <summary> /// 获得蓝牙状态 /// </summary> /// <returns></returns> public bool getBlueToothState() { return MAndroidJavaObject.Call<bool>("getBlueToothState"); } /// <summary> /// 开启蓝牙 /// </summary> /// <returns></returns> public bool openBlueTooth() { return MAndroidJavaObject.Call<bool>("openBlueTooth"); } /// <summary> /// 关闭蓝牙 /// </summary> /// <returns></returns> public bool colseBlueTooth() { return MAndroidJavaObject.Call<bool>("colseBlueTooth"); } #region 私有方法 /// <summary> /// 注册蓝牙状态监听 /// </summary> void registerBluetoothReceiver() { MAndroidJavaObject.Call("registerBluetoothReceiver"); } /// <summary> /// 取消注册蓝牙状态监听 /// </summary> void unregisterBluetoothReceiver() { MAndroidJavaObject.Call("unregisterBluetoothReceiver"); } protected override void OnDestroy() { unregisterBluetoothReceiver(); base.OnDestroy(); } #endregion #region 私有变量 AndroidJavaObject _mAndroidJavaObject; public AndroidJavaObject MAndroidJavaObject { get { if (_mAndroidJavaObject == null) { _mAndroidJavaObject = new AndroidJavaObject("com.example.bluetoothstatewrapper.BluetoothStateUtil"); } return _mAndroidJavaObject; } } #endregion } } 2、BluetoothStateInterface using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace AndroidWrapper { /// <summary> /// 蓝牙状态监听接口 /// </summary> public class BluetoothStateInterface : AndroidJavaProxy { /// <summary> /// 蓝牙变化委托事件 /// </summary> Action _mBluetoothStateON; Action _mBluetoothStateOFF; public BluetoothStateInterface(Action mBluetoothStateON, Action mBluetoothStateOFF) : base("com.example.bluetoothstatewrapper.BluetoothStateInterface") { _mBluetoothStateON = mBluetoothStateON; _mBluetoothStateOFF = mBluetoothStateOFF; } /// <summary> /// 蓝牙打开事件监听 /// </summary> public void onBluetoothStateON() { if (_mBluetoothStateON != null) { _mBluetoothStateON(); } Debug.Log(GetType() + "/onBluetoothStateON()/ 蓝牙开启事件"); } /// <summary> /// 蓝牙关闭事件监听 /// </summary> public void onBluetoothStateOFF() { if (_mBluetoothStateOFF != null) { _mBluetoothStateOFF(); } Debug.Log(GetType() + "/onBluetoothStateOFF()/ 蓝牙关闭事件"); } } } 3、TestBluetoothStateWrapper using System.Collections; using System.Collections.Generic; using UnityEngine; using AndroidWrapper; using UnityEngine.UI; public class TestBluetoothStateWrapper : MonoBehaviour { public Toggle BTState_Toggle; // Start is called before the first frame update void Start() { BluetoothStateWrapper.Instance.Init(SetOnToggle, SetOffToggle); InitToggle(); } /// <summary> /// 初始化 /// </summary> void InitToggle() { #if UNITY_EDITOR // 获取当前状态 SetIsOnToggle(Random.Range(0,2) ==0 ? false:true); // 设置监听事件 BTState_Toggle.onValueChanged.AddListener((isOn) => { }); #else // 获取当前状态 SetIsOnToggle(BluetoothStateWrapper.Instance.getBlueToothState()); // 设置监听事件 BTState_Toggle.onValueChanged.AddListener((isOn)=> { if (isOn == true) { BluetoothStateWrapper.Instance.openBlueTooth(); } else { BluetoothStateWrapper.Instance.colseBlueTooth(); } }); #endif } void SetOnToggle() { SetIsOnToggle(true); } void SetOffToggle() { SetIsOnToggle(false); } void SetIsOnToggle(bool isOn) { BTState_Toggle.isOn = isOn; } } 4、MonoSingleton using UnityEngine; public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour { private static T instance = null; private static readonly object locker = new object(); private static bool bAppQuitting; public static T Instance { get { if (bAppQuitting) { instance = null; return instance; } lock (locker) { if (instance == null) { instance = FindObjectOfType<T>(); if (FindObjectsOfType<T>().Length > 1) { Debug.LogError("不应该存在多个单例!"); return instance; } if (instance == null) { var singleton = new GameObject(); instance = singleton.AddComponent<T>(); singleton.name = "(singleton)" + typeof(T); singleton.hideFlags = HideFlags.None; DontDestroyOnLoad(singleton); } else DontDestroyOnLoad(instance.gameObject); } instance.hideFlags = HideFlags.None; return instance; } } } protected virtual void Awake() { bAppQuitting = false; } protected virtual void OnDestroy() { bAppQuitting = true; } } ———————————————— 版权声明:本文为CSDN博主「仙魁XAN」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/u014361280/article/details/108217598 最后修改:2021 年 11 月 26 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,请随意赞赏