安卓BLE蓝牙开发入门

     最近做了有关安卓BLE蓝牙开发的东西,所以在这里记录一下,是一些入门的知识。希望能帮到正需要学习安卓ble蓝牙开发的同学。

 

  1.    介绍:安卓 4.3(API 18)为 BLE 的核心功能提供平台支持和 API,App 可以利用它来发现设 备、查询服务和读写特性。相比传统的蓝牙,BLE 更显著的特点是低功耗。这一优 点使 Android App 可以与具有低功耗要求的 BLE 设备通信,如近距离传感器、心脏 速率监视器、健身设备等。

  2. 角色和责任 :
    以下是 Android 设备与 BLE 设备交互时的角色和责任: 
    中央 VS 外围设备。 适用于 BLE 连接本身。中央设备扫描,寻找广播;外 围设备发出广播。  GATT 服务端 VS GATT 客户端。决定了两个设备在建立连接后如何互相交 流。为了方便理解,想象你有一个 Android 手机和一个用于活动跟踪 BLE 设备,手机支 持中央角色,活动跟踪器支持外围(为了建立 BLE 连接你需要注意两件事,只支持 外围设备的两方或者只支持中央设备的两方不能互相通信)。 当手机和运动追踪器建立连接后,他们开始向另一方传输 GATT 数据。哪一方作为 服务器取决于他们传输数据的种类。例如,如果运动追踪器想向手机报告传感器数 据,运动追踪器是服务端。如果运动追踪器更新来自手机的数据,手机会作为服务 端。 

        代码编写:

  1.   权限部分:我开发过程中要了以下几个权限,才能正常使用相应功能。有些运行时申请的权限请各位读者自行申请权限。

                       

    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

    2.   第一步:检查设备是否支持BLE

private void check()//检查设备是否支持BLE
    {
        if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);        }

        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE))
        {
            Toast.makeText(this, "此设备不支持BLE功能", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

 

   3.  第二步:开启BLE蓝牙

      mBluetoothAdapter 是蓝牙设配器在整个蓝牙开发中有重要功能,后续也会用到这个对象,所以这里我们先初始化它。

 private void bleTurnOn()//开启BLE蓝牙
    {
        final BluetoothManager bluetoothManager =(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        // 确保蓝牙在设备上可以开启
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled())
        {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

        }

    }

 

  4. 开启/停止扫描蓝牙设备:

     mBluetoothAdapter这里充当了开启/停止蓝牙扫描的功能。

  private void scanLeDevice(final boolean enable)
    {
        if(enable){
            //时间超出预定扫描时间后,停止扫描。
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if(mScanning) {
                        mScanning = false;
                        mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    }
                }
            },SCAN_PERIOD);
            mScanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        }else{
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
    }

5.扫描的回调可以在这里连接设备

  private BluetoothAdapter.LeScanCallback mLeScanCallback =new 
  BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord)
        {

            if(device.getName()!=null&&device.getName().equals(bleName)){
               connect(device);

            }
            Log.d("scanResult","扫描到了一个BLE设备"+device.getName());
            runOnUiThread(new Runnable() {
                @Override
                public void run(){
                   Toast.makeText(MainActivity.this,"扫描到"+device.getName(),Toast.LENGTH_SHORT).show();
                }
            });
        }
    };

6.我们在这里看一下

mGattCallback

的代码。这也是BLE蓝牙开发的重要核心。

连接成功时,发现服务,写入数据....,都会回调

mGattCallback

的相应方法。

private BluetoothGattCallback mGattCallback= new BluetoothGattCallback() {
    // 连接状态改变的回调
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status,
        int newState) {
    
    };
 
    // 发现服务回调
    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {

    };
 
    @Override
    public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
        // 由mBluetoothGatt.readRemoteRssi()调用得到,可不停刷新rssi信号强度
     
    }
 
    // 写描述信息回调
    @Override
    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor
        descriptor, int status) {
        
    };
 
    // 写操作回调
    @Override
    public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic 
        characteristic, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
         
        }
    };
 
    // 读操作回调
    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic 
        characteristic, int status) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            
        }
    }
 
    // 数据改变回调(接收BLE设备发送的数据)
    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic 
        characteristic) {
 
        };
    };
}

 7.连接设备

   这里我们首先停止扫描蓝牙,然后用device.connectGatt()连接蓝牙设备。

 private void connect(BluetoothDevice device)
    {
        
        mBluetoothAdapter.stopLeScan(mLeScanCallback);
        mBluetoothGatt=device.connectGatt(MainActivity.this,false,mGattCallback);
        mScanning=false;


    }

8.扫描服务:我们可以在 

 public void onConnectionStateChange(BluetoothGatt gatt, int status,
        int newState) {
    
    };

里先判断连接是否成功然后使用 

 mBluetoothGatt.discoverServices();

扫描设备的服务。这里给出一个例子代码:

  public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState) {

            if (newState == BluetoothProfile.STATE_CONNECTED) {//当前蓝牙设备已经连接
                intentAction = ACTION_GATT_CONNECTED;
                mConnectionState = STATE_CONNECTED;//记录连接状态的
     
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this,gatt.getDevice().getName()+"设备已经连接",Toast.LENGTH_SHORT).show();
                    }
                });
                mBluetoothGatt.discoverServices();
                Log.i("connected", "Connected to GATT server.");
                Log.i("serviceFinding", "Attempting to start service discovery:" + mBluetoothGatt.discoverServices());
            } 
            }
        }

 

扫描到服务回调onServicesDiscovered(...)方法。

这里给出示例代码:

 public void onServicesDiscovered(BluetoothGatt gatt, int status){
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    List<BluetoothGattService> serviceList= gatt.getServices();//获取服务列表
                 }
        }

 

9.针对一个服务我们可以获取它的特征列表。然后对相应特征进行读写操作。

          List<BluetoothGattCharacteristic> mlist=service.getCharacteristics();

 10.读取特征数据

mBluetoothGatt.readCharacteristic(Characteristic a);
//使用mBluetoothGatt的readCharacteristic()进行读取即可。

11.写入特征数据

    private  void writeData(byte hexData[], BluetoothGattCharacteristic characteristic){

        characteristic.setValue(hexData);//先设置值,再写入。数据是比特数组。
        mBluetoothGatt.writeCharacteristic(characteristic);
 

    }

12.注意要想写入之后收到BLE设备的通知应该设置接受通知。示例代码如下:

 public void setCharacteristicNotification() {


        BluetoothGattDescriptor descriptor = readCharacteristic.getDescriptors().get(0);
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        mBluetoothGatt.writeDescriptor(descriptor);
        mBluetoothGatt.setCharacteristicNotification(readCharacteristic, true);



    }

13.备注:

所有关于FTPClient的操作都要异步执行,否则就会出现错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值