Android 蓝牙开发(BLE)封装

声明

本文主要讲解BLE(低功耗蓝牙4.0以上)的使用和封装,为了UI层方便拿取数据展示,统一对蓝牙搜索、连接、数据交互、蓝牙协议等封装为lib。

一.BLE简介

为什么要学习蓝牙技术,蓝牙作为一种成熟、低功耗无线通信技术的先锋,在可穿戴设备领域中扮演着越来越重要的作用。

BLE分为三部分:ServiceCharacteristicDescriptor。这三部分都是使用UUID来作为唯一标识符加以区分。一个BLE终端可以包含多个Service,一个Service可以包含多个Characteristic,而一个Characteristic包含一个value和多个Descriptor,一个Descriptor只包含一个valueUUID格式为:0000ffe1-0000-1000-8000-00805f9b34fb

二.蓝牙前期简单介绍

1.添加权限

<uses-permission android:name="android.permission.BLUETOOTH" /><!--蓝牙管理-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><!--蓝牙操作权限-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><!--在有些机型上需要获取位置信息才能扫描到蓝牙设备,此权限在api23+需要动态申请-->
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" /> <!--表示此app只支持拥有BLE的设备上运行-->

如果你不确定你的app使用的设备是否支持低功耗蓝牙,但又想让支持的设备使用低功耗蓝牙,把标志位改为false,同时去代码中判断设备是否支持BLE:

// 是否支持蓝牙低功耗广播(4.3+)
if (!getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            finish()//此处可以根据特定需求去改变处理
            return false;
}

2.蓝牙适配器BluetoothAdapter

有两种获取方式:

1).BluetoothManager bluetoothManager =(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
  BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();

2).BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 

此处需要做非空判断,为null则表示设备不支持蓝牙。

BluetoothAdapter方法描述:
  • isEnabled() 判断系统蓝牙是否打开
  • disable() 无弹窗提示关闭系统蓝牙
  • enable() 无弹窗提示打开系统蓝牙(此操作有点不友好!)
  • startDiscovery() 开始搜索设备 —–适合经典蓝牙和低功耗蓝牙两种
  • cancelDiscovery() 取消搜索设备
  • startLeScan() 开始搜索设备 —–适合扫描低功耗蓝牙,但是在api21以上被标记废弃使用
  • stopLeScan() 停止搜索设备
  • startScan() 开始搜索设备 —–api21以上扫描低功耗蓝牙,通过bluetoothAdapter.getBluetoothLeScanner()方法获取
  • stopScan() 停止搜索设备
  • stopScan() 停止搜索设备

说明:startDiscovery()方法在大多数手机上是可以同时发现经典蓝牙和低功耗蓝牙(BLE)的,但是startDiscovery()的回调无法返回BLE的广播,所以无法通过广播识别设备,而且startDiscovery()扫描BLE效率比startLeScan()低很多。因此需要根据具体的需求去做适配,才能更高效的搜寻蓝牙。PS: startLeScan()和startScan()有重载方法可以指定规则,参数去搜索。

3.蓝牙协议BluetoothGatt

获取方式:

BluetoothGatt mBluetoothGatt = device.connectGatt(getContext(), false, mGattCallback);//创建连接
BluetoothGatt方法描述:
  • connect() 连接远程设备
  • discoverServices() 搜索连接设备所支持的service
  • disconnect() 断开与远程设备的GATT连接
  • close() 关闭GATT Client端,释放资源
  • readCharacteristic(characteristic) 在指定的characteristic特征端口中读取数据
  • writeDescriptor(characteristic) 在指定的characteristic特征端口中写入数据
  • setCharacteristicNotification(characteristic, enabled) 设置当指定characteristic特征端口值变化时,是否发出通知返回
  • readRemoteRssi() 读取当前连接设备信号值,返回数值为负,值越小信号越弱。
  • getServices() 获取远程设备所支持的services
  • getDevice() 获取已连接的设备信息

三.蓝牙正式封装

与BLE蓝牙交互分为三步骤:搜索、连接、读写数据。BLE蓝牙无需配对即可连接

1.搜索、连接蓝牙

在搜索、连接蓝牙之前,首先对官方提供的BluetoothLeService进行一层封装,此类无非就是对BluetoothGatt协议的的获取和使用(连接设备,断开连接,发现服务,读写设备等操作)。本文采用单列模式和接口回调方式进行解耦分离、数据交互,源码实现方式为服务+广播的形式。PS:ble蓝牙官方demo网上资源还是比较多的,如果没有可以在下方留言。

package com.csym.bluetoothlib;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;

import com.orhanobut.logger.Logger;

import java.util.List;

/**
 * 蓝牙服务管理类
 * Created by ${zhoupeng} on 2016/8/10.
 */
public class BluetoothLeService {
   

    private BluetoothManager mBluetoothManager;//用来获取蓝牙适配器
    private BluetoothAdapter mBluetoothAdapter;//蓝牙适配器,处理系统蓝牙是否打开,搜索设备
    private BluetoothGatt mBluetoothGatt;//发现蓝牙服务,根据特征值处理数据交互
    private BluetoothDevice mBluetoothDevice = null;//蓝牙设备

    private static BluetoothLeService INSTANCE = null;//单列模式
    private static Context mContext;//上下文

    /**
     * 是否连接
     */
    private boolean isConnected = false;

    public boolean isConnected() {
        return isConnected;
    }

    public void setConnected(boolean connected) {
        isConnected = connected;
    }

    /**
     * 获取上下文
     *
     * @return context
     */
    private Context getContext() {
        return mContext;
    }

    private BluetoothLeService() {
        boolean value = initialize();
        if (!value) Logger.e("蓝牙适配器adapter初始化失败!!!");
    }

    /**
     * 单列模式,确保唯一性
     *
     * @param context 上下文
     * @return 对象
     */
    public static BluetoothLeService getInstance(Context context) {
        mContext = context;
        if (INSTANCE == null) {
            synchronized (BluetoothLeService.class) {
                if (INSTANCE == null) {
                    INSTANCE = new BluetoothLeService();
                }
            }
        }
        return INSTANCE;
    }

    /**
     * 初始化bluetooth adapter
     *
     * @return 为null返回false
     */
    private boolean initialize() {
        if (mBluetoothManager == null) {
            mBluetoothManager = (BluetoothManager) getContext().getSystemService(Context.BLUETOOTH_SERVICE);
        }
        if (mBluetoothManager == null) return false;
        mBluetoothAdapter = mBluetoothManager.getAdapter();
        return mBluetoothAdapter != null;
    }

    /**
     * 启用或者禁用通知\标志返回特性 true, if the requested notification status was set successfully
     *
     * @param characteristic 蓝牙特征对象
     * @param enabled        是否允许
     * @return 设置成功或失败
     */
    public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
        return !(mBluetoothAdapter == null || mBluetoothGatt == null)
                && mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
    }

    public boolean writeDescriptor(BluetoothGattDescriptor bluetoothGattDescriptor) {
        return !(bluetoothGattDescriptor == null || mBluetoothGatt == null)
                && mBluetoothGatt.writeDescriptor(bluetoothGattDescriptor);
    }

    /**
     * 发现数据通道服务
     *
     * @return true or false
     */
    public boolean discoverServices() {
        return !(!isConnected() || mBluetoothGatt == null)
                && mBluetoothGatt.discoverServices();
    }

    /**
     * 读取蓝牙数据
     *
     * @param characteristic 蓝牙特征值
     * @return true or false
     */
    public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
        return !(mBluetoothAdapter == null || mBluetoothGatt == null)
                && mBluetoothGatt.readCharacteristic(characteristic);
    }

    /**
     * 往设备中写入数据
     *
     * @param characteristic 蓝牙特征值
     * @return true or false
     */
    public boolean writeCharecteristic(BluetoothGattCharacteristic characteristic) {
        return !(mBluetoothAdapter == null || mBluetoothGatt == null)
                && mBluetoothGatt.writeCharacteristic(characteristic);
    }

    /**
     * 获取gatt服务列表
     *
     * @return 远程设备提供的gatt服务列表(功能通道)
     */
    public List<BluetoothGattService> getSupportedGattServices() {
        if (mBluetoothGatt == null) return null;
        return mBluetoothGatt.getServices();
    }

    /
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值