Android Bluetooth BLE(3)

The previous article talked about connecting devices, and this article talked about Bluetooth device communication.
The following categories are mainly used.

BluetoothGattService: (Bluetooth Service) There is at least one or more services on a Bluetooth device.
BluetoothGattCharacteristic: (Bluetooth characteristics) There is at least one or more characteristics in a service.
UUID: Each service and feature has a specific UUID, which is similar to an ID number.

Code: Find the service when the connection is successful:

case BluetoothGatt.STATE_CONNECTED://已连接
                    Log.e("lee", "已连接");
                    //去寻找服务
                    bluetoothGatt.discoverServices();
                    break;

       //当服务被找到时回调此方法。
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {//寻找服务成功。
                //或许该设备下的所有服务(每个服务都有自己的UUID)
                List<BluetoothGattService> services = gatt.getServices();
                for (BluetoothGattService service : services) {
                    //获取该服务下的所有的特性
                    List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
                    for (BluetoothGattCharacteristic characteristic : characteristics) {
                        //此处可以和蓝牙设备的硬件工程师交流 哪个特征值是对应的什么效果。 然后通过调用
                        if (characteristic.getUuid().equals("00000")) {//(此处我就瞎写一个) 通过UUID来获取硬件工程师告诉你的特征
                            characteristic.setValue(new byte[]{0x05});//(这个也是我瞎写的  需要蓝牙硬件工程师告诉你)
                            //调用了这个setValue()方法写入对应的数据,就能调用蓝牙设备的该特性了。
                        }
                    }
                }
            }
        }

Of course, the setValue() method here is generally written in the click event of a certain button, so the
characteristic needs to be extracted and assigned to a member variable.

This completes the function of the App to control the Bluetooth device.

                        if (characteristic.getUuid().equals("11111")) {//(此处我就瞎写一个) 获取设备控制App的命令

                            //调用此方法获取设备的通知
                            characteristic.notify();//(这个也是我瞎写的)
                        }


        //当特征值改变时回调此方法。
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            //通过判断characteristic的UUID和我们下面的那个11111的UUid是不是一样的 是一样的就可以做对应的操作了。
            if (characteristic.getUuid().equals("11111")){
                //获取characteristic中的值
                byte[] value = characteristic.getValue();
                //转化成16进制
                String s = bytesToHex(value);
                if (s.equals("0x55")){
                    //执行对应的操作
                }
            }
        }

The above completes the Bluetooth device control mobile phone.

You need to use the read method when you need to always read a piece of information on the device

if (characteristic.getUuid().equals("22222")) {//(此处我就瞎写一个) 获取设备的电量

                            //调用此方法获取设备的通知 读取到时会回调
                            gatt.readCharacteristic(characteristic);
                        }


//当读取到设备的信息时回调此方法
        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {//读取成功
                if (characteristic.getUuid().equals("22222")) {
                    byte[] value = characteristic.getValue();
                }
            }
        }

The following is the entire code

package com.demo.ibeacondemo;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private BluetoothAdapter mBluetoothAdapter;
    private static final int REQUEST_COARSE_LOCATION = 0;
    private List<BluetoothDevice> devices = new ArrayList<>();
    private BluetoothGatt bluetoothGatt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        isLocationOpen();
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {

            Intent enableBluetooth = new Intent(

                    BluetoothAdapter.ACTION_REQUEST_ENABLE);

            startActivityForResult(enableBluetooth, 1);
        }
        mBluetoothAdapter.startLeScan(mLeScanCallback);
    }

    static final char[] hexArray = "0123456789ABCDEF".toCharArray();

    private void isLocationOpen() {
        //清单文件里面也需要配置
        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,}, 0);
        }
    }

    //系统方法,从requestPermissions()方法回调结果
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        //确保是我们的请求
        if (requestCode == REQUEST_COARSE_LOCATION) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "权限被授予", Toast.LENGTH_SHORT).show();
            } else if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "权限被拒绝", Toast.LENGTH_SHORT).show();
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    private static String bytesToHex(byte[] bytes) {

        char[] hexChars = new char[bytes.length * 2];

        for (int j = 0; j < bytes.length; j++) {

            int v = bytes[j] & 0xFF;

            hexChars[j * 2] = hexArray[v >>> 4];

            hexChars[j * 2 + 1] = hexArray[v & 0x0F];

        }

        return new String(hexChars);

    }

    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {

        @Override

        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
            if (!devices.contains(device)) {

            }
            bluetoothGatt = device.connectGatt(MainActivity.this, false, gattCallback);
        }
    };


    private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
        //链接状态改变回调此方法。
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            switch (newState) {
                case BluetoothGatt.STATE_CONNECTED://已连接
                    Log.e("lee", "已连接");
                    //去寻找服务
                    bluetoothGatt.discoverServices();
                    break;
                case BluetoothGatt.STATE_CONNECTING://连接中
                    Log.e("lee", "连接中");
                    break;
                case BluetoothGatt.STATE_DISCONNECTED://已断开
                    Log.e("lee", "已断开");
                    break;
                case BluetoothGatt.STATE_DISCONNECTING://断开中
                    Log.e("lee", "断开中");
                    break;
            }
        }
		
		//当读取到设备的信息时回调此方法
        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {//读取成功
                if (characteristic.getUuid().equals("22222")) {
                    byte[] value = characteristic.getValue();
                }
            }
        }

        //当特征值改变时回调此方法。
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            //通过判断characteristic的UUID和我们下面的那个11111的UUid是不是一样的 是一样的就可以做对应的操作了。
            if (characteristic.getUuid().equals("11111")){
                //获取characteristic中的值
                byte[] value = characteristic.getValue();
                //转化成16进制
                String s = bytesToHex(value);
                if (s.equals("0x55")){
                    //执行对应的操作
                }
            }
        }

        //当服务被找到时回调此方法。
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {//寻找服务成功。
                //或许该设备下的所有服务(每个服务都有自己的UUID)
                List<BluetoothGattService> services = gatt.getServices();
                for (BluetoothGattService service : services) {
                    //获取该服务下的所有的特性
                    List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
                    for (BluetoothGattCharacteristic characteristic : characteristics) {
                        //此处可以和蓝牙设备的硬件工程师交流 哪个特征值是对应的什么效果。 然后通过调用
                        if (characteristic.getUuid().equals("00000")) {//(此处我就瞎写一个) 通过UUID来获取硬件工程师告诉你的特征
                            characteristic.setValue(new byte[]{0x05});//(这个也是我瞎写的  需要蓝牙硬件工程师告诉你)
                            //调用了这个setValue()方法写入对应的数据,就能调用蓝牙设备的该特性了。
                        }


                        if (characteristic.getUuid().equals("11111")) {//(此处我就瞎写一个) 获取设备控制App的命令

                            //调用此方法获取设备的通知
                            characteristic.notify();//(这个也是我瞎写的)
                        }
                        
    					if (characteristic.getUuid().equals("22222")) {//(此处我就瞎写一个) 获取设备的电量

                            //调用此方法获取设备的通知 读取到时会回调
                            gatt.readCharacteristic(characteristic);
                        }
                    }
                }
            }
        }
    };
}

All in all, the write is called when the App actively contacts the device, the notification is called when the device actively contacts the App, and the read method is used when the App may obtain device information for a long time. (Many of these depend on the documentation information of the device)

Guess you like

Origin blog.csdn.net/qq77485042/article/details/109312987