安卓蓝牙开发 1. 发现过程

Posted 编程圈子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安卓蓝牙开发 1. 发现过程相关的知识,希望对你有一定的参考价值。

安卓蓝牙开发 1. 发现过程

一、基本概念

蓝牙是一种低功耗、低成本、近距离的无线连接方案,已经经历了2.0、2.1、3.0、4.0、4.2、5.0、5.1、5.2等多个版本迭代。

安卓4.3版本引入了蓝牙支持,可以用于发现设备、查询服务和传输信息。

安卓支持的蓝牙通讯主要是两种:

  1. GATT和ATT 实现与附近的设备传输少量的数据(低功耗蓝牙),主要用在鼠标、键盘、物联网设备通讯。
  2. 传统大数据通讯。

二、 蓝牙发现

安卓开发蓝牙程序一般过程:

Created with Raphaël 2.3.0 设备是否支持蓝牙 蓝牙是否打开? 打开蓝牙 搜索蓝牙设备 连接蓝牙 设备通讯 yes no

三、相关API

  • BluetoothAdapter:本地蓝牙适配器
  • BluetoothDevice:蓝牙设备对象
  • BluetoothProfile:通用的蓝牙规范(数据收发协议)
  • BluetoothGatt:蓝牙通用属性协议,用于连接设备、搜索服务等
  • BluetoothGattCallback:蓝牙连接成功回调函数
  • BluetoothGattService:蓝牙设备提供的服务,它是蓝牙设备特征的集合
  • BluetoothGattCharacteristic:蓝牙设备特征,构建GATT服务的基本单位
  • BluetoothGattDescriptor:蓝牙设备特征描述符,对特征的额外描述。

四、发现的过程

1. 启用权限

<!-- 通用蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
 
<!-- 位置权限,安卓6.0以上发现过程需要位置权限 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

SDK23以上需要添加运行时权限:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
        checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
        checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
        checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ) 
             requestPermissions(new String[]Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION ,
            Manifest.permission.CAMERA,, 1);

2. 获取BluetoothAdapter

private BluetoothAdapter mBluetoothAdapter;

final BluetoothManager bletoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdatper  bluetoothManager.getAdapter();

3. 判断蓝牙是否开启

if(mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled())
   // 如果没有开启,转到用户蓝牙设备界面
   Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
   startActivityForResult(enableBtIntent, 6);
   

4. 查找蓝牙设备

以下三种方式可以用来执行查找蓝牙设备的操作。

4.4.1 BluetoothAdapter.startLeScan

BluetoothAdapter的 startLeScan方法用来查找设备。查找过程是一个异步方法,查找完成,通过 实现 BluetoothAdapter.LeScanCallback回调查看查找结果 。
在onLeScan() 中不能做耗时操作,否则容易堵塞。

startLeScan的定义:


public boolean startLeScan(LeScanCallback callback) ;
public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) ;

可以通过UUID[] 来设置扫描特定类型的外设。

扫描的代码片段:

    private Handler mHandler;

    // 延迟执行的函数,用来限定扫描时间
    mHandler.postDelayed(new Runnable() 
        @Override
        public void run() 
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        
    , 10*1000);

    mScanning = true;
    mBluetoothAdapter.startLeScan(mLeScanCallback);

4.4.2 getBluetoothLeScanner()

bluetoothAdapter.getBluetoothLeScanner()用来获取一个扫描器,这个扫描器可以设置扫描蓝牙的模式、过滤器等参数。整体来说,与上一种方式区别不大。

           List<ScanFilter> filters = new ArrayList<>();
           ScanFilter filter = new ScanFilter.Builder().setDeviceName("要限定的蓝牙名称").build();
             filters.add(filter);
             ScanSettings scanSettings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();

             scanner.startScan(filters, scanSettings, scanCallback);
             Looper.prepare();
             new Handler().postDelayed(() -> 
                 scanner.stopScan(scanCallback);
                 Looper.myLooper().quit();
             , 30 * 1000L);
             Looper.loop();

4.4.3 startDiscovery()方法

这个方法要继承一个BroadcastReceiver的广播,重写其中的onReceive方法。

// 定义 广播接收
class SingBroadcastReceiver extends BroadcastReceiver 
    @Override
    public void onReceive(Context context, Intent intent) 
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action) )
            // Get the BluetoothDevice object from the Intent
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // Add the name and address to an array adapter to show in a Toast
            String derp = device.getName() + " - " + device.getAddress();
            Toast.makeText(context, derp, Toast.LENGTH_LONG).show();
        
    


// 注册广播、创建SingBroadcastReceiver对象。
SingBroadcastReceiver mReceiver=new SingBroadcastReceiver ();
 mBluetoothAdapter.startDiscovery();
 IntentFilter ifilter1= new IntentFilter(BluetoothDevice.ACTION_FOUND);
  registerReceiver(mReceiver, ifilter1);

// 扫描
mBluetoothAdapter.startDiscovery();
// 停止扫描
mBluetoothAdapter.cancelDiscovery();

使用这种方式注意广播要及时关闭。

5. 在查找的回调函数中取得扫描的设备

上面每种扫描方式对应的回调函数有所不同。

4.5.1 使用 BluetoothAdapter.start.LeScan的回调

BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() 
      @Override
      public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) 
          mArrayAdapter.add(device.getName() + "\\n" + device.getAddress());
          lv_bluetooth.setAdapter(mArrayAdapter);
          Log.d(TAG, "onLeScan:563463 ");
      
  ;

4.5.2 getBluetoothLeScanner

@Override
            public void onScanResult(int callbackType, ScanResult result) 
                BluetoothDevice device = result.getDevice();
                Log.i(TAG, "蓝牙设备名称:" + device.getName() + ";address=" + device.getAddress());
                super.onScanResult(callbackType, result);
            

4.5.3 在前一章节发现的方法中已经定义了回调。

以上是关于安卓蓝牙开发 1. 发现过程的主要内容,如果未能解决你的问题,请参考以下文章

蓝牙设备的特征值及其编码

Android蓝牙开发(二)经典蓝牙消息传输实现

基于蓝牙的安卓客户端开发

安卓开发蓝牙接收数据,返回数据如何处理

Android蓝牙连接自动测试工具

微信小程序蓝牙模块BLE开发说明基础知识