美文网首页
Android Bluetooth 使用总结

Android Bluetooth 使用总结

作者: 我的_世界 | 来源:发表于2019-08-15 10:38 被阅读0次

    前言

    本文主要讲解经典蓝牙和BLE(低功耗蓝牙)的使用流程

    一.获取蓝牙适配器

    BluetoothAdapter 为蓝牙适配器,所有对蓝牙的操作都是通过它完成的.

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

    或者

    BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
    

    以上两种实际一样.

    二.开启蓝牙

    友好界面的开启,在onActivityResult中获取开启结果

    if (!mAdapter.isEnabled()){//先判断是否已开启
         Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
         startActivityForResult(intent,REQUEST_CODE);
    }
    

    简单粗暴的开启,当然这个也是异步开启的.

    if (!mAdapter.isEnabled()){//先判断是否已开启
       mAdapter.enable();
    }
    

    由于上面是该方式为异步开启,如果想监听则要注册广播,如下

    //注册广播
    private void registerBluetoothReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);//蓝牙状态改变的广播
        filter.addAction(BluetoothDevice.ACTION_FOUND);//找到设备的广播
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索完成的广播
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//开始扫描的广播
        filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//状态改变
        registerReceiver(mReceive, intentFilter);
    }
    //注销广播
    private void unregisterBluetoothReceiver() {
        if (mReceive != null) {
            unregisterReceiver(mReceive);
            mReceive = null;
        }
    }
    private BroadcastReceiver mReceive = new BroadcastReceiver() {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
             if (action == null) {
                 return;
             }
             switch (action) {
                 case BluetoothAdapter.ACTION_STATE_CHANGED:
                    int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
                    if(BluetoothAdapter.STATE_OFF == state) {
                        //蓝牙关闭
                    }else if(BluetoothAdapter.STATE_ON == state) {
                        //蓝牙开启,开始扫描蓝牙
                    }
                     break;
                 case BluetoothDevice.ACTION_ACL_CONNECTED:
                     break;
                 case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
                    //绑定状态返回
                     break;
                 case BluetoothDevice.ACTION_FOUND:
                    //扫描到的设备
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    break;
    
             }
        }
    };
    

    三.扫描蓝牙

    金典蓝牙和BLE蓝牙扫描方试上有区别了.

    1.经典蓝牙扫描

    经典蓝牙获取到的设备需要到上面注册的广播中获取.

    if (mAdapter.isDiscovering()){
        mAdapter.cancelDiscovery();
    }
    mAdapter.startDiscovery();
    

    2.BLE蓝牙扫描

    BLE扫描到的蓝牙直接回调得到设备

    public void startScanDevice() {
        BluetoothLeScanner bluetoothLeScanner = mAdapter.getBluetoothLeScanner();
        bluetoothLeScanner.startScan(mLocalScanCallback);
    }
    
    ScanCallback mLocalScanCallback = new ScanCallback() {
         @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
         @Override
         public void onScanResult(int callbackType, ScanResult result) {
            BluetoothDevice device = result.getDevice();
             //扫描到的设备
         }
    
         @Override
         public void onScanFailed(int errorCode) {
             
         }
     };
    

    四.连接蓝牙

    获取扫描到的BluetoothDevice(蓝牙设备)后即可连接.

    1.经典蓝牙

    配对

    该方法为异步调用,返回true为正在绑定,同样需要在上面注册的广播中获取结果

    boolean bond = device.createBond();
    
    连接

    客户端
    连接操作为耗时过程,应该到子线程中进行,代码中的uuid可以理解为http中的端口号,这是一个唯一标识.

    if (mAdapter.isDiscovering()) {
        mAdapter.cancelDiscovery();
    }
    ParcelUuid parcelUuid = device.getUuids()[0];
    BluetoothSocket mBluetoothSocket = device.createRfcommSocketToServiceRecord(parcelUuid.getUuid());
    if (!mBluetoothSocket.isConnected()) {
        mBluetoothSocket.connect();
    }
    

    服务端

    /**
     * 开启服务端
     */
    public void startBluetoothService() {
     
        while (true) {
            try {
                BluetoothServerSocket bluetoothServerSocket = mAdapter.listenUsingRfcommWithServiceRecord("zcx", UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                BluetoothSocket bluetoothSocket = bluetoothServerSocket.accept();
                if (bluetoothSocket != null) {
                    bluetoothServerSocket .close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    2.BLE蓝牙

    //连接蓝牙
    bluetoothGatt = device.connectGatt(getApplicationContext(), false, new BluetoothGattCallback() {
                            @ThreadChange
                            @Override
                            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                                //发现服务
                                bluetoothGatt.discoverServices();
                                if (newState == BluetoothProfile.STATE_CONNECTED) {
                                } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                                    
                                } else if (newState == BluetoothProfile.STATE_CONNECTING) {
                                    
                                } else if (newState == BluetoothProfile.STATE_DISCONNECTING) {
                                    
                                }
                            }
    
                            @Override
                            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                                super.onServicesDiscovered(gatt, status);
                                BluetoothGattService service = bluetoothGatt.getService(UUID.fromString(SERVICE_UUID));
                                BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(Characteristic_uuid));
                                //设置接收通知
                                bluetoothGatt.setCharacteristicNotification(characteristic, true);
                                //00002902-0000-1000-8000-00805f9b34fb为系统接受通知自带的UUID
                                BluetoothGattDescriptor dsc = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
                                dsc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                                //设置BluetoothGattDescriptor 使蓝牙设备发送通知信号时回调onCharacteristicChanged方法
                                boolean success = bluetoothGatt.writeDescriptor(dsc);
                                Log.d(TAG, "writing enabledescriptor:" + success);
                            }
    
                            @Override
                            public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                                
                            }
    
                            @Override
                            public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                                super.onCharacteristicWrite(gatt, characteristic, status);
                                
                            }
    
                            @Override
                            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                                //接收到的通知
                            }
                        });
    
                        break;
    
                }
    

    四.通讯

    1.经典蓝牙

    //接收消息,需要用个子线程
    public  void  receiveMessage(){
        if (bluetoothSocket == null){
            return;
        }
        try {
            InputStream inputStream = bluetoothSocket.getInputStream();
          
            BufferedReader bff = new BufferedReader(new InputStreamReader(inputStream));
            String message;
            while (true) {
                    while ((message= bff.readLine()) != null) {
                        //获取到的数据
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
     
    }
    
    
    //发送文本消息
    public static void sendMessage(String message) {
        if (bluetoothSocket == null || TextUtils.isEmpty(message)){
            return;
        } 
        try {
            message += "\r\n";
            OutputStream outputStream = bluetoothSocket.getOutputStream();
            outputStream.write(message.getBytes("utf-8"));
            outputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    
    

    2.BLE蓝牙

    ble接收消息在连接时的onCharacteristicChanged方法中可以接收到,这里需要发送的方法

    //发送文本消息
    public boolean sendMessage(String message) {
         if (bluetoothGatt == null) return false;
         BluetoothGattCharacteristic gc = bluetoothGatt.getService(UUID.fromString(SERVICE_UUID)).getCharacteristic(UUID.fromString(Characteristic_uuid));
         gc.setValue(message.getBytes());
         bluetoothGatt.writeCharacteristic(gc);
         return true;
    }
    

    android蓝牙到这里就结束了,可以愉快的使用蓝牙了

    总结

    这里总结一下这两种蓝牙区别吧
    金典蓝牙: 3.0版本以下的蓝牙,功耗高、传输数据量大、传输距离只有10米。
    BLE(低功耗)蓝牙 4.0及以上版本的蓝牙,低功耗、数据量小、距离50米左右。

    相关文章

      网友评论

          本文标题:Android Bluetooth 使用总结

          本文链接:https://www.haomeiwen.com/subject/okvajctx.html