android關於藍牙BLE的開發

 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);
            }
        }
    }


}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章