Bluetooth Low Energyのnotificationの実装について

1,641 views
Skip to first unread message

市道裕介

unread,
Nov 10, 2016, 8:18:20 AM11/10/16
to 日本Androidの会
スペース失礼いたします。

仕事でBLEの実装をすることになったのですが、通知部分ではまってしまい、作業が進まなくなってしまったため、皆さんの知恵を犯し頂ければと思い過去こませていただきました。

知っている方いたら解決策を教えてください。(期限が4日後のため急いでいます)

【質問】
BluetoothGattのnotificationの実装についての質問です。
BluetoothGattDescriptorを使用し設定することで、BluetoothGattCallBack#onCharacteristicChangedが呼び出されるようになることまではわかったのですが、これを複数のcharacteristicに対して設定を行いたいと思っているのですがどうしても最初の一つだけが有効になっており、あとから設定したものについては反映されていない状態となっています。

抜粋ですがソースコードは以下となります。
よろしくお願いします。

-------------------------------------------------------------------------------------------------------
@Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        // 接続状況が変化したら実行.
        Log.i(TAG, "onConnectionStateChange --------------------");
        Log.d(TAG, address + "/" + "newState : " + newState);

        switch (newState) {
            case BluetoothProfile.STATE_CONNECTING:
                Log.d(TAG, "  STATE_CONNECTING");
                break;
            case BluetoothProfile.STATE_CONNECTED:
                //接続→サービス検索(onServicesDiscovered)
                Log.d(TAG, "  STATE_CONNECTED");
                gatt.discoverServices();
                break;
            case BluetoothProfile.STATE_DISCONNECTING:
                Log.d(TAG, "  STATE_DISCONNECTING");
                break;
            case BluetoothProfile.STATE_DISCONNECTED:
                Log.d(TAG, "  STATE_DISCONNECTED");
                //sBluetoothGatt = null;
                //sStatus = Status.FOUND;     //またスキャンから始めるべきか?
                break;
            default:
                //エラーにすべき?
                Log.d(TAG, "  unknown state : " + newState);
                break;
        }
    }
    

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, final int status) {
   
    List<BluetoothGattService> list =  gatt.getServices();
            List<BluetoothGattCharacteristic> List2 = null;

            Log.i(TAG,address + " - service : " + list.size());
            for(BluetoothGattService service : list){

                String serviceUuid = service.getUuid().toString().toUpperCase();
                Log.i(TAG,address + " - service : " + serviceUuid);

                boolean getCharacteristic = true;

                if(getCharacteristic){
                    List<BluetoothGattCharacteristic> list2 = service.getCharacteristics();

                    Log.i(TAG,address + " - characteristic : " + list2.size());

                    for(BluetoothGattCharacteristic characteristic : list2){
                        String characterUuid = characteristic.getUuid().toString().toUpperCase();

                        Log.i(TAG,address + " - characteristic : " + characterUuid);

                        seGatttNotification(gatt, characteristic,true);
                    }
                }
            }
    }
    
     @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic){
        Log.i(TAG,"onCharacteristicChanged --------------------");
        String uuid = characteristic.getUuid().toString().toUpperCase();
        Log.i(TAG,"uuid : " + uuid);


    }
    
    private BluetoothGattDescriptor seGatttNotification(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,boolean enable){
        Log.i(TAG,"seGatttNotification");
        
        String uuid = characteristic.getUuid().toString().toUpperCase();


        String log = "";
        int charaProp = characteristic.getProperties();

        /**
        Log.w(TAG, "charaProp:" + charaProp);
        Log.w(TAG, "PROPERTY_READ:" + BluetoothGattCharacteristic.PROPERTY_READ);
        Log.w(TAG, "PROPERTY_WRITE:" + BluetoothGattCharacteristic.PROPERTY_WRITE);
        Log.w(TAG, "PROPERTY_NOTIFY:" + BluetoothGattCharacteristic.PROPERTY_NOTIFY);
        Log.w(TAG, "read check:" + (charaProp | BluetoothGattCharacteristic.PROPERTY_READ));
        Log.w(TAG, "noti check:" + (charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY));
        */

        if(charaProp == BluetoothGattCharacteristic.PROPERTY_READ){
        //if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {

            enable = false;
            // このcharacteristicは read に対応している

            boolean flag = gatt.setCharacteristicNotification(characteristic, enable);
            Log.w(TAG, "flag:" + flag);
            Log.w(TAG, "result read:" + gatt.readCharacteristic(characteristic));

            if(flag){
                log += " read";
            }
        }


        BluetoothGattDescriptor descriptor = null;
        if(false) {
        }else if(charaProp == BluetoothGattCharacteristic.PROPERTY_NOTIFY){
        //}else if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {

            //enable = true;
            // このcharacteristicは notification に対応している

            boolean flag = gatt.setCharacteristicNotification(characteristic, enable);
            Log.w(TAG, "flag:" + flag);

            descriptor = characteristic.getDescriptor(
                    UUID.fromString(CHARACTERISTIC_CONFIG));



            if(descriptor != null){


                int parmissions = descriptor.getPermissions();
                Log.w(TAG, "parmissions:" + parmissions);


                Log.w(TAG, "property : ENABLE_NOTIFICATION_VALUE");
                // Notifyに対応
                descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                // Indicateに対応
                //descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
                
                boolean flag2 = gatt.writeDescriptor(descriptor);
                Log.w(TAG, "result write:" + flag2);

                if(flag2){
                    log += " notification";
                }
            }else {

            }
        }

        if(false){

        }else if (charaProp == BluetoothGattCharacteristic.PROPERTY_WRITE) | charaProp == BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) {
        //}else if (((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE) | (charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) > 0) {
            Log.d(TAG,"BluetoothGattCharacteristic has PROPERY_WRITE | PROPERTY_WRITE_NO_RESPONSE");

        }



        Log.i(TAG, uuid + " enable:" + log);

        return descriptor;
    }

市道裕介

unread,
Nov 11, 2016, 8:35:41 AM11/11/16
to 日本Androidの会
自己解決しました。

BluetoothGattCallBack#onDescriptorWriteが呼ばれたタイミング以降でないと次のを登録できなかったみたいです。
お騒がせいたしました。

2016年11月10日木曜日 22時18分20秒 UTC+9 市道裕介:
Reply all
Reply to author
Forward
0 new messages