Android BLE-连接到多个设备似乎失败,并且两个连接的GATT响应都相同吗? [英] Android BLE - Connecting to multiple devices seem to fail and GATT Response is the same for both connections?

查看:346
本文介绍了Android BLE-连接到多个设备似乎失败,并且两个连接的GATT响应都相同吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Android应用程序,该应用程序连接到BLE设备并读取我需要检查的特定GATT特性和服务.我以Android Dev网站中的BluetoothLeGATT示例为参考.我可以毫无问题地连接到预定义的地址,并阅读GATT属性更新.

I am developing an Android Application that connects to a BLE Device and reads the specific GATT Characteristics and Services that I need to check. I used the BluetoothLeGATT example from the Android Dev site as my reference. I can connect to a predefined Address without problems and read the GATT Attribute updates.

我接下来要做的是能够同时连接到两个BLE设备.但是,这似乎是一个挑战.

What I want to do next is to be able to connect to two BLE Devices simultaneously. However, this seems to be a challenge.

我所做的基本上是复制连接到单个BLE设备所需的代码.我有2个BluetoothLeServices,2个用于GattCharacteristics和Gatt服务数据的ArrayList,以及2个服务连接和2个用于GattCallbacks的广播接收器.

What I did was to essentially duplicate the code needed to connect to a single BLE Device. I had 2 BluetoothLeServices, 2 ArrayLists for the GattCharacteristics and Gatt Service Data, as well as 2 Service Connections, and 2 Broadcast Receivers for GattCallbacks.

但是,在我的GattCallback函数中,我会收到相同的消息,就像它们已连接到同一区域一样.这是我的代码:

However, in my GattCallback functions, I get the same message -- as if they were connected to the same area. Here is my code:

public class MainActivity extends AppCompatActivity {

        /*
        UUIDs
            Dog Block - 20:CD:39:87:DC:AA
            Cat Block - 20:CD:39:87:DF:82
     */

    private final String TAG = this.getClass().getSimpleName();

    private BluetoothAdapter mBluetoothAdapter;
    private Handler mHandler;

    private static final int REQUEST_ENABLE_BT = 1;
    private static final long SCAN_PERIOD = 10000;

    private ArrayList<String> addressID = new ArrayList<>();
    private ArrayList<BluetoothDevice> deviceList = new ArrayList<>();

    private boolean mScanning = false;
    private boolean mConnected = false;

    private BluetoothLeService mBluetoothLeService;
    private BluetoothLeService mBluetoothLeService1;

    private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics =
            new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
    private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics1 =
            new ArrayList<ArrayList<BluetoothGattCharacteristic>>();


    private final String LIST_NAME = "NAME";
    private final String LIST_UUID = "UUID";

    ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
    ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData
            = new ArrayList<ArrayList<HashMap<String, String>>>();
    ArrayList<HashMap<String, String>> gattServiceData1 = new ArrayList<HashMap<String, String>>();
    ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData1
            = new ArrayList<ArrayList<HashMap<String, String>>>();

    private BluetoothGattCharacteristic mNotifyCharacteristic;
    private BluetoothGattCharacteristic mNotifyCharacteristic1;

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

        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(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
            finish();
        }

        // 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(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
            finish();
            return;
        }

        addressID.add("20:CD:39:87:DC:AA");
        addressID.add("20:CD:39:87:DF:82");
    }



    @Override
    protected void onResume() {
        super.onResume();

        Log.e(TAG, "onResume");

        // Ensures Bluetooth is enabled on the device.  If Bluetooth is not currently enabled,
        // fire an intent to display a dialog asking the user to grant permission to enable it.
        if (!mBluetoothAdapter.isEnabled()) {
            if (!mBluetoothAdapter.isEnabled()) {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }
        }
        scanLeDevice(true);

        if (mBluetoothLeService != null) {

        }

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // User chose not to enable Bluetooth.
        if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
            finish();
            return;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onPause() {
        super.onPause();
        scanLeDevice(false);
        unregisterReceiver(mGattUpdateReceiver);
        unregisterReceiver(mGattUpdateReceiver1);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mServiceConnection);
        mBluetoothLeService = null;
        mBluetoothLeService1 = null;
    }

    private void scanLeDevice(final boolean enable) {
        if (enable) {
            Log.e(TAG, "scanLeDevice true");
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    invalidateOptionsMenu();
                }
            }, SCAN_PERIOD);

            mScanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        } else {
            Log.e(TAG, "scanLeDevice false");
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
        invalidateOptionsMenu();
    }

    // Device scan callback.
    private BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {

                @Override
                public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {

                            deviceList.add(device);

                            Log.e(TAG, "deviceList count = " + deviceList.size());

                            if(deviceList.size() >= 2){
                                checkDevices();
                            }
                        }
                    });
                }
            };

    private void checkDevices() {

        Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
        bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);

        Intent gattServiceIntent1 = new Intent(this, BluetoothLeService.class);
        bindService(gattServiceIntent1, mServiceConnection1, BIND_AUTO_CREATE);

        registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
        registerReceiver(mGattUpdateReceiver1, makeGattUpdateIntentFilter());
    }

    //TODO -- connect functions here
    private static IntentFilter makeGattUpdateIntentFilter() {
        final 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);
        return intentFilter;
    }

    // Code to manage Service lifecycle.
    private final ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if (!mBluetoothLeService.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth");
                finish();
            }
            Log.e(TAG, "connecting to " + deviceList.get(0).getAddress());
            mBluetoothLeService.connect("20:CD:39:87:DC:AA");
        }
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mBluetoothLeService = null;
        }
    };
    private final ServiceConnection mServiceConnection1 = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            mBluetoothLeService1 = ((BluetoothLeService.LocalBinder) service).getService();

            if (!mBluetoothLeService1.initialize()) {
                Log.e(TAG, "1Unable to initialize Bluetooth");
                finish();
            }
            // Automatically connects to the device upon successful start-up initialization.
            Log.e(TAG, "1connecting to " + deviceList.get(1).getAddress());
            mBluetoothLeService1.connect("20:CD:39:87:DF:82");
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mBluetoothLeService = null;
        }
    };

    private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
                Log.e(TAG, "connected");
            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                Log.e(TAG, "disconnected");
                mConnected = false;
            } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
                // Show all the supported services and characteristics on the user interface.
                Log.e(TAG, "gatt services discovered");
                displayGattServices(mBluetoothLeService.getSupportedGattServices());
            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
                Log.e(TAG, "data available");
                String data = intent.getStringExtra(BluetoothLeService.EXTRA_DATA);
                Log.e(TAG, "data is = " + data);
            }
        }
    };

    private final BroadcastReceiver mGattUpdateReceiver1 = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
                Log.e(TAG, "1connected");
            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                Log.e(TAG, "1disconnected");
                mConnected = false;
            } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
                // Show all the supported services and characteristics on the user interface.
                Log.e(TAG, "1gatt services discovered");
                displayGattServices1(mBluetoothLeService1.getSupportedGattServices());
            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
                Log.e(TAG, "1data available");
                String data = intent.getStringExtra(BluetoothLeService.EXTRA_DATA);
                Log.e(TAG, "1data is = " + data);
            }
        }
    };

    private void displayGattServices(List<BluetoothGattService> gattServices) {
        if (gattServices == null) return;
        Log.e(TAG, "display gatt services not null.");
        String uuid = null;
        String unknownServiceString = getResources().getString(R.string.unknown_service);
        String unknownCharaString = getResources().getString(R.string.unknown_characteristic);

        mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();

        // Loops through available GATT Services.
        for (BluetoothGattService gattService : gattServices) {
            HashMap<String, String> currentServiceData = new HashMap<String, String>();
            uuid = gattService.getUuid().toString();
            currentServiceData.put(
                    LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString));
            currentServiceData.put(LIST_UUID, uuid);
            gattServiceData.add(currentServiceData);

            ArrayList<HashMap<String, String>> gattCharacteristicGroupData =
                    new ArrayList<HashMap<String, String>>();
            List<BluetoothGattCharacteristic> gattCharacteristics =
                    gattService.getCharacteristics();
            ArrayList<BluetoothGattCharacteristic> charas =
                    new ArrayList<BluetoothGattCharacteristic>();

            // Loops through available Characteristics.
            for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                charas.add(gattCharacteristic);
                HashMap<String, String> currentCharaData = new HashMap<String, String>();
                uuid = gattCharacteristic.getUuid().toString();
                currentCharaData.put(
                        LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString));
                currentCharaData.put(LIST_UUID, uuid);
                gattCharacteristicGroupData.add(currentCharaData);

                if(uuid.equals(SampleGattAttributes.DOG_CHARACTERISTIC_CONFIG)){
                    Log.e(TAG, "uuid characteristic detected");

                    final int charaProp = gattCharacteristic.getProperties();
                    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
                        Log.e(TAG, "gatt characteristics read!");
                        // If there is an active notification on a characteristic, clear
                        // it first so it doesn't update the data field on the user interface.
                        if (mNotifyCharacteristic != null) {
                            mBluetoothLeService.setCharacteristicNotification(
                                    mNotifyCharacteristic, false);
                            mNotifyCharacteristic = null;
                        }
                        mBluetoothLeService.readCharacteristic(gattCharacteristic);

                    }
                    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                        Log.e(TAG, "gatt characteristics notify!");
                        mNotifyCharacteristic = gattCharacteristic;
                        mBluetoothLeService.setCharacteristicNotification(
                                gattCharacteristic, true);

                    }
                }

            }
            mGattCharacteristics.add(charas);
            gattCharacteristicData.add(gattCharacteristicGroupData);
        }

    }

    private void displayGattServices1(List<BluetoothGattService> gattServices) {
        if (gattServices == null) return;
        Log.e(TAG, "1display gatt services not null.");
        String uuid = null;
        String unknownServiceString = getResources().getString(R.string.unknown_service);
        String unknownCharaString = getResources().getString(R.string.unknown_characteristic);

        mGattCharacteristics1 = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();

        // Loops through available GATT Services.
        for (BluetoothGattService gattService : gattServices) {
            HashMap<String, String> currentServiceData = new HashMap<String, String>();
            uuid = gattService.getUuid().toString();
            currentServiceData.put(
                    LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString));
            currentServiceData.put(LIST_UUID, uuid);
            gattServiceData1.add(currentServiceData);

            ArrayList<HashMap<String, String>> gattCharacteristicGroupData =
                    new ArrayList<HashMap<String, String>>();
            List<BluetoothGattCharacteristic> gattCharacteristics =
                    gattService.getCharacteristics();
            ArrayList<BluetoothGattCharacteristic> charas =
                    new ArrayList<BluetoothGattCharacteristic>();

            // Loops through available Characteristics.
            for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                charas.add(gattCharacteristic);
                HashMap<String, String> currentCharaData = new HashMap<String, String>();
                uuid = gattCharacteristic.getUuid().toString();
                currentCharaData.put(
                        LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString));
                currentCharaData.put(LIST_UUID, uuid);
                gattCharacteristicGroupData.add(currentCharaData);

                if (uuid.equals(SampleGattAttributes.DOG_CHARACTERISTIC_CONFIG)) {
                    Log.e(TAG, "1uuid characteristic detected");

                    final int charaProp = gattCharacteristic.getProperties();
                    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
                        Log.e(TAG, "1gatt characteristics read!");
                        // If there is an active notification on a characteristic, clear
                        // it first so it doesn't update the data field on the user interface.
                        if (mNotifyCharacteristic1 != null) {
                            mBluetoothLeService1.setCharacteristicNotification(
                                    mNotifyCharacteristic1, false);
                            mNotifyCharacteristic1 = null;
                        }
                        mBluetoothLeService1.readCharacteristic(gattCharacteristic);

                    }
                    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                        Log.e(TAG, "1gatt characteristics notify!");
                        mNotifyCharacteristic1 = gattCharacteristic;
                        mBluetoothLeService1.setCharacteristicNotification(
                                gattCharacteristic, true);

                    }
                }

            }
            mGattCharacteristics1.add(charas);
            gattCharacteristicData1.add(gattCharacteristicGroupData);
        }

    }
}

我要做的是,一旦获得要连接的2个地址,便会初始化所有必需的连接,服务和广播接收器.但是,我收到的blueLeothLeGatt消息是相同的.根据连接到狗"或猫"块的方式,我会得到以下信息:

What I do is that once I get the 2 addresses that I want to connect to, I initialize all the necessary connections, services, and broadcast receivers. However, the bluetoothLeGatt messages I receive are the same. Depending on it connected to the Dog or Cat block, I'd get the lines:

data = dog
1data = dog

来自LogCat.似乎它们已连接到同一设备.

From the LogCat. It seems as if they were connected to the same device.

我检查了我的代码,甚至将地址硬编码在其中,但无济于事.

I checked my code and I even hardcoded the addresses in but to no avail.

推荐答案

我已经与多个设备建立了连接,并且工作正常.我还为扫描"项目提供了一项服务,为每项ble通信提供了一项服务.确保不要在通信部分使用绑定服务,因为断开连接可能会成为问题.(在我的情况下). 对于扫描内容,我制作了一个包含Mac地址的字符串列表.当我在扫描仪中找到一台设备时,我通过广播接收器将该设备发送到我的主要活动,然后在那里将其传输到其服务.因此,每个连接都通过自己的广播接收器和过滤器设置在自己的服务中运行.为了确保这不是广播接收器的问题,请在每个服务中创建一个控制台日志,在其中立即显示输出.我无法想象您的设备必须连接到同一服务器.

I've made a connection with multiple devices and it works fine. I also made one Service for the Scanning stuff and one for each ble communication. Make shure not to use bound services for the communication part because de disconnection might be a problem.(It was in my case). For the Scanning stuff I made a List of Strings with the Mac adresses in it. When I found one device in my scanner I send the device via broadcastreceiver to my main activity and there I transmit it to it's service. So every connection runs in it's own service with it's own broadcastreceiver and filtersettings. To make shure that it's not a problem of your broadcastreceiver, make a console log in each service where you display the output immeadiatly. I can't imagine that your device has to connections to the same server.

这篇关于Android BLE-连接到多个设备似乎失败,并且两个连接的GATT响应都相同吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆