android蓝牙BLE的开发:

1、最新的api是使用  bluetoothLeScanner.startScan

废弃了  adapter.startLeScan

2、顺序


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.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import static android.bluetooth.BluetoothDevice.TRANSPORT_LE;

public class BlueActivity extends AppCompatActivity {

    private ArrayList<String> data = null;
    private ListView listView = null;
    private ArrayAdapter adapter = null;

    private Button button;
    private BluetoothManager bluetoothManager;
    private BluetoothAdapter bluetoothAdapter;//app可以使用蓝牙适配器bluetoothAdapter与蓝牙硬件交互
    private BluetoothLeScanner bluetoothLeScanner;

    //先定几个服务类型的UUID
    /*
     * 服务    TYPE_SERVICE, "000019D0-0000-1000-8000-00805f9b34fb"
      */
    public static UUID TYPE_SERVICE = UUID.fromString("000019D0-0000-1000-8000-00805f9b34fb");
    /* Mandatory Current Time Information Characteristic
    *  读
     *  TYPE_CHARACTERISTIC, "00002E00-0000-1000-8000-00805f9b34fb"
    * */
    public static UUID TYPE_CHARACTERISTIC_READ = UUID.fromString("00002E00-0000-1000-8000-00805f9b34fb");
    /*
     * 写
      * TYPE_CHARACTERISTIC, "00002E01-0000-1000-8000-00805f9b34fb"
      * */
    public static UUID TYPE_CHARACTERISTIC_WRITE = UUID.fromString("00002E01-0000-1000-8000-00805f9b34fb");


    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ble);

        // 获得数据
        this.data = new ArrayList<>();
        // 初始化控件
        this.initView();
    }

    private void initView() {
        // 获得button
        this.button = findViewById(R.id.search);
        this.button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 扫描蓝牙
                scanBle();
            }
        });

        // 初始化ListView
        this.adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, this.data);
        this.listView = findViewById(R.id.lv);
        this.listView.setAdapter(adapter);
    }

    BluetoothGatt mBluetoothGatt;
    // 蓝牙扫描回调
    private ScanCallback newBtsc = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            BluetoothDevice device = result.getDevice();
            // 更新数据
            data.add(device.getAddress() + "--" + device.getName());
            adapter.notifyDataSetChanged();
            // BLE中心设备连接外围设备的数量有限(大概2~7个),在建立新连接之前必须释放旧连接资源,否则容易出现连接错误133
//            closeConn();

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                mBluetoothGatt = device.connectGatt(BlueActivity.this, true, bluetoothGattCallback,TRANSPORT_LE);
            }else {
                mBluetoothGatt = device.connectGatt(BlueActivity.this, true, bluetoothGattCallback);
            }
            Log.e("ble:", device.getAddress() + "--" + device.getName());

        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            super.onBatchScanResults(results);
        }

        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
        }
    };

    private void closeConn() {
        if (mBluetoothGatt != null) {
            mBluetoothGatt.disconnect();
            mBluetoothGatt.close();
        }
    }

    // 扫描蓝牙
    private void scanBle() {
        // 初始化蓝牙适配器
        bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        if (bluetoothManager == null) {
            return;
        }
        bluetoothAdapter = bluetoothManager.getAdapter();

        // 打开蓝牙
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            Intent enable = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enable, 1);
        } else {
            bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
            bluetoothLeScanner.startScan(newBtsc);
            // 设置扫描时间
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    bluetoothLeScanner.stopScan(newBtsc);
                }
            }, 10000);
        }
    }

    private String TAG = "tag";

    BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            String intentAction;
            Log.i(TAG, "newState=="+newState);
            if (newState == BluetoothProfile.STATE_CONNECTED) {
//                intentAction = ACTION_GATT_CONNECTED;
//                broadcastUpdate(intentAction);
                Log.i(TAG, "Connected to GATT server.");
                // Attempts to discover services after successful connection.
                //链接成功,开始搜索服务
                Log.i(TAG, "Attempting to start service discovery:" + gatt.discoverServices());

//                writeandreadData(gatt);

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
//                intentAction = ACTION_GATT_DISCONNECTED;
                Log.i(TAG, "Disconnected from GATT server.");
//                broadcastUpdate(intentAction);
            } else if (newState == BluetoothProfile.STATE_CONNECTING) {
//                intentAction = ACTION_GATT_CONNECTING;
                Log.i(TAG, "connecting from GATT server.");
//                broadcastUpdate(intentAction);
            } else {
//                intentAction = ACTION_GATT_DISCONNECTING;
                Log.i(TAG, "Disconnecting from GATT server.");
//                broadcastUpdate(intentAction);
            }
        }


        //发现设备,(真正建立连接)
        // 直到这里才是真正建立了可通信的连接
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            Log.i(TAG, String.format("onServicesDiscovered:%s,%s,%s", gatt.getDevice().getName(), gatt.getDevice().getAddress(), status));
            if (status == BluetoothGatt.GATT_SUCCESS) { //BLE服务发现成功
                // 遍历获取BLE服务Services/Characteristics/Descriptors的全部UUID
                for (BluetoothGattService service : gatt.getServices()) {
                    StringBuilder allUUIDs = new StringBuilder("UUIDs={\nS=" + service.getUuid().toString());
                    for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
                        allUUIDs.append(",\nC=").append(characteristic.getUuid());
                        for (BluetoothGattDescriptor descriptor : characteristic.getDescriptors())
                            allUUIDs.append(",\nD=").append(descriptor.getUuid());
                    }
                    allUUIDs.append("}");
                    Log.i(TAG, "onServicesDiscovered:" + allUUIDs.toString());
                }
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            UUID uuid = characteristic.getUuid();
            String valueStr = new String(characteristic.getValue());
            Log.i(TAG, String.format("onCharacteristicRead:%s,%s,%s,%s,%s", gatt.getDevice().getName(), gatt.getDevice().getAddress(), uuid, valueStr, status));
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            UUID uuid = characteristic.getUuid();
            String valueStr = new String(characteristic.getValue());
            Log.i(TAG, String.format("onCharacteristicWrite:%s,%s,%s,%s,%s", gatt.getDevice().getName(), gatt.getDevice().getAddress(), uuid, valueStr, status));
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            UUID uuid = characteristic.getUuid();
            String valueStr = new String(characteristic.getValue());
            Log.i(TAG, String.format("onCharacteristicChanged:%s,%s,%s,%s", gatt.getDevice().getName(), gatt.getDevice().getAddress(), uuid, valueStr));
        }

        @Override
        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            UUID uuid = descriptor.getUuid();
            String valueStr = Arrays.toString(descriptor.getValue());
            Log.i(TAG, String.format("onDescriptorRead:%s,%s,%s,%s,%s", gatt.getDevice().getName(), gatt.getDevice().getAddress(), uuid, valueStr, status));
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            UUID uuid = descriptor.getUuid();
            String valueStr = Arrays.toString(descriptor.getValue());
            Log.i(TAG, String.format("onDescriptorWrite:%s,%s,%s,%s,%s", gatt.getDevice().getName(), gatt.getDevice().getAddress(), uuid, valueStr, status));
        }

    };

    BluetoothGattCharacteristic characteristic;

    private void writeandreadData(BluetoothGatt bluetoothGatt) {
        BluetoothGattService service = bluetoothGatt.getService(TYPE_SERVICE);
        if (service != null) {
            characteristic = service.getCharacteristic(TYPE_CHARACTERISTIC_READ);
            if (characteristic != null) {
                //设置characteristic的通知,触发bluetoothGatt.onCharacteristicWrite()事件。
                bluetoothGatt.setCharacteristicNotification(characteristic, true);

                characteristic.setValue("0x06");
                bluetoothGatt.writeCharacteristic(characteristic);
            }
        }
    }


}

 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐