什么是获得蓝牙低功耗(BLE)设备通知的步骤是什么? [英] What are the steps to get notified by Bluetooth Low Energy (BLE) device?

查看:285
本文介绍了什么是获得蓝牙低功耗(BLE)设备通知的步骤是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的蓝牙低功耗(BLE)应用程序。我有一个BLE装置(规模),其测量体重。我能够与该设备连接。但我没有得到如何从中读取数据(权值)。

我想知道如果我的应用程序连接到任何BLE装置,那么,得到由设备以获得更新后的数据通知的步骤。

好了,下面是我的活动,我现在用的。

 公共类BlogBLEActivity扩展活动实现OnItemClickListener
{
    私人最终静态字符串变量= BlogBLEActivity.class.getSimpleName();

    私人BluetoothAdapter bluetoothAdapter;
    BluetoothManager bluetoothManager;

    布尔hasBleFeature = FALSE;

    TextView的tvMessage;
    INT邮件ID = R.string.doesnt_support_ble;
    INT colorId = android.R.color.holo_red_light;

    私人布尔mScanning;
    私人处理程序处理程序=新的处理程序();

    私有静态最后长SCAN_PERIOD = 10000;
    私有静态最终诠释REQUEST_ENABLE_BT = 1209;

    ListView控件的ListView;
    ArrayList的< BluetoothDevice类> listDevices;

    BleDeviceAdapter bleDeviceAdapter;

    TextView的tvHumidity;
    TextView的tvTemperature;
    TextView的电视pressure;

    布尔isConnected = FALSE;

    @覆盖
    保护无效的onCreate(包savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.blog_ble);

        initParameters();
        initViews();

        scanLeDevice(真正的);
    }

    @燮pressLint(NewApi)
    无效initParameters()
    {
        hasBleFeature = getPackageManager()hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)。
        Log.i(TAG,hasBleFeature:+ hasBleFeature);

        如果(hasBleFeature)
        {
            邮件ID = R.string.supports_ble;
            colorId = android.R.color.holo_blue_light;
        } 其他
        {
            邮件ID = R.string.doesnt_support_ble;
            colorId = android.R.color.holo_red_light;
        }

        bluetoothManager =(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
        bluetoothAdapter = bluetoothManager.getAdapter(); // BluetoothAdapter.getDefaultAdapter();

        如果(bluetoothAdapter == NULL ||!bluetoothAdapter.isEnabled())
        {
            意图enableBtIntent =新的意图(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);
        }

        listDevices =新的ArrayList< BluetoothDevice类>();
        bleDeviceAdapter =新BleDeviceAdapter(这一点,listDevices);
    }

    无效initViews()
    {
        tvHumidity =(TextView中)findViewById(R.id.blog_ble_tv_humidity);
        tvTemperature =(TextView中)findViewById(R.id.blog_ble_tv_temprature);
        电视pressure =(TextView中)findViewById(R.id.blog_ble_tv_ pressure);

        tvMessage =(TextView中)findViewById(R.id.blog_ble_tv_message);
        tvMessage.setText(getResources()的getString(邮件ID));
        tvMessage.setTextColor(getResources()的getColor(colorId));

        ListView的=(的ListView)findViewById(R.id.blog_ble_list_view);
        listView.setAdapter(bleDeviceAdapter);
        listView.setOnItemClickListener(本);
    }

    @燮pressLint(NewApi)
    无效scanLeDevice(最终布尔使能)
    {
        如果(启用)
        {
            handler.postDelayed(新的Runnable()
            {
                @燮pressLint(NewApi)
                @覆盖
                公共无效的run()
                {
                    mScanning = FALSE;
                    bluetoothAdapter.stopLeScan(leScanCallback);
                }
            },SCAN_PERIOD);

            mScanning = FALSE;
            bluetoothAdapter.startLeScan(leScanCallback);
        } 其他
        {
            mScanning = FALSE;
            bluetoothAdapter.stopLeScan(leScanCallback);
        }
    }

    @燮pressLint(NewApi)
    私人BluetoothAdapter.LeScanCallback leScanCallback =新BluetoothAdapter.LeScanCallback()
    {
        @覆盖
        公共无效onLeScan(最终BluetoothDevice类设备,INT RSSI,byte []的scanRecord)
        {
            runOnUiThread(新的Runnable()
            {
                @覆盖
                公共无效的run()
                {
                    如果(设备!= NULL)
                    {
                        bleDeviceAdapter.add(设备);
                        bleDeviceAdapter.notifyDataSetChanged();
                    }
                }
            });
        }
    };

    类BleDeviceAdapter扩展ArrayAdapter< BluetoothDevice类>
    {
        公共BleDeviceAdapter(上下文的背景下,名单,其中,BluetoothDevice类>对象)
        {
            超(背景下,R.layout.row_ble_device,R.id.row_ble_device_tv_name,对象);
        }

        @燮pressLint(NewApi)
        @覆盖
        公共查看getView(INT位置,查看convertView,父母的ViewGroup)
        {
            查看排= super.getView(位置,convertView,父母);
            ViewHolder支架=(ViewHolder)row.getTag();
            如果(持有人== NULL)
            {
                持有人=新ViewHolder(行);
                row.setTag(保持器);
            }

            BluetoothDevice类设备=的getDevice(位置);
            holder.tvName.setText(+ device.getName());

            Log.i(TAG,+ device.getName());
            返回行;
        }
    }

    BluetoothDevice类的getDevice(INT位置)
    {
        返程(BluetoothDevice类)listView.getAdapter()的getItem(位置)。
    }

    @燮pressLint(NewApi)
    @覆盖
    公共无效onItemClick(适配器视图<>为arg0,查看ARG1,INT位置,长ARG3)
    {
        BluetoothDevice类设备=的getDevice(位置);
        Toast.makeText(这一点,+ device.getName(),Toast.LENGTH_SHORT).show();
        BluetoothGatt connectGatt = device.connectGatt(这一点,假的,mGattCallback);

    }

    / *客户端配置描述符* /
    私有静态最后UUID CONFIG_DESCRIPTOR = UUID.fromString(00002902-0000-1000-8000-00805f9b34fb);

    私有静态最后UUID KITCHEN_SCALE_SERVICE = UUID.fromString(0000780a-0000-1000-8000-00805f9b34fb);
    私有静态最后UUID KITCHEN_SCALE_FEATURE_CHAR = UUID.fromString(00008aa0-0000-1000-8000-00805f9b34fb);
    私有静态最后UUID KITCHEN_SCALE_MEASUREMENT_CHAR = UUID.fromString(00008aa1-0000-1000-8000-00805f9b34fb);
    私有静态最后UUID KITCHEN_SCALE_INTERMEDIATE_CHAR = UUID.fromString(00008aa2-0000-1000-8000-00805f9b34fb);

    / *
     *在回调中,我们已经创建了一个有点状态机来强制执行的
     *仅一个特征被读或写的时间,直到所有的我们的
     *传感器被激活,我们正在注册以获得通知。
     * /
    @燮pressLint(NewApi)
    私人BluetoothGattCallback mGattCallback =新BluetoothGattCallback()
    {

        / *状态机跟踪* /
        私人诠释mState = 0;

        私人无效复位()
        {
            mState = 0;
        }

        私人无效提前()
        {
            mState ++;
        }

        / *
         *发送写配置enable命令到每个传感器
         * 特性。这是特定于SensorTag保持功率低
         *通过禁用不使用的传感器。
         * /
        私人无效enableNextSensor(BluetoothGatt GATT)
        {
            BluetoothGattCharacteristic特性;
            开关(mState)
            {
            情况下0:
                Log.i(TAG,启用计重秤);
                特点= gatt.getService(KITCHEN_SCALE_SERVICE).getCharacteristic(KITCHEN_SCALE_FEATURE_CHAR);
                Log.i(TAG,功能属性:+ characteristic.getProperties());
                characteristic.setValue(新的byte []
                {×09});
                打破;

            默认:
                mHandler.sendEmptyMessage(MSG_DISMISS);
                Log.i(TAG,所有的传感器已启用);
                返回;
            }

            gatt.writeCharacteristic(特性);
        }

        / *
         *读取数据特征的价值为每个传感器明确地
         * /
        私人无效readNextSensor(BluetoothGatt GATT)
        {
            BluetoothGattCharacteristic特性;
            开关(mState)
            {
            情况下0:
                Log.i(TAG,读重CAL);
                特点= gatt.getService(KITCHEN_SCALE_SERVICE).getCharacteristic(KITCHEN_SCALE_MEASUREMENT_CHAR);
                打破;

            默认:
                mHandler.sendEmptyMessage(MSG_DISMISS);
                Log.i(TAG,所有的传感器已启用);
                返回;
            }

            gatt.readCharacteristic(特性);
        }

        / *
         *启用变更通知对每一个数据特征
         *通过写ENABLE_NOTIFICATION_VALUE标志,该传感器
         *特性的配置描述符。
         * /
        私人无效setNotifyNextSensor(BluetoothGatt GATT)
        {
            BluetoothGattCharacteristic特性;
            开关(mState)
            {
            情况下0:
                Log.i(TAG,通知设置重);
                特点= gatt.getService(KITCHEN_SCALE_SERVICE).getCharacteristic(KITCHEN_SCALE_MEASUREMENT_CHAR);
                打破;

            默认:
                mHandler.sendEmptyMessage(MSG_DISMISS);
                Log.i(TAG,所有的传感器已启用);
                返回;
            }

            //启用本地通知
            gatt.setCharacteristicNotification(特征,真实);
            //启用远程通知
            BluetoothGattDescriptor DESC = characteristic.getDescriptor(CONFIG_DESCRIPTOR);
            desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            gatt.writeDescriptor(DESC);
        }

        @覆盖
        公共无效onConnectionStateChange(BluetoothGatt关贸总协定,INT状态,INT newState)
        {
            Log.i(TAG,连接状态更改:+状态+ - >中+ connectionState(newState));
            如果(状态== BluetoothGatt.GATT_SUCCESS和放大器;&安培; newState == BluetoothProfile.STATE_CONNECTED)
            {
                / *
                 *一旦连接成功,就必须在下一个发现所有的
                 *服务在设备上,才可以读取和写入的
                 *特征。
                 * /
                gatt.discoverServices();
                mHandler.sendMessage(Message.obtain(空,MSG_PROGRESS,发现服务......));
            }否则,如果(状态== BluetoothGatt.GATT_SUCCESS和放大器;&安培; newState == BluetoothProfile.STATE_DISCONNECTED)
            {
                / *
                 *如果在我们断开任何一点,将消息发送到清除
                 *天气价值观出了用户界面
                 * /

                mHandler.sendEmptyMessage(MSG_CLEAR);
            }否则,如果(状态!= BluetoothGatt.GATT_SUCCESS)
            {
                / *
                 *如果有故障的任何阶段,只需断开
                 * /
                gatt.disconnect();
            }
        }

        @覆盖
        公共无效onServicesDiscovered(BluetoothGatt关贸总协定,INT状态)
        {
            Log.i(TAG,服务发现:+状态);
            如果(状态== BluetoothGatt.GATT_SUCCESS)
            {
                Log.i(TAG,没有发现服务:+ gatt.getServices()的大小());
                mHandler.sendMessage(Message.obtain(空,MSG_PROGRESS,没有服务的发现:+ gatt.getServices()的大小()));

                名单< BluetoothGattService>服务= gatt.getServices();
                对于(BluetoothGattService bluetoothGattService:服务)
                {
                    UUID UUID = bluetoothGattService.getUuid();
                    Log.e(TAG,+ uuid.toString());
                    名单< BluetoothGattCharacteristic>特性= bluetoothGattService.getCharacteristics();
                    对于(BluetoothGattCharacteristic bluetoothGattCharacteristic:特性)
                    {
                        UUID uuidC = bluetoothGattCharacteristic.getUuid();
                        Log.i(TAG,盖特属性:+ bluetoothGattCharacteristic.getProperties());
                        Log.i(TAG,+ uuidC.toString());
                        CharacteristicHelper帮手=新CharacteristicHelper(bluetoothGattCharacteristic);
                        Log.i(TAG,isRead:+ helper.isRead());
                        Log.i(TAG,isWrite:+ helper.isWrite());
                        Log.i(TAG,isNotify:+ helper.isNotify());
                        Log.i(TAG,isWriteNoResponse:+ helper.isWriteNoResponse());
                    }
                }
            }
            // mHandler.sendMessage(Message.obtain(空,MSG_PROGRESS,
            //启用传感器......));
            / *
             *使用服务发现,我们将重新设置我们的状态机
             *和开始通过我们需要使传感器工作
             * /
             复位();
             enableNextSensor(GATT);
        }

        @覆盖
        公共无效onCharacteristicRead(BluetoothGatt关贸总协定,BluetoothGattCharacteristic特征,诠释状态)
        {
            Log.i(TAG,onCharacteristicRead);
            //对于每个读取,传递数据到UI线程更新
            // 显示
            /**methodToUpdateUI().*/

            //读取初始值后,接下来我们启用通知
            setNotifyNextSensor(GATT);
        }

        @覆盖
        公共无效onCharacteristicWrite(BluetoothGatt关贸总协定,BluetoothGattCharacteristic特征,诠释状态)
        {
            Log.i(TAG,onCharacteristicWrite);
            //后写使能标志,接下来我们看到的初始值
            readNextSensor(GATT);
        }

        @覆盖
        公共无效onCharacteristicChanged(BluetoothGatt关贸总协定,BluetoothGattCharacteristic特性)
        {
            Log.i(TAG,onCharacteristicChanged);
            / *
             *启用通知后,从设备上的所有更新
             *特征值的变化将张贴在这里。如同
             *阅读,我们一方面这些到UI线程更新显示。
             * /
        }

        @覆盖
        公共无效onDescriptorWrite(BluetoothGatt关贸总协定,BluetoothGattDescriptor描述,诠释状态)
        {
            Log.i(TAG,onDescriptorWrite);
            //一旦启用通知,我们移动到下一个传感器,并
            //新开始启用
            提前();
            enableNextSensor(GATT);
        }

        @覆盖
        公共无效onReadRemoteRssi(BluetoothGatt关贸总协定,诠释RSSI,诠释状态)
        {
            Log.i(TAG,远程RSSI:+ RSSI);
        }

        私人字符串connectionState(INT状态)
        {
            开关(状态)
            {
            案例BluetoothProfile.STATE_CONNECTED:
                返回已连接;
            案例BluetoothProfile.STATE_DISCONNECTED:
                返回断开连接;
            案例BluetoothProfile.STATE_CONNECTING:
                返回正在连接;
            案例BluetoothProfile.STATE_DISCONNECTING:
                返回断开;
            默认:
                返回将String.valueOf(状态);
            }
        }
    };

    / *
     *我们有一个处理程序来处理在主线程事件结果
     * /
    私有静态最终诠释MSG_PROGRESS = 201;
    私有静态最终诠释MSG_DISMISS = 202;
    私有静态最终诠释MSG_CLEAR = 301;
    私人处理程序mHandler =新的处理程序()
    {
        @燮pressLint(NewApi)
        @覆盖
        公共无效的handleMessage(信息MSG)
        {
            BluetoothGattCharacteristic特性;
            开关(msg.what)
            {
            案例MSG_PROGRESS:
                tvMessage.setText((字符串)msg.obj);
                打破;
            案例MSG_DISMISS:
                tvMessage.setText(服务已启用);
                打破;
            案例MSG_CLEAR:
                tvMessage.setText();
                打破;
            }
        }
    };
}
 

在我的活动,首先我扫描所有可用的设备及放大器; preparing的ListView。在单击列表项我连接到特定的设备。当设备的状态成为连接后来我发现服务。我该设备的服务和放大器的UUID;它的特性。但我不知道怎么写于任何特定的特征或从中启用或读取数据。   虽然我已经试过这件事情,但我看不出有任何的成功。

如果任何人有任何想法,请帮助我。

解决方案

让我用这需要设备

  descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE)
 

而不是

  descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)
 

在这个问题的解释

<一个href="http://stackoverflow.com/questions/17910322/android-ble-api-gatt-notification-not-received">Android BLE API:GATT通知没有收到

I am working on a Bluetooth Low Energy (BLE) app. I have a BLE device (scale) which measures weight. I am able to connect with this device. But I am not getting how to read data (weight value) from it.

I want to know if my app is connected to any BLE device, so what are the steps to get notified by device in order to get updated data.

Okay, following is the for my Activity which I am using..

public class BlogBLEActivity extends Activity implements OnItemClickListener
{
    private final static String TAG = BlogBLEActivity.class.getSimpleName();

    private BluetoothAdapter bluetoothAdapter;
    BluetoothManager bluetoothManager;

    boolean hasBleFeature = false;

    TextView tvMessage;
    int messageId = R.string.doesnt_support_ble;
    int colorId = android.R.color.holo_red_light;

    private boolean mScanning;
    private Handler handler = new Handler();

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

    ListView listView;
    ArrayList<BluetoothDevice> listDevices;

    BleDeviceAdapter bleDeviceAdapter;

    TextView tvHumidity;
    TextView tvTemperature;
    TextView tvPressure;

    boolean isConnected = false;

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

        initParameters();
        initViews();

        scanLeDevice(true);
    }

    @SuppressLint("NewApi")
    void initParameters()
    {
        hasBleFeature = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
        Log.i(TAG, "hasBleFeature : " + hasBleFeature);

        if (hasBleFeature)
        {
            messageId = R.string.supports_ble;
            colorId = android.R.color.holo_blue_light; 
        } else
        {
            messageId = R.string.doesnt_support_ble;
            colorId = android.R.color.holo_red_light;
        }

        bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        bluetoothAdapter = bluetoothManager.getAdapter();// BluetoothAdapter.getDefaultAdapter();

        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled())
        {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }

        listDevices = new ArrayList<BluetoothDevice>();
        bleDeviceAdapter = new BleDeviceAdapter(this, listDevices);
    }

    void initViews()
    {
        tvHumidity = (TextView) findViewById(R.id.blog_ble_tv_humidity);
        tvTemperature = (TextView) findViewById(R.id.blog_ble_tv_temprature);
        tvPressure = (TextView) findViewById(R.id.blog_ble_tv_pressure);

        tvMessage = (TextView) findViewById(R.id.blog_ble_tv_message);
        tvMessage.setText(getResources().getString(messageId));
        tvMessage.setTextColor(getResources().getColor(colorId));

        listView = (ListView) findViewById(R.id.blog_ble_list_view);
        listView.setAdapter(bleDeviceAdapter);
        listView.setOnItemClickListener(this);
    }

    @SuppressLint("NewApi")
    void scanLeDevice(final boolean enable)
    {
        if (enable)
        {
            handler.postDelayed(new Runnable()
            {
                @SuppressLint("NewApi")
                @Override
                public void run()
                {
                    mScanning = false;
                    bluetoothAdapter.stopLeScan(leScanCallback);
                }
            }, SCAN_PERIOD);

            mScanning = false;
            bluetoothAdapter.startLeScan(leScanCallback);
        } else
        {
            mScanning = false;
            bluetoothAdapter.stopLeScan(leScanCallback);
        }
    }

    @SuppressLint("NewApi")
    private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback()
    {
        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord)
        {
            runOnUiThread(new Runnable()
            {
                @Override
                public void run()
                {
                    if (device != null)
                    {
                        bleDeviceAdapter.add(device);
                        bleDeviceAdapter.notifyDataSetChanged();
                    }
                }
            });
        }
    };

    class BleDeviceAdapter extends ArrayAdapter<BluetoothDevice>
    {
        public BleDeviceAdapter(Context context, List<BluetoothDevice> objects)
        {
            super(context, R.layout.row_ble_device, R.id.row_ble_device_tv_name, objects);
        }

        @SuppressLint("NewApi")
        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            View row = super.getView(position, convertView, parent);
            ViewHolder holder = (ViewHolder) row.getTag();
            if (holder == null)
            {
                holder = new ViewHolder(row);
                row.setTag(holder);
            }

            BluetoothDevice device = getDevice(position);
            holder.tvName.setText("" + device.getName());

            Log.i(TAG, "" + device.getName());
            return row;
        }
    }

    BluetoothDevice getDevice(int position)
    {
        return (BluetoothDevice) listView.getAdapter().getItem(position);
    }

    @SuppressLint("NewApi")
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3)
    {
        BluetoothDevice device = getDevice(position);
        Toast.makeText(this, "" + device.getName(), Toast.LENGTH_SHORT).show();
        BluetoothGatt connectGatt = device.connectGatt(this, false, mGattCallback);

    }

    /* Client Configuration Descriptor */
    private static final UUID CONFIG_DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");

    private static final UUID KITCHEN_SCALE_SERVICE = UUID.fromString("0000780a-0000-1000-8000-00805f9b34fb");
    private static final UUID KITCHEN_SCALE_FEATURE_CHAR = UUID.fromString("00008aa0-0000-1000-8000-00805f9b34fb");
    private static final UUID KITCHEN_SCALE_MEASUREMENT_CHAR = UUID.fromString("00008aa1-0000-1000-8000-00805f9b34fb");
    private static final UUID KITCHEN_SCALE_INTERMEDIATE_CHAR = UUID.fromString("00008aa2-0000-1000-8000-00805f9b34fb");

    /*
     * In this callback, we've created a bit of a state machine to enforce that
     * only one characteristic be read or written at a time until all of our
     * sensors are enabled and we are registered to get notifications.
     */
    @SuppressLint("NewApi")
    private BluetoothGattCallback mGattCallback = new BluetoothGattCallback()
    {

        /* State Machine Tracking */
        private int mState = 0;

        private void reset()
        {
            mState = 0;
        }

        private void advance()
        {
            mState++;
        }

        /*
         * Send an enable command to each sensor by writing a configuration
         * characteristic. This is specific to the SensorTag to keep power low
         * by disabling sensors you aren't using.
         */
        private void enableNextSensor(BluetoothGatt gatt)
        {
            BluetoothGattCharacteristic characteristic;
            switch (mState)
            {
            case 0:
                Log.i(TAG, "Enabling weight scale");
                characteristic = gatt.getService(KITCHEN_SCALE_SERVICE).getCharacteristic(KITCHEN_SCALE_FEATURE_CHAR);
                Log.i(TAG, "Feature Properties : "+characteristic.getProperties());
                characteristic.setValue(new byte[]
                { 0x09 });
                break;

            default:
                mHandler.sendEmptyMessage(MSG_DISMISS);
                Log.i(TAG, "All Sensors Enabled");
                return;
            }

            gatt.writeCharacteristic(characteristic);
        }

        /*
         * Read the data characteristic's value for each sensor explicitly
         */
        private void readNextSensor(BluetoothGatt gatt)
        {
            BluetoothGattCharacteristic characteristic;
            switch (mState)
            {
            case 0:
                Log.i(TAG, "Reading weight cal");
                characteristic = gatt.getService(KITCHEN_SCALE_SERVICE).getCharacteristic(KITCHEN_SCALE_MEASUREMENT_CHAR);
                break;

            default:
                mHandler.sendEmptyMessage(MSG_DISMISS);
                Log.i(TAG, "All Sensors Enabled");
                return;
            }

            gatt.readCharacteristic(characteristic);
        }

        /*
         * Enable notification of changes on the data characteristic for each
         * sensor by writing the ENABLE_NOTIFICATION_VALUE flag to that
         * characteristic's configuration descriptor.
         */
        private void setNotifyNextSensor(BluetoothGatt gatt)
        {
            BluetoothGattCharacteristic characteristic;
            switch (mState)
            {
            case 0:
                Log.i(TAG, "Set notify weight ");
                characteristic = gatt.getService(KITCHEN_SCALE_SERVICE).getCharacteristic(KITCHEN_SCALE_MEASUREMENT_CHAR);
                break;

            default:
                mHandler.sendEmptyMessage(MSG_DISMISS);
                Log.i(TAG, "All Sensors Enabled");
                return;
            }

            // Enable local notifications
            gatt.setCharacteristicNotification(characteristic, true);
            // Enabled remote notifications
            BluetoothGattDescriptor desc = characteristic.getDescriptor(CONFIG_DESCRIPTOR);
            desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            gatt.writeDescriptor(desc);
        }

        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState)
        {
            Log.i(TAG, "Connection State Change: " + status + " -> " + connectionState(newState));
            if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED)
            {
                /*
                 * Once successfully connected, we must next discover all the
                 * services on the device before we can read and write their
                 * characteristics.
                 */
                gatt.discoverServices();
                mHandler.sendMessage(Message.obtain(null, MSG_PROGRESS, "Discovering Services..."));
            } else if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_DISCONNECTED)
            {
                /*
                 * If at any point we disconnect, send a message to clear the
                 * weather values out of the UI
                 */

                mHandler.sendEmptyMessage(MSG_CLEAR);
            } else if (status != BluetoothGatt.GATT_SUCCESS)
            {
                /*
                 * If there is a failure at any stage, simply disconnect
                 */
                gatt.disconnect();
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status)
        {
            Log.i(TAG, "Services Discovered: " + status);
            if (status == BluetoothGatt.GATT_SUCCESS)
            {
                Log.i(TAG, "No of services discovered: " + gatt.getServices().size());
                mHandler.sendMessage(Message.obtain(null, MSG_PROGRESS, "No of services discovered: " + gatt.getServices().size()));

                List<BluetoothGattService> services = gatt.getServices();
                for (BluetoothGattService bluetoothGattService : services)
                {
                    UUID uuid = bluetoothGattService.getUuid();
                    Log.e(TAG, ""+uuid.toString());
                    List<BluetoothGattCharacteristic> characteristics = bluetoothGattService.getCharacteristics();
                    for (BluetoothGattCharacteristic bluetoothGattCharacteristic : characteristics)
                    {
                        UUID uuidC = bluetoothGattCharacteristic.getUuid();
                        Log.i(TAG, "Gatt Properties : "+bluetoothGattCharacteristic.getProperties());
                        Log.i(TAG, ""+uuidC.toString());
                        CharacteristicHelper helper = new CharacteristicHelper(bluetoothGattCharacteristic);
                        Log.i(TAG, "isRead : "+helper.isRead());
                        Log.i(TAG, "isWrite : "+helper.isWrite());
                        Log.i(TAG, "isNotify : "+helper.isNotify());
                        Log.i(TAG, "isWriteNoResponse : "+helper.isWriteNoResponse());
                    }
                }
            }
            // mHandler.sendMessage(Message.obtain(null, MSG_PROGRESS,
            // "Enabling Sensors..."));
            /*
             * With services discovered, we are going to reset our state machine
             * and start working through the sensors we need to enable
             */
             reset();
             enableNextSensor(gatt);
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
        {
            Log.i(TAG, "onCharacteristicRead");
            // For each read, pass the data up to the UI thread to update the
            // display
            /**methodToUpdateUI().*/

            // After reading the initial value, next we enable notifications
            setNotifyNextSensor(gatt);
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
        {
            Log.i(TAG, "onCharacteristicWrite");
            // After writing the enable flag, next we read the initial value
            readNextSensor(gatt);
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
        {
            Log.i(TAG, "onCharacteristicChanged");
            /*
             * After notifications are enabled, all updates from the device on
             * characteristic value changes will be posted here. Similar to
             * read, we hand these up to the UI thread to update the display.
             */
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status)
        {
            Log.i(TAG, "onDescriptorWrite");
            // Once notifications are enabled, we move to the next sensor and
            // start over with enable
            advance();
            enableNextSensor(gatt);
        }

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status)
        {
            Log.i(TAG, "Remote RSSI: " + rssi);
        }

        private String connectionState(int status)
        {
            switch (status)
            {
            case BluetoothProfile.STATE_CONNECTED:
                return "Connected";
            case BluetoothProfile.STATE_DISCONNECTED:
                return "Disconnected";
            case BluetoothProfile.STATE_CONNECTING:
                return "Connecting";
            case BluetoothProfile.STATE_DISCONNECTING:
                return "Disconnecting";
            default:
                return String.valueOf(status);
            }
        }
    };

    /*
     * We have a Handler to process event results on the main thread
     */
    private static final int MSG_PROGRESS = 201;
    private static final int MSG_DISMISS = 202;
    private static final int MSG_CLEAR = 301;
    private Handler mHandler = new Handler()
    {
        @SuppressLint("NewApi")
        @Override
        public void handleMessage(Message msg)
        {
            BluetoothGattCharacteristic characteristic;
            switch (msg.what)
            {
            case MSG_PROGRESS:
                tvMessage.setText((String) msg.obj);
                break;
            case MSG_DISMISS:
                tvMessage.setText("Service Enabled");
                break;
            case MSG_CLEAR:
                tvMessage.setText("");
                break;
            }
        }
    };
}

In my activity, first of all I am scanning all the available devices & preparing ListView. On clicking on list item I connect to that particular device. When device's status become connected then I discover services. I have UUIDs of the device's service & its characteristics. But I am not sure how to write to any particular characteristics or enable or read data from it. Although I have tried this thing but I don't see any success.

If any one has any idea about it, so please help me.

解决方案

Had a device which required me to use

descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE)

instead of

descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)

as explained in this question

Android BLE API: GATT Notification not received

这篇关于什么是获得蓝牙低功耗(BLE)设备通知的步骤是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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