实现功能

  • 检测是否拥有蓝牙权限
  • 监视蓝牙开关
  • 监视蓝牙连接断开
  • 获取蓝牙配对列表
  • 获取当前连接的蓝牙信息

1.在AndroidManifest.xml文件中添加蓝牙权限

<!--  定位权限,用于获取手机的大致或精准位置 于发现附近的蓝牙设备通常是必需的  -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!-- 允许应用程序发现和配对蓝牙设备   -->
    <uses-permission android:name="android.permission.BLUETOOTH_ADACCESS_FINE_LOCATIONMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <!-- 允许应用程序连接到已配对的蓝牙设备并进行数据传输   -->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <!--  允许应用发起对蓝牙设备的连接  -->
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

2.在Activity的onCreate方法中进行运行时的动态权限获取(如果是在Activity类里面申请的直接把(Activity) mUniSDKInstance.getContext()替换成this即可。120这可以随便写)

有人问为什么在AndroidManifest.xml文件中添加了蓝牙权限,为什么运行时还要申请一遍

应为在 Android 6.0 (API 级别 23) 及更高版本中,用户需要在运行时授予权限。对于一些需要特殊权限的操作(如定位、读写存储等),仅在 AndroidManifest.xml 文件中声明这些权限是不够的,你还需要在运行时进行权限请求

ActivityCompat.requestPermissions((Activity) mUniSDKInstance.getContext(), new String[]{Manifest.permission.BLUETOOTH}, 120);

注意:这个请求会在手机上面进行UI弹窗,点击允许即可如果点击拒绝会获取不到蓝牙的任何操作

3.创建自定义广播接收器(BroadcastReceiver)。这个类会响应系统发出的关于蓝牙状态的广播


 实现

  • 监视蓝牙开关
  • 监视蓝牙连接断开
  • 获取当前连接的蓝牙信息
package io.bluet.uniplugin;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
 * 全局蓝牙广播器
 */
public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Log.e("Bluetooth", "action: "+action);

        if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
            //蓝牙设备已断开连接
            Log.e("Bluetooth", "蓝牙设备已断开连接");
            

        }else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)){
            //蓝牙连接
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            Log.e("Bluetooth", "蓝牙连接");
            Log.e("Bluetooth", "连接蓝牙的名称: "+device.getName());
            Log.e("Bluetooth", "连接蓝牙的地址: "+device.getAddress());
        }


        // 判断蓝牙是否打开
        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
            switch(state) {
                case BluetoothAdapter.STATE_TURNING_ON:
                    // 蓝牙正在打开
                    Log.e("Bluetooth", "蓝牙正在打开");
                    break;
                case BluetoothAdapter.STATE_ON:
                    // 蓝牙已经打开
                    Log.e("Bluetooth", "蓝牙已经打开");
                    break;
                case BluetoothAdapter.STATE_TURNING_OFF:
                    // 蓝牙正在关闭
                    Log.e("Bluetooth", "蓝牙正在关闭");
                    break;
                case BluetoothAdapter.STATE_OFF:
                    // 蓝牙已经关闭
                    Log.e("Bluetooth", "蓝牙已经关闭");
                    break;
            }
        }
    }
}

4.在AndroidManifest.xml文件中注册您的自定义广播接收器(BroadcastReceiver)的配置项

<receiver android:name="io.bluet.uniplugin.MyBroadcastReceiver"  android:exported="true" android:launchMode="singleInstance">
            <intent-filter>
                <action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
                <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
                <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
            </intent-filter>
        </receiver>

 android:name属性指定了您的广播接收器的完全限定类名(包名 + 类名)

android:exported="true"表示其他应用可以给您的应用发送此广播。如果为"false"则表示只有系统或者应用内部可以发送此广播

android:launchMode="singleInstance"表示此接收器的启动模式为单实例模式,即在进程存在的情况下不会重新创建接收器,而是复用已存在的实例

<intent-filter>标签为您的广播接收器定义了一个意图过滤器。这意味着您的广播接收器只接收满足过滤器配置的广播

过滤器配置了三个<action>,分别为: 

  • android.bluetooth.device.action.ACL_CONNECTED: 蓝牙设备已连接的广播;
  • android.bluetooth.device.action.ACL_DISCONNECTED: 蓝牙设备已断开的广播;
  • android.bluetooth.adapter.action.STATE_CHANGED: 蓝牙状态已改变的广播。

在AndroidManifest.xml文件中的定义,MyBroadcastReceiver是全局的广播接收器 

注意:上面的代码判断不了第一次进入app蓝牙的问题 。应为进入app的时候才注册的广播接收器之前的蓝牙操作是检测不到的,只能检测在app内操作蓝牙的消息,app外操作的蓝牙是检测不到的。

5.下面代码是解决第一次进入app检测不到蓝牙通知的代码方法(每次进入app先使用这个进行判断蓝牙的一些列操作,后面app内的蓝牙操作可以用上面的广播进行实时获取蓝牙信息)

public static void checkBluetoothPermissions(Context context){
        BluetoothAdapter defaultAdapter = BluetoothAdapter.getDefaultAdapter();
        if (defaultAdapter == null){
            // 设备不支持蓝牙功能
            Log.e("Bluetooth", "设备不支持蓝牙功能");
            return;
        }else{
            if (!defaultAdapter.isEnabled()){
                //蓝牙未开启
                Log.e("Bluetooth", "蓝牙未开启");
                return;
            }else{
                // 蓝牙已开启
                Log.e("Bluetooth", "蓝牙已开启");
            }
        }

        try {
            Set<BluetoothDevice> bluetoothDeviceSet =  defaultAdapter.getBondedDevices();
            if (bluetoothDeviceSet.size() > 0){  //判断适配器里面是否有自己的耳机  
                for (BluetoothDevice device : bluetoothDeviceSet) {   //这里的循环是获取手机里面所有配对成功的蓝牙信息
                    // device 是已配对或已连接的蓝牙设备
                    String deviceName = device.getName(); // 获取设备名称
                    String deviceHardwareAddress = device.getAddress(); // 获取设备MAC地址
                    // 根据设备的名称或地址,判断是哪一个蓝牙设备
                    Log.e("Bluetooth", "蓝牙名称: "+device.getName());
                    Log.e("Bluetooth", "蓝牙地址: "+device.getAddress());
                       // Test  改成独特的耳机名称
                    if ("Test".equals(deviceName)){
                        defaultAdapter.getProfileProxy(context, new BluetoothProfile.ServiceListener() {
                            @Override
                            public void onServiceConnected(int profile, BluetoothProfile bluetoothProfile) {
                                List<BluetoothDevice> devices = bluetoothProfile.getConnectedDevices();
                                for (BluetoothDevice device : devices) {
                                    // device 是已连接的蓝牙设备
                                    String deviceName = device.getName(); // 获取设备名称
                                    String deviceHardwareAddress = device.getAddress(); // 获取设备MAC地址
                                    // 根据设备的名称或地址,判断是哪一个蓝牙设备
                                    if ("Test".equals(deviceName)){
                                       
                                    }else{
                                        
                                    }
                                }
                            }
                            @Override
                            public void onServiceDisconnected(int i) {
                            }
                        }, BluetoothProfile.A2DP);
                    }else{
                       
                    }
                }
            }else{
                Log.e("Bluetooth", "蓝牙列表里面没有配对或已连接的蓝牙设备");
            }
        }catch (SecurityException e){
            Log.e("Bluetooth","获取不到蓝牙权限");
        }
    }

Activity类里面的方法可以监听到app的生命周期,比如退出,进入,切换app。但是要在AndroidManifest.xml配置程序的入口

<activity
            android:name="com.xxx.xxx.MyActivity改成自己的Activity程序入口类即可"
            android:configChanges="orientation|keyboardHidden|keyboard|navigation"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:hardwareAccelerated="true"
            android:theme="@style/TranslucentTheme"
            android:screenOrientation="user"
            android:windowSoftInputMode="adjustResize" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>