【问题标题】:How to scan and connect ble devices when app is in background in android?当应用程序在Android后台时如何扫描和连接BLE设备?
【发布时间】:2018-04-05 12:25:44
【问题描述】:

我开发了一个 android 应用程序来扫描 ble 设备,并在应用程序处于用户交互时完成了 gatt 特性的读取和写入。我想保持与特定 ble 设备的连接,并希望在应用程序处于前台和后台时读写 gatt 特性。这是我的 BluetoothLeService 类。

public class BluetoothLeService extends Service 
{
    public static final String ACTION_DATA_AVAILABLE = "com.example.tracker.service.ACTION_DATA_AVAILABLE";
    public static final String ACTION_GATT_CONNECTED = "com.example.tracker.service.ACTION_GATT_CONNECTED";
    public static final String ACTION_GATT_DISCONNECTED = "com.example.tracker.service.ACTION_GATT_DISCONNECTED";
    public static final String ACTION_GATT_RSSI_UPDATE = "com.example.tracker.service.ACTION_GATT_RSSI_UPDATE";
    public static final String ACTION_GATT_SERVICES_DISCOVERED = "com.example.tracker.service.ACTION_GATT_SERVICES_DISCOVERED";
    public static final String ACTION_GATT_WRITE_FAILED = "com.example.tracker.service.ACTION_GATT_WRITE_FAILED";
    protected static final UUID CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
    public static final String CHARACTERISTIC_UUID = "com.example.tracker.service.CHARACTERISTIC_UUID";
    public static final String EXTRA_DATA = "com.example.tracker.service.EXTRA_DATA";
    public static final String SIGNAL = "SIGNAL";
    private static final String TAG = BluetoothLeService.class.getSimpleName();
    private final IBinder mBinder = new LocalBinder();
    private BluetoothAdapter mBluetoothAdapter;
    private String mBluetoothDeviceAddress;
    private BluetoothGatt mBluetoothGatt;
    private BluetoothManager mBluetoothManager;
    private BluetoothGattCharacteristic mFocusedCharacteristic;

    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (newState == 2) {
                BluetoothLeService.this.broadcastUpdate(BluetoothLeService.ACTION_GATT_CONNECTED);
                Log.i(BluetoothLeService.TAG, "Connected to GATT server.");
                Log.i("MyActivity", "Connected to GATT server.");
                Log.i("MyActivity", "Attempting to start service discovery:" + BluetoothLeService.this.mBluetoothGatt.discoverServices());
            } else if (newState == 0) {
                String intentAction = BluetoothLeService.ACTION_GATT_DISCONNECTED;
                Log.i("MyActivity", "Disconnected from GATT server.");
                BluetoothLeService.this.broadcastUpdate(intentAction);
            }
        }

        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == 0) {
                BluetoothLeService.this.broadcastUpdate(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
            } else {
                Log.w("MyActivity", "onServicesDiscovered received: " + status);
            }
        }

        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            if (status == 0) {
                BluetoothLeService.this.broadcastUpdate(BluetoothLeService.ACTION_DATA_AVAILABLE, characteristic);
                Log.i("MyActivity", "Characteristic flags " + characteristic.getProperties());
                BluetoothLeService.this.mFocusedCharacteristic = characteristic;
            }
        }

        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            if (status == 0) {
                BluetoothLeService.this.broadcastUpdate(BluetoothLeService.ACTION_DATA_AVAILABLE, characteristic);
                if ((characteristic.getProperties() & 2) > 0) {
                    BluetoothLeService.this.readCharacteristic();
                    Log.i("MyActivity", "Characteristic permits read");
                }
                Log.i("MyActivity", "Characteristic was written");
                return;
            }
            Log.i("MyActivity", "Failed to write characteristic");
            BluetoothLeService.this.broadcastUpdate(BluetoothLeService.ACTION_GATT_WRITE_FAILED);
        }

        public void onReadRemoteRssi(BluetoothGatt gatt, int Rssi, int status) {
            if (status == 0) {
                BluetoothLeService.this.broadcastUpdate(BluetoothLeService.ACTION_GATT_RSSI_UPDATE, Rssi);
            }
        }

        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            Log.i("MyActivity", "Characteristic has changed");
            BluetoothLeService.this.broadcastUpdate(BluetoothLeService.ACTION_DATA_AVAILABLE, characteristic);
        }
    };

    public class LocalBinder extends Binder {
        public BluetoothLeService getService() {
            return BluetoothLeService.this;
        }
    }

    private void broadcastUpdate(String action) {
        sendBroadcast(new Intent(action));
    }

    private void broadcastUpdate(String action, int Rssi) {
        Intent intent = new Intent(action);
        intent.putExtra(EXTRA_DATA, Rssi);
        sendBroadcast(intent);
    }

    private void broadcastUpdate(String action, BluetoothGattCharacteristic characteristic) {
        Intent intent = new Intent(action);
        byte[] data = characteristic.getValue();
        if (data != null && data.length > 0) {
            StringBuilder stringBuilder = new StringBuilder(data.length);
            int length = data.length;
            for (int i = 0; i < length; i++) {
                stringBuilder.append(String.format("%02X ", new Object[]{Byte.valueOf(data[i])}));
            }
            intent.putExtra(EXTRA_DATA, new StringBuilder(String.valueOf(new String(data))).append("    [ ").append(stringBuilder.toString()).toString());
            intent.putExtra(CHARACTERISTIC_UUID, characteristic.getUuid().toString());
        }
        sendBroadcast(intent);
    }

    public IBinder onBind(Intent intent) {



        return this.mBinder;
    }

    public boolean onUnbind(Intent intent) {
        close();
        return super.onUnbind(intent);
    }

    public boolean initialize() {
        if (this.mBluetoothManager == null) {
            this.mBluetoothManager = (BluetoothManager) getSystemService("bluetooth");
            if (this.mBluetoothManager == null) {
                Log.e(TAG, "Unable to initialize BluetoothManager.");
                return false;
            }
        }
        this.mBluetoothAdapter = this.mBluetoothManager.getAdapter();
        if (this.mBluetoothAdapter != null) {
            return true;
        }
        Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
        return false;
    }

    public boolean connect(String address) {
        if (this.mBluetoothAdapter == null || address == null) {
            Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
            return false;
        } else if (this.mBluetoothDeviceAddress == null || !address.equals(this.mBluetoothDeviceAddress) || this.mBluetoothGatt == null) {
            BluetoothDevice device = this.mBluetoothAdapter.getRemoteDevice(address);
            if (device == null) {
                Log.w(TAG, "LocalDevice not found.  Unable to connect.");
                return false;
            }
            this.mBluetoothGatt = device.connectGatt(this, false, this.mGattCallback);
            Log.d(TAG, "Trying to create a new connection.");
            this.mBluetoothDeviceAddress = address;
            return true;
        } else {
            Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
            if (this.mBluetoothGatt.connect()) {
                return true;
            }
            return false;
        }
    }

    public void disconnect() {
        if (this.mBluetoothAdapter == null || this.mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
        } else {
            this.mBluetoothGatt.disconnect();
        }
    }

    public void readRemoteRssi() {
        if (this.mBluetoothAdapter == null || this.mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
        } else {
            this.mBluetoothGatt.readRemoteRssi();
        }
    }

    public BluetoothGattCharacteristic CurrentCharacteristic() {
        return this.mFocusedCharacteristic;
    }

    public String getCurrentCharacteristicUuid() {
        return this.mFocusedCharacteristic.getUuid().toString();
    }

    public void writeCharacteristic(byte[] c) {
        mFocusedCharacteristic.setValue(c);

        if (mBluetoothGatt!=null && mFocusedCharacteristic!=null){
            mBluetoothGatt.writeCharacteristic(mFocusedCharacteristic);
        }

    }

    public void readCharacteristic() {
        Log.i("MyActivity", "Read Characteristic");
        this.mBluetoothGatt.readCharacteristic(this.mFocusedCharacteristic);
    }

    public void notifyCharacteristic() {
        Log.i("MyActivity", "Notify Characteristic");
        setCharacteristicNotification(this.mFocusedCharacteristic, true);
    }

    public void setCurrentCharacteristic(BluetoothGattCharacteristic characteristic) {
        this.mFocusedCharacteristic = characteristic;
    }

    public void close() {
        if (this.mBluetoothGatt != null) {
            this.mBluetoothGatt.close();
            this.mBluetoothGatt = null;
        }
    }

    public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
        if (this.mBluetoothAdapter == null || this.mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
        } else {
            this.mBluetoothGatt.readCharacteristic(characteristic);
        }
    }

    public boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enable) {
        Log.i("MyActivity", "setCharacteristicNotification");
        this.mBluetoothGatt.setCharacteristicNotification(characteristic, enable);
        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID);
        descriptor.setValue(enable ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : new byte[2]);
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
         SystemClock.sleep(200);
        return this.mBluetoothGatt.writeDescriptor(descriptor);
    }

    public List<BluetoothGattService> getSupportedGattServices() {
        if (this.mBluetoothGatt == null) {
            return null;
        }
        return this.mBluetoothGatt.getServices();
    }

}

【问题讨论】:

  • 欢迎来到 Stack Overflow! stackoverflow.com/help/how-to-ask 可能会帮助您入门。
  • 创建AlarmManager,它将在一段时间后继续调用服务,并且扫描和连接应该在服务中。
  • 嗨 j.prashant,你能分享BluetoothLeService class
  • @NirmalPrajapat 好的.. 我会分享
  • 好的。 . .m 等待你的帖子:)

标签: android bluetooth bluetooth-lowenergy bluetooth-gatt


【解决方案1】:

无论您的应用是在前台还是后台,API 都是相同的。您唯一需要做的就是确保系统不会在后台关闭应用程序。为此,只需在您的应用进程中的某处运行前台服务即可。

【讨论】:

    【解决方案2】:

    当应用程序在android后台时,使用服务扫描和连接BLE设备。

    package com.example.tracker.service;
    
    import android.app.Service;
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothDevice;
    import android.bluetooth.BluetoothGatt;
    import android.bluetooth.BluetoothGattCharacteristic;
    import android.bluetooth.BluetoothGattService;
    import android.bluetooth.BluetoothManager;
    import android.bluetooth.le.BluetoothLeScanner;
    import android.bluetooth.le.ScanFilter;
    import android.bluetooth.le.ScanSettings;
    import android.content.BroadcastReceiver;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.content.ServiceConnection;
    import android.content.pm.PackageManager;
    import android.net.Uri;
    import android.os.Handler;
    import android.os.IBinder;
    import android.support.annotation.Nullable;
    import android.support.v4.widget.SwipeRefreshLayout;
    import android.util.Log;
    import android.widget.Button;
    import android.widget.LinearLayout;
    import android.widget.ListView;
    import android.widget.SeekBar;
    import android.widget.Toast;
    
    import com.google.firebase.auth.FirebaseAuth;
    import com.example.tracker.R;
    import com.example.tracker.utils.SampleGattAttributes;
    import com.example.tracker.utils.SharedPreferencesUtils;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.UUID;
    
    import static com.example.tracker.constant.SharedFreferencesConstant.KEY_SP_MOBILE_NUMBER;
    
    /**
     * Created by Jprashant on 12/9/17.
     */
    
    public class BackgroundService extends Service{
    
        private int scanPeriod;
    
        Context context;
        String TAG="BackgroundService";
        private BluetoothAdapter mBluetoothAdapter;
        private boolean mScanning;
        private Handler mHandler;
        public String[] advDataTypes = new String[256];
    
        ArrayList<BluetoothDevice> bluetoothDeviceArrayList=new ArrayList<>();
        ArrayList<BluetoothDevice> bluetoothDeviceArrayListTwo=new ArrayList<>();
        private static final int REQUEST_ENABLE_BT = 1;
        // Stops scanning after 10 seconds.
        private static final long SCAN_PERIOD = 10000;
    
    
        /*Connect Ble Device*/
    
    
    
        String deviceId;
        public static String arrayDidOpnSec2;
    
        BluetoothGattService gattService4;
        public static ArrayList<BluetoothGattCharacteristic> lastCharacteristic;
    
    
        //    AlertDialog.Builder alertDialog;
        private float avgRssi = 0.0f;
        // private Dialog dialog;
        private BluetoothLeService mBluetoothLeService;
        private boolean mConnected = false;
        private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList();
    
        //service and char uuid
        private static final int TRACKER_ON_OFF = 2;
        private static final UUID TRACER_TRIPPLE_PRESS_SERVICE=UUID.fromString("edfec62e-9910-0bac-5241-d8bda6932a2f");
        private static final UUID TRACKER_TRIPPLE_PRESS_CHAR=UUID.fromString("772ae377-b3d2-4f8e-4042-5481d1e0098c");
        private static final UUID IMMEDIATE_ALERT_UUID = UUID.fromString("00001802-0000-1000-8000-00805f9b34fb");
        private static final UUID ALERT_LEVEL_UUID = UUID.fromString("00002a06-0000-1000-8000-00805f9b34fb");
    
        private Button btnSMS;
        public static String mDeviceName,mDeviceAddress,connectionStatus;
    
        /*-------------------------------------------------------------------------------*/
    
        public static final String PREFS_NAME = "PreferencesFile";
    
        public int deviceCount = 0;
    
        public String[] mData = new String[400];
        private Handler mHandler1;
    
        private ListView listItems;
    
    
        /*--------for > 21--------------*/
        private BluetoothLeScanner mLEScanner;
        private ScanSettings settings;
        private List<ScanFilter> filters;
        private BluetoothGatt mGatt;
    
    
    
    
        public BackgroundService() {
    
        }
    
        public BackgroundService(Context context) {
            this.context = context;
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
    
    //        getting systems default ringtone
    
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(getApplicationContext(),"CALL YOUR METHOD",Toast.LENGTH_LONG).show();
    
                    mHandler = new Handler();
    
                    // Use this check to determine whether BLE is supported on the device.  Then you can
                    // selectively disable BLE-related features.
                    if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
                        Toast.makeText(context, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
                    }
    
                    // Initializes a Bluetooth adapter.  For API level 18 and above, get a reference to
                    // BluetoothAdapter through BluetoothManager.
                    final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
                    mBluetoothAdapter = bluetoothManager.getAdapter();
    
                    // Checks if Bluetooth is supported on the device.
                    if (mBluetoothAdapter == null) {
                        Toast.makeText(context, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
                        return;
                    }
    
    
                    for (int i = 0; i < 256; i += REQUEST_ENABLE_BT) {
                        advDataTypes[i] = "Unknown Data Type";
                    }
                    advDataTypes[REQUEST_ENABLE_BT] = "Flags";
                    advDataTypes[2] = "Incomplete List of 16-bit Service Class UUIDs";
                    advDataTypes[3] = "Complete List of 16-bit Service Class UUIDs";
                    advDataTypes[4] = "Incomplete List of 32-bit Service Class UUIDs";
                    advDataTypes[5] = "Complete List of 32-bit Service Class UUIDs";
                    advDataTypes[6] = "Incomplete List of 128-bit Service Class UUIDs";
                    advDataTypes[7] = "Complete List of 128-bit Service Class UUIDs";
                    advDataTypes[8] = "Shortened Local Name";
                    advDataTypes[9] = "Complete Local Name";
                    advDataTypes[10] = "Tx Power Level";
                    advDataTypes[13] = "Class of LocalDevice";
                    advDataTypes[14] = "Simple Pairing Hash";
                    advDataTypes[15] = "Simple Pairing Randomizer R";
                    advDataTypes[16] = "LocalDevice ID";
                    advDataTypes[17] = "Security Manager Out of Band Flags";
                    advDataTypes[18] = "Slave Connection Interval Range";
                    advDataTypes[20] = "List of 16-bit Solicitaion UUIDs";
                    advDataTypes[21] = "List of 128-bit Solicitaion UUIDs";
                    advDataTypes[22] = "Service Data";
                    advDataTypes[23] = "Public Target Address";
                    advDataTypes[24] = "Random Target Address";
                    advDataTypes[25] = "Appearance";
                    advDataTypes[26] = "Advertising Interval";
                    advDataTypes[61] = "3D Information Data";
                    advDataTypes[255] = "Manufacturer Specific Data";
                    scanPeriod = getApplicationContext().getSharedPreferences(PREFS_NAME, 0).getInt("scan_interval", 6000);
                    scanTrackerDevices();
                }
            }, 10000);
    
    
    
    
            return START_STICKY;
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
        }
    
        public void scanTrackerDevices(){
            Log.e(TAG,"scanTrackerDevices");
    
            if (!mBluetoothAdapter.isEnabled()) {
                if (!mBluetoothAdapter.isEnabled()) {
                    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                }
            }
            scanLeDevice(true);
        }
    
    
        private void scanLeDevice(final boolean enable) {
            bluetoothDeviceArrayList.clear();
            if (enable) {
                // Stops scanning after a pre-defined scan period.
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mScanning = false;
                        mBluetoothAdapter.stopLeScan(mLeScanCallback);
    
                        int arraySize=bluetoothDeviceArrayListTwo.size();
                        Log.e(TAG,"bluetoothDeviceArrayListTwo Size in scan :"+arraySize);
    
                         for (int i=0;i<bluetoothDeviceArrayListTwo.size();i++){
                            BluetoothDevice bluetoothDevice=bluetoothDeviceArrayListTwo.get(i);
                            Log.e(TAG,"Device Name in scan :"+bluetoothDevice.getName());
                            Log.e(TAG,"Device Address in scan :"+bluetoothDevice.getAddress());
    
                             if (i==0){
                                 mBluetoothLeService.connect(bluetoothDevice.getAddress());
                             }
                            }
                    }
                }, scanPeriod);
    
                mScanning = true;
                mBluetoothAdapter.startLeScan(mLeScanCallback);
            } else {
                mScanning = false;
                mBluetoothAdapter.stopLeScan(mLeScanCallback);
            }
        }
    
    
    
    
        private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
            public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
    
                        String d = "";
                        String rd = "";
                        String h = "0123456789ABCDEF";
                        int ln = 0;
                        int i = 0;
                        while (i < scanRecord.length) {
                            int x = scanRecord[i] & 255;
                            rd = new StringBuilder(String.valueOf(rd)).append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) +REQUEST_ENABLE_BT)).toString();
                            if (i == ln) {
                                ln = (i + x) + REQUEST_ENABLE_BT;
                                if (x == 0) {
                                    break;
                                }
                                d = new StringBuilder(String.valueOf(d)).append("\r\n     Length: ").append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) +REQUEST_ENABLE_BT)).toString();
                                i += REQUEST_ENABLE_BT;
                                x = scanRecord[i] & 255;
                                d = new StringBuilder(String.valueOf(d)).append(",   Type :").append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) + REQUEST_ENABLE_BT)).append(" = ").append(advDataTypes[x]).append(",   Value: ").toString();
                                rd = new StringBuilder(String.valueOf(rd)).append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) + REQUEST_ENABLE_BT)).toString();
    
                            } else {
                                d = new StringBuilder(String.valueOf(d)).append(" ").append(h.substring(x / 16, (x / 16) + REQUEST_ENABLE_BT)).append(h.substring(x % 16, (x % 16) +REQUEST_ENABLE_BT)).toString();
                            }
                            i += REQUEST_ENABLE_BT;
                        }
    
    
                        Log.e(TAG,"UUID : "+device.getUuids());
                        String[] arrayDeviceName=String.valueOf(device.getName()).split(" ");
                        String deviceName0=arrayDeviceName[0];
                            bluetoothDeviceArrayListTwo.add(device);
    
    
            }
        };
    
    
    
        /*-------------------Connect BLE---------------------------------------------*/
    
            private Handler mHandler2;
    
    
            public final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
    
            public void onReceive(Context context, Intent intent)
            {
                String action = intent.getAction();
    
    
                if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action))
                {
                    numberOfRssi = 0;
                    avgRssi = 0.0f;
                    mConnected = true;
                    updateConnectionState(R.string.connected);
                    mHandler2.postDelayed(startRssi, 300);
                    Log.e(TAG,"ACTION_GATT_CONNECTED");
    
                }
    
    
                else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                    mConnected = false;
                    updateConnectionState(R.string.disconnected);
                    Log.e(TAG,"ACTION_GATT_DISCONNECTED");
    
    
                } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
                    displayGattServicesForDimmer(mBluetoothLeService.getSupportedGattServices());// For dimmer
    
                    Log.e(TAG,"ACTION_GATT_SERVICES_DISCOVERED");
    
    
                } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
                    Log.e(TAG,"ACTION_DATA_AVAILABLE");
                    String unknownServiceString = context.getResources().getString(R.string.unknown_service);
                    displayDimmerData("<<" + SampleGattAttributes.lookup(intent.getStringExtra(BluetoothLeService.CHARACTERISTIC_UUID), unknownServiceString) + ">> Value: " + intent.getStringExtra(BluetoothLeService.EXTRA_DATA) + "]");
                    displayDimmer2(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
    
    
                } else if (BluetoothLeService.ACTION_GATT_RSSI_UPDATE.equals(action)) {
                    updateRssi(intent.getIntExtra(BluetoothLeService.EXTRA_DATA, -400));
    
                } else if (BluetoothLeService.ACTION_GATT_WRITE_FAILED.equals(action)) {
                    Log.e(TAG,"ACTION_GATT_WRITE_FAILED");
    
                }
    
            }
        };
    
    
    
    
    
    
    
        /*------------------------------------------------------------------------*/
    
        @Override
        public void onCreate() {
            super.onCreate();
    //    -------------------Connect Ble--------------------------------------
    
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
            intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
            intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
            intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
            intentFilter.addAction(BluetoothLeService.ACTION_GATT_RSSI_UPDATE);
            intentFilter.addAction(BluetoothLeService.ACTION_GATT_WRITE_FAILED);
    
            Log.e(TAG,"OnResume()");
    
            getApplicationContext().registerReceiver(mGattUpdateReceiver, intentFilter);
            getApplicationContext().bindService(new Intent(getApplicationContext(), BluetoothLeService.class), mServiceConnection, 1);
    
            mHandler2=new Handler();
        }
    
    
    
    
    
        private BluetoothGattCharacteristic mNotifyCharacteristic;
        private final ServiceConnection mServiceConnection = new ServiceConnection() {
            public void onServiceConnected(ComponentName componentName, IBinder service) {
                mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
                if (!mBluetoothLeService.initialize()) {
                    Log.e(TAG, "Unable to initialize Bluetooth");
    
                }
            }
            public void onServiceDisconnected(ComponentName componentName) {
                mBluetoothLeService = null;
            }
        };
        private boolean notificationActive = true;
        private int numberOfRssi = 0;
    
    
        private Runnable startRssi = new Runnable() {
            public void run() {
                if (mConnected) {
                    mBluetoothLeService.readRemoteRssi();
                    mHandler2.postDelayed(startRssi, 200);
                }
            }
        };
    
    
    
        public BluetoothGatt getmGatt() {
            return mGatt;
        }
    
        //code from DeviceControlActivity
        private void updateConnectionState(final int resourceId) {
            connectionStatus= String.valueOf(resourceId);
            Log.e(TAG,"Resource ID"+resourceId);
    
        }
    
        private void displayDimmerData(String data){
            Log.e(TAG,"Display Data :"+data);
    
    
        }
    
        private void displayDimmer2(String data){
            Log.e(TAG,"display Dimmer2"+data);
    
    
            String sosString = data.substring(0, Math.min(data.length(), 3));
            Log.e(TAG,"SOS String :"+sosString);
            if (sosString.equals("SOS")){
                Intent callIntent = new Intent(Intent.ACTION_CALL);
                    callIntent.setData(Uri.parse("tel:"+ SharedPreferencesUtils.getStringFromSharedPreferences(KEY_SP_MOBILE_NUMBER,getApplicationContext())));
                    callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    getApplicationContext().startActivity(callIntent);
            }
    
        }
    
        private void updateRssi(int data) {
            if (data > -400) {
                if (this.numberOfRssi > 10) {
                    this.avgRssi = ((9.0f * this.avgRssi) + ((float) data)) / 10.0f;
                } else {
                    this.avgRssi = (this.avgRssi + ((float) data)) / 2.0f;
                    this.numberOfRssi++;
                }
                connectionStatus="Connected, RSSI:" + data + ",  Avg:" + Math.round(this.avgRssi);
    
            }
        }
    
        /*-------------------------disaplay gatt service for dimmer----------------------*/
        private void displayGattServicesForDimmer(List<BluetoothGattService> gattServices) {
    
            if (gattServices != null) {
    
                String unknownServiceString = getResources().getString(R.string.unknown_service);
                String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
                ArrayList<HashMap<String, String>> gattServiceData = new ArrayList();
                ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList();
                this.mGattCharacteristics = new ArrayList();
    
    
                for (BluetoothGattService gattService : gattServices) {
                    HashMap<String, String> currentServiceData = new HashMap();
                    String uuid = gattService.getUuid().toString();
                    currentServiceData.put("NAME", SampleGattAttributes.lookup(uuid, unknownServiceString));
                    currentServiceData.put("UUID", uuid);
                    gattServiceData.add(currentServiceData);
                    ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList();
                    List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
                    ArrayList<BluetoothGattCharacteristic> charas = new ArrayList();
    
    
                    for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                        charas.add(gattCharacteristic);
                        HashMap<String, String> currentCharaData = new HashMap();
                        uuid = gattCharacteristic.getUuid().toString();
                        currentCharaData.put("NAME", "\t\t\t<<" + SampleGattAttributes.lookup(uuid, unknownCharaString) + ">>");
                        currentCharaData.put("UUID", "\t\t\tUUID: 0x" + uuid.substring(4, 8) + ", Properties: " + translateProperties(gattCharacteristic.getProperties()));
                        gattCharacteristicGroupData.add(currentCharaData);
    
                        Log.i(TAG,"CUrrent CHARACTERISTIC DATA"+currentCharaData);
                        Log.i(TAG,"UUID : "+uuid.substring(4, 8));
                        Log.i(TAG,"Proprties : "+gattCharacteristic.getProperties());
                        Log.i(TAG,"Translate Proprties : "+translateProperties(gattCharacteristic.getProperties()));
                        Log.i(TAG,"char list"+gattCharacteristicData.toString());
    
                    }
                    gattService4=gattService;
                    this.mGattCharacteristics.add(charas);
                }
    
                if (mGattCharacteristics.get(3)!=null) {
                    lastCharacteristic = new ArrayList<>(mGattCharacteristics.get(3));
                    enableNotifyOfCharcteristicForDimmer(lastCharacteristic);
    
                }
    
    
            }
        }
    
        private String translateProperties(int properties) {
            String s = "";
            if ((properties & 1) > 0) {
                s = new StringBuilder(String.valueOf(s)).append("/Broadcast").toString();
            }
            if ((properties & 2) > 0) {
                s = new StringBuilder(String.valueOf(s)).append("/Read").toString();
            }
            if ((properties & 4) > 0) {
                s = new StringBuilder(String.valueOf(s)).append("/WriteWithoutResponse").toString();
            }
            if ((properties & 8) > 0) {
                s = new StringBuilder(String.valueOf(s)).append("/Write").toString();
            }
            if ((properties & 16) > 0) {
                s = new StringBuilder(String.valueOf(s)).append("/Notify").toString();
            }
            if ((properties & 32) > 0) {
                s = new StringBuilder(String.valueOf(s)).append("/Indicate").toString();
            }
            if ((properties & 64) > 0) {
                s = new StringBuilder(String.valueOf(s)).append("/SignedWrite").toString();
            }
            if ((properties & 128) > 0) {
                s = new StringBuilder(String.valueOf(s)).append("/ExtendedProperties").toString();
            }
            if (s.length() > 1) {
                return s.substring(1);
            }
            return s;
        }
    
    
        //    Enable Characteristic for dimmer
        public void enableNotifyOfCharcteristicForDimmer(ArrayList<BluetoothGattCharacteristic> lastCharacteristic){
    
            if(mGattCharacteristics!=null) {
    
                checkCharacteristicPresent(lastCharacteristic.get(0));
                mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(0), true);
                notificationActive = true;
                Log.e(TAG,"Characteristic index : "+0+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 0 +" :" +lastCharacteristic.get(0).toString());
    
                checkCharacteristicPresent(lastCharacteristic.get(1));
                mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(1), true);
                notificationActive = true;
                Log.e(TAG,"Characteristic index : "+1+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 1 +" :" +lastCharacteristic.get(1).toString());
    
                checkCharacteristicPresent(lastCharacteristic.get(2));
                mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(2), true);
                notificationActive = true;
                Log.e(TAG,"Characteristic index : "+2+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 2 +" :" +lastCharacteristic.get(2).toString());
    
                checkCharacteristicPresent(lastCharacteristic.get(3));
                mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(3), true);
                notificationActive = true;
                Log.e(TAG,"Characteristic index : "+3+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 3 +" :" +lastCharacteristic.get(3).toString());
    
                checkCharacteristicPresent(lastCharacteristic.get(4));
                mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(4), true);
                notificationActive = true;
                Log.e(TAG,"Characteristic index : "+4+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 4 +" :" +lastCharacteristic.get(4).toString());
    
                checkCharacteristicPresent(lastCharacteristic.get(5));
                mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(5), true);
                notificationActive = true;
                Log.e(TAG,"Characteristic index : "+5+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 5 +" :" +lastCharacteristic.get(5).toString());
    
                checkCharacteristicPresent(lastCharacteristic.get(2));
                mBluetoothLeService.setCharacteristicNotification(lastCharacteristic.get(2), true);
                notificationActive = true;
                Log.e(TAG,"Characteristic index : "+2+":\nM GATT CHARACTERISTIC AT "+"Service 4 : CHAR"+ 2 +" :" +lastCharacteristic.get(2).toString());
    
            }
        }
    
        //  Check the type of characteristic i.e READ/WRITE/NOTIFY
        public void checkCharacteristicPresent(BluetoothGattCharacteristic characteristic) {
    
    
            int charaProp = characteristic.getProperties();
            Log.e(TAG, "checkCharacteristicPresent Prop : " + charaProp);
            mBluetoothLeService.setCurrentCharacteristic(characteristic);
    
            if ((charaProp & 2) > 0) {
                Log.e(TAG, "CharProp & 2 : " + charaProp);
                mBluetoothLeService.readCharacteristic(characteristic);
            } 
            if ((charaProp & 16) > 0) {
                Log.e(TAG, "CharProp & 16 : " + charaProp);
                mNotifyCharacteristic = characteristic;
    
            } else {
                if (mNotifyCharacteristic != null) {
                    mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, false);
                    mNotifyCharacteristic = null;
                }
            }
    
            if ((charaProp & 8) > 0 || (charaProp & 4) > 0) {
                Log.e(TAG, "CharProp & 4 : " + charaProp);
            } else {
                Log.e(TAG, "Else : " + charaProp);
    
            }
        }
    
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多