美文网首页
蓝牙笔记

蓝牙笔记

作者: 金卡戴珊ugly | 来源:发表于2019-03-29 20:07 被阅读0次

    ##蓝牙

    ```

    @SuppressLint("NewApi")

    public class BluetoothLeServiceextends Service {

    private final static StringTAG = BluetoothLeService.class.getSimpleName();

    private BluetoothManagermBluetoothManager;

    private BluetoothAdaptermBluetoothAdapter;

    private StringmBluetoothDeviceAddress;

    private BluetoothGattmBluetoothGatt;

    private int mConnectionState =STATE_DISCONNECTED;

    private static final int STATE_DISCONNECTED =0;

    private static final int STATE_CONNECTING =1;

    private static final int STATE_CONNECTED =2;

    public final static StringACTION_GATT_CONNECTED ="com.example.bluetooth.le.ACTION_GATT_CONNECTED";

    public final static StringACTION_GATT_DISCONNECTED ="com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";

    public final static StringACTION_GATT_ERR_DISCONNECTED ="com.example.bluetooth.le.ACTION_GATT_ERR_DISCONNECTED";

    public final static StringACTION_SCAN_TIMEOUT ="com.example.bluetooth.le.ACTION_GATT_SCAN_TIMEOUT";

    public final static StringACTION_SCAN_NEW_DEVICE ="com.example.bluetooth.le.ACTION_GATT_SCAN_NEW_DEVICE";

    public final static StringACTION_GATT_SERVICES_DISCOVERED ="com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";

    public final static StringACTION_DATA_AVAILABLE ="com.example.bluetooth.le.ACTION_DATA_AVAILABLE";

    public final static StringEXTRA_DATA ="com.example.bluetooth.le.EXTRA_DATA";

    public static final UUIDCLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID = UUID

    .fromString("00002902-0000-1000-8000-00805f9b34fb");

    /* public final static UUID UUID_HEART_RATE_MEASUREMENT = UUID

    .fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);*/

    // Implements callback methods for GATT events that the app cares about. For

    // example,

    // connection change and services discovered.

        public static BluetoothLeServiceME =null;

    public boolean isScanning =false;

    public static final int AUTO_STOP_SCAN_MSG_WHAT =0X15011501;

    protected static final int CUSTOM_CONNECT_TIMEOUT_MSG_WHAT =0X031801;

    private ObjectnewScanCallback =null;

    protected HashSetscanDeviceMacAddress =new HashSet<>();

    @Override

        public void onCreate() {

    ME =this;

    LoggerUtils.i("onCreate---------------------.");

    initialize();

    super.onCreate();

    }

    @Override

        public void onDestroy() {

    ME =null;

    super.onDestroy();

    }

    @SuppressWarnings("deprecation")

    public synchronized void scan(boolean flag) {

    if (flag ==isScanning) {

    return;

    }

    isScanning = flag;

    if (flag) {

    scanDeviceMacAddress.clear();

    Message msg = DelayHandler.getInstance().obtainMessage();

    msg.what =AUTO_STOP_SCAN_MSG_WHAT;

    msg.obj =new Runnable() {

    @Override

                    public void run() {

    isScanning =false;

    stopScanBLEDevice();

    broadcastUpdate(ACTION_SCAN_TIMEOUT,"");

    }

    };

    DelayHandler.getInstance().sendMessageDelayed(msg, PublicConstant.SCAN_BLE_TIME);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

    if (newScanCallback ==null) {

    newScanCallback =new ScanCallback() {

    @Override

                            public void onScanResult(int callbackType, ScanResult result) {

    LoggerUtils.i("android5.0及以上搜索结果" + result.toString());

    handleSearchResult(result.getDevice(), result.getRssi(), result.getScanRecord().getBytes());

    }

    @Override

                            public void onBatchScanResults(List results) {

    LoggerUtils.i("外围设备->onBatchScanResults:" + results.toString());

    }

    @Override

                            public void onScanFailed(int errorCode) {

    LoggerUtils.i("外围设备->onScanFailed:" + errorCode);

    }

    };

    }

    List list =new ArrayList<>();

    ScanFilter.Builder builder =new ScanFilter.Builder();

    builder.setServiceUuid(ParcelUuid.fromString("00000001-0000-1000-8000-00805f9b34fb"));

    list.add(builder.build());

    ScanSettings.Builder builderSS =new ScanSettings.Builder();

    builderSS.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);

    if (mBluetoothAdapter !=null &&newScanCallback !=null) {

    try {

    mBluetoothAdapter.getBluetoothLeScanner().startScan(null, builderSS.build(), (ScanCallback)newScanCallback);

    }catch (Exception e) {

    e.printStackTrace();

    }

    }

    }else {

    if (mBluetoothAdapter !=null &&mLeScanCallback !=null) {

    try {

    mBluetoothAdapter.startLeScan(mLeScanCallback);

    }catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    LoggerUtils.i("扫描设备...");

    }else {

    DelayHandler.getInstance().removeMessages(AUTO_STOP_SCAN_MSG_WHAT);

    stopScanBLEDevice();

    LoggerUtils.i("停止扫描...");

    }

    }

    @SuppressWarnings("deprecation")

    private void stopScanBLEDevice() {

    LoggerUtils.i("停止扫描------------------------------------");

    if (mBluetoothAdapter ==null)return;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

    if (newScanCallback !=null) {

    try {

    mBluetoothAdapter.getBluetoothLeScanner().stopScan((ScanCallback)newScanCallback);

    }catch (Exception e) {

    e.printStackTrace();

    }

    }

    }else {

    if (mLeScanCallback !=null) {

    try {

    mBluetoothAdapter.stopLeScan(mLeScanCallback);

    }catch (Exception e) {

    e.printStackTrace();

    }

    }

    }

    }

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

    @Override

            public void onLeScan(BluetoothDevice device,int rssi,byte[] scanRecord) {

    LoggerUtils.i("android5.0以下搜索结果:" + device.getName()+" mac:"+device.getAddress());

    handleSearchResult(device, rssi, scanRecord);

    }

    };

    private void handleSearchResult(BluetoothDevice device,int rssi,byte[] scanRecord) {

    String deviceName = device.getName() ==null ?"" : device.getName();

    if (!scanDeviceMacAddress.contains(device.getAddress())) {

    scanDeviceMacAddress.add(device.getAddress());

    broadcastUpdate(ACTION_SCAN_NEW_DEVICE, device.getAddress());

    }

    }

    private void searchService(final BluetoothGatt gatt) {

    new Thread() {

    public void run() {

    gatt.discoverServices();

    }

    }.start();

    }

    private final BluetoothGattCallbackmGattCallback =new BluetoothGattCallback() {

    @Override

            public void onConnectionStateChange(BluetoothGatt gatt,int status,

    int newState) {

    String intentAction;

    if (newState == BluetoothProfile.STATE_CONNECTED) {

    mBluetoothGatt = gatt;

    intentAction =ACTION_GATT_CONNECTED;

    mConnectionState =STATE_CONNECTED;

    broadcastUpdate(intentAction, gatt.getDevice().getAddress());

    LoggerUtils.i("Connected to GATT server.");

    // Attempts to discover services after successful connection.

    //          LoggerUtils.i( "Attempting to start service discovery:"

    //                + mBluetoothGatt.discoverServices());

                    Util.threadSleep(200);

    searchService(gatt);

    }else if (newState == BluetoothProfile.STATE_DISCONNECTED) {

    intentAction =ACTION_GATT_DISCONNECTED;

    mConnectionState =STATE_DISCONNECTED;

    LoggerUtils.i("Disconnected from GATT server.");

    broadcastUpdate(intentAction, gatt.getDevice().getAddress());

    gatt.close();

    mBluetoothGatt =null;

    scanDeviceMacAddress.remove(gatt.getDevice().getAddress());

    }else {

    broadcastUpdate(ACTION_GATT_ERR_DISCONNECTED, gatt.getDevice().getAddress());

    }

    }

    @Override

            public void onServicesDiscovered(BluetoothGatt gatt,int status) {

    LoggerUtils.i("onServicesDiscovered received: " + status);

    if (status == BluetoothGatt.GATT_SUCCESS) {

    broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED, gatt.getDevice().getAddress());

    }

    }

    @Override

            public void onCharacteristicRead(BluetoothGatt gatt,

    BluetoothGattCharacteristic characteristic,int status) {

    LoggerUtils.i("onCharacteristicRead");

    if (status == BluetoothGatt.GATT_SUCCESS) {

    broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic, gatt.getDevice().getAddress());

    }

    }

    @Override

            public void onDescriptorWrite(BluetoothGatt gatt,

    BluetoothGattDescriptor descriptor,int status) {

    LoggerUtils.i("onDescriptorWriteonDescriptorWrite = " + status

    +", descriptor =" + descriptor.getUuid().toString());

    }

    @Override

            public void onCharacteristicChanged(BluetoothGatt gatt,

    BluetoothGattCharacteristic characteristic) {

    broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic, gatt.getDevice().getAddress());

    if (characteristic.getValue() !=null) {

    //String test = characteristic.getStringValue(0);

                    LoggerUtils.i(characteristic.getStringValue(0));

    }

    LoggerUtils.i("--------onCharacteristicChanged-----");

    }

    @Override

            public void onReadRemoteRssi(BluetoothGatt gatt,int rssi,int status) {

    LoggerUtils.i("rssi = " + rssi);

    }

    public void onCharacteristicWrite(BluetoothGatt gatt,

    BluetoothGattCharacteristic characteristic,int status) {

    LoggerUtils.i("--------write success----- status:" + status);

    }

    ;

    };

    private void broadcastUpdate(final String action) {

    final Intent intent =new Intent(action);

    sendBroadcast(intent);

    }

    private void broadcastUpdate(final String action, String address) {

    LoggerUtils.i("-----------------广播action:" + action);

    final Intent intent =new Intent(action);

    intent.putExtra("address", address);

    sendBroadcast(intent);

    }

    private void broadcastUpdate(final String action,

    final BluetoothGattCharacteristic characteristic) {

    final Intent intent =new Intent(action);

    // This is special handling for the Heart Rate Measurement profile. Data

    // parsing is

    // carried out as per profile specifications:

    // http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml

    /*if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {

    int flag = characteristic.getProperties();

    int format = -1;

    if ((flag & 0x01) != 0) {

    format = BluetoothGattCharacteristic.FORMAT_UINT16;

    LoggerUtils.i( "Heart rate format UINT16.");

    } else {

    format = BluetoothGattCharacteristic.FORMAT_UINT8;

    LoggerUtils.i( "Heart rate format UINT8.");

    }

    final int heartRate = characteristic.getIntValue(format, 1);

    LoggerUtils.i("Received heart rate: %d" + heartRate);

    LoggerUtils.i( String.format("Received heart rate: %d", heartRate));

    intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));

    } else {*/

    // For all other profiles, writes the data formatted in HEX.

            final byte[] data = characteristic.getValue();

    if (data !=null && data.length >0) {

    final StringBuilder stringBuilder =new StringBuilder(

    data.length);

    for (byte byteChar : data)

    stringBuilder.append(String.format("%02X", byteChar));

    //String test = stringBuilder.toString();

                LoggerUtils.i("ppp" +new String(data) +"\n"

                        + stringBuilder.toString());

    intent.putExtra(EXTRA_DATA, stringBuilder.toString());

    }

    //}

            sendBroadcast(intent);

    }

    private void broadcastUpdate(final String action,

    final BluetoothGattCharacteristic characteristic, String address) {

    final Intent intent =new Intent(action);

    // This is special handling for the Heart Rate Measurement profile. Data

    // parsing is

    // carried out as per profile specifications:

    // http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml

    /*if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {

    int flag = characteristic.getProperties();

    int format = -1;

    if ((flag & 0x01) != 0) {

    format = BluetoothGattCharacteristic.FORMAT_UINT16;

    LoggerUtils.i( "Heart rate format UINT16.");

    } else {

    format = BluetoothGattCharacteristic.FORMAT_UINT8;

    LoggerUtils.i( "Heart rate format UINT8.");

    }

    final int heartRate = characteristic.getIntValue(format, 1);

    LoggerUtils.i("Received heart rate: %d" + heartRate);

    LoggerUtils.i( String.format("Received heart rate: %d", heartRate));

    intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));

    } else {*/

    // For all other profiles, writes the data formatted in HEX.

            final byte[] data = characteristic.getValue();

    if (data !=null && data.length >0) {

    final StringBuilder stringBuilder =new StringBuilder(

    data.length);

    for (byte byteChar : data)

    stringBuilder.append(String.format("%02X", byteChar));

    //String test = stringBuilder.toString();

                LoggerUtils.i("ppp" +new String(data) +"\n"

                        + stringBuilder.toString());

    intent.putExtra(EXTRA_DATA, stringBuilder.toString());

    }

    //}

            intent.putExtra("address", address);

    sendBroadcast(intent);

    }

    public class LocalBinderextends Binder {

    public BluetoothLeService getService() {

    return BluetoothLeService.this;

    }

    }

    @Override

        public IBinder onBind(Intent intent) {

    return mBinder;

    }

    @Override

        public boolean onUnbind(Intent intent) {

    // After using a given device, you should make sure that

    // BluetoothGatt.close() is called

    // such that resources are cleaned up properly. In this particular

    // example, close() is

    // invoked when the UI is disconnected from the Service.

            close();

    return super.onUnbind(intent);

    }

    private final IBindermBinder =new LocalBinder();

    /**

    * Initializes a reference to the local Bluetooth adapter.

    *

        * @return Return true if the initialization is successful.

    */

        public boolean initialize() {

    // For API level 18 and above, get a reference to BluetoothAdapter

    // through

    // BluetoothManager.

            if (mBluetoothManager ==null) {

    mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

    if (mBluetoothManager ==null) {

    LoggerUtils.i("Unable to initialize BluetoothManager.");

    return false;

    }

    }

    mBluetoothAdapter =mBluetoothManager.getAdapter();

    if (mBluetoothAdapter ==null) {

    LoggerUtils.i("Unable to obtain a BluetoothAdapter.");

    return false;

    }

    return true;

    }

    /**

    * Connects to the GATT server hosted on the Bluetooth LE device.

    *

        * @param address The device address of the destination device.

        * @return Return true if the connection is initiated successfully. The

    * connection result is reported asynchronously through the

        * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}

    * callback.

    */

        public boolean connect(final String address) {

    if (mBluetoothAdapter ==null || address ==null) {

    LoggerUtils.i(

    "BluetoothAdapter not initialized or unspecified address.");

    return false;

    }

    final BluetoothDevice device =mBluetoothAdapter.getRemoteDevice(address);

    if (device ==null) {

    LoggerUtils.i("Device not found.  Unable to connect.");

    return false;

    }

    int connectionState =mBluetoothManager.getConnectionState(device, BluetoothProfile.GATT);

    if (connectionState == BluetoothProfile.STATE_CONNECTED) {

    LoggerUtils.i("===================已连接上");

    broadcastUpdate(ACTION_GATT_CONNECTED, address);

    return true;

    }

    // Previously connected device. Try to reconnect. (��ǰ���ӵ��豸�� ������������)

            if (mBluetoothDeviceAddress !=null

                    && address.equals(mBluetoothDeviceAddress)

    &&mBluetoothGatt !=null) {

    LoggerUtils.i(

    "Trying to use an existing mBluetoothGatt for connection.");

    if (mBluetoothGatt.connect()) {

    mConnectionState =STATE_CONNECTING;

    return true;

    }else {

    return false;

    }

    }

    // We want to directly connect to the device, so we are setting the

    // autoConnect

    // parameter to false.

    //    mBluetoothGatt = device.connectGatt(this, false, mGattCallback);

            device.connectGatt(this,false,mGattCallback);

    LoggerUtils.i("Trying to create a new connection.");

    mBluetoothDeviceAddress = address;

    mConnectionState =STATE_CONNECTING;

    return true;

    }

    /**

    * Disconnects an existing connection or cancel a pending connection. The

    * disconnection result is reported asynchronously through the

        * {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}

    * callback.

    */

        public void disconnect() {

    if (mBluetoothAdapter ==null ||mBluetoothGatt ==null) {

    LoggerUtils.i("BluetoothAdapter not initialized");

    return;

    }

    int connectionState =mBluetoothManager.getConnectionState(mBluetoothGatt.getDevice(), BluetoothProfile.GATT);

    if (connectionState == BluetoothProfile.STATE_DISCONNECTED) {

    LoggerUtils.i("===================已断开");

    broadcastUpdate(ACTION_GATT_DISCONNECTED,mBluetoothGatt.getDevice().getAddress());

    return;

    }

    if (connectionState == BluetoothProfile.STATE_DISCONNECTING) {

    LoggerUtils.i("===================正在断开");

    return;

    }

    refreshGatt(mBluetoothGatt);

    mBluetoothGatt.disconnect();

    }

    /**

    * After using a given BLE device, the app must call this method to ensure

    * resources are released properly.

    */

        public void close() {

    if (mBluetoothGatt ==null) {

    return;

    }

    LoggerUtils.i("gatt--close");

    mBluetoothGatt.close();

    mBluetoothGatt =null;

    }

    private void refreshGatt(BluetoothGatt gatt) {

    try {

    Method method = gatt.getClass().getDeclaredMethod("refresh");

    method.invoke(gatt);

    }catch (Exception e) {

    e.printStackTrace();

    }

    }

    public boolean wirteCharacteristic(BluetoothGattCharacteristic characteristic) {

    if (mBluetoothAdapter ==null ||mBluetoothGatt ==null || characteristic ==null) {

    LoggerUtils.i("BluetoothAdapter not initialized");

    return false;

    }

    return mBluetoothGatt.writeCharacteristic(characteristic);

    }

    /**

        * Request a read on a given {@code BluetoothGattCharacteristic}. The read

    * result is reported asynchronously through the

        * {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)}

    * callback.

    *

        * @param characteristic The characteristic to read from.

    */

        public void readCharacteristic(BluetoothGattCharacteristic characteristic) {

    if (mBluetoothAdapter ==null ||mBluetoothGatt ==null) {

    LoggerUtils.i("BluetoothAdapter not initialized");

    return;

    }

    mBluetoothGatt.readCharacteristic(characteristic);

    }

    /**

    * Enables or disables notification on a give characteristic.

    *

        * @param characteristic Characteristic to act on.

        * @param enabled        If true, enable notification. False otherwise.

    */

        public void setCharacteristicNotification(

    BluetoothGattCharacteristic characteristic,boolean enabled) {

    if (mBluetoothAdapter ==null ||mBluetoothGatt ==null) {

    LoggerUtils.i("BluetoothAdapter not initialized");

    return;

    }

    if (enabled ==true) {

    LoggerUtils.i("Enable Notification");

    mBluetoothGatt.setCharacteristicNotification(characteristic,true);

    BluetoothGattDescriptor descriptor = characteristic

    .getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID);

    descriptor

    .setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);

    mBluetoothGatt.writeDescriptor(descriptor);

    }else {

    LoggerUtils.i("Disable Notification");

    mBluetoothGatt.setCharacteristicNotification(characteristic,false);

    BluetoothGattDescriptor descriptor = characteristic

    .getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID);

    descriptor

    .setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);

    mBluetoothGatt.writeDescriptor(descriptor);

    }

    }

    /**

    * Retrieves a list of supported GATT services on the connected device. This

        * should be invoked only after {@code BluetoothGatt#discoverServices()}

    * completes successfully.

    *

        * @return A {@code List} of supported services.

    */

        public List getSupportedGattServices() {

    if (mBluetoothGatt ==null)

    return null;

    return mBluetoothGatt.getServices();

    }

    /**

    * Read the RSSI for a connected remote device.

    */

        public boolean getRssiVal() {

    if (mBluetoothGatt ==null)

    return false;

    return mBluetoothGatt.readRemoteRssi();

    }

    public int getConnectionState() {

    return mConnectionState;

    }

    }

    ```

    相关文章

      网友评论

          本文标题:蓝牙笔记

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