Intereting Posts
Наследование AppCompat 22.1.1 Диалог colorAccent от темы приложения не работает Размещение фонового изображения Android Studio импортирует существующие модульные тесты «Невозможно найти информацию об оборудовании» Разработка кросс-платформенного мобильного приложения Кинжал 2 примера Qt мобильное видеовызов Как получить доступ к камере на телефонах Android? Android получает значение выбранного переключателя Gson и Active Android: Попытка сериализации java.lang.Class. Забыл зарегистрировать адаптер типа? Как создать намерение, открывающее активность журнала вызовов? Добавление настроек в Настройки Fatal Exception: java.lang.NoClassDefFoundError: android.support.v7.app.AppCompatDelegateImplV23 Изменить цвет текста элемента навигации Как исправить проблемы с видимостью ссылок на html.fromHtml (в ICS и Honeycomb)? Почему приложение на Android не должно быть написано на C / C ++, потому что вы просто предпочитаете программировать на C / C ++?

Каковы шаги для получения уведомления устройством Bluetooth Low Energy (BLE)?

Я работаю над приложением Bluetooth Low Energy (BLE). У меня есть устройство BLE (шкала), которое измеряет вес. Я могу подключиться к этому устройству. Но я не понимаю, как читать данные (значение веса).

Я хочу знать, подключено ли мое приложение к любому устройству BLE, и каковы шаги для получения уведомления устройством для получения обновленных данных.

Хорошо, следуя за моей деятельностью, которую я использую.

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; } } }; } 

В своей деятельности, в первую очередь, я просматриваю все доступные устройства и готовлю ListView. При нажатии на элемент списка я подключаюсь к этому конкретному устройству. Когда статус устройства подключается, я обнаруживаю службы. У меня есть UUIDs службы устройства и его характеристики. Но я не уверен, как писать какие-либо конкретные характеристики или разрешать или читать данные из него. Хотя я пробовал эту вещь, но я не вижу никакого успеха.

Если у кого-нибудь есть представление об этом, пожалуйста, помогите мне.

Solutions Collecting From Web of "Каковы шаги для получения уведомления устройством Bluetooth Low Energy (BLE)?"

Было устройство, которое требовало от меня использования

 descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE) 

вместо

 descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE) 

Как объясняется в этом вопросе

Android BLE API: уведомление GATT не получено

Обратитесь к исходному коду примера приложения «bluetoothlegatt», представленному на портале разработчика.

Пример службы: http://developer.android.com/samples/BluetoothLeGatt/src/com.example.android.bluetoothlegatt/BluetoothLeService.html

Использование сервиса: http://developer.android.com/samples/BluetoothLeGatt/src/com.example.android.bluetoothlegatt/DeviceControlActivity.html

Этот пример содержит характеристики с свойствами чтения и уведомления. Поэтому вы определенно найдете свое решение. Перейдите в раздел со следующим кодом: (Вы можете понять это)

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

Вы должны различать значение, это уведомление или указание, и установить соответствующее значение с помощью дескриптора.setValue. Если вы ошиблись, вы не получите значение.

Этот работает для меня:

Чтобы уведомить мастер-устройство о том, что какая-то характеристика изменяется, вызовите эту функцию на вашем периферийном устройстве:

 private BluetoothGattServer server; //init.... //on BluetoothGattServerCallback... //call this after change the characteristic server.notifyCharacteristicChanged(device, characteristic, false); 

В главном устройстве: включить setCharacteristicNotification после обнаружения службы:

 @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { super.onServicesDiscovered(gatt, status); services = mGatt.getServices(); for(BluetoothGattService service : services){ if( service.getUuid().equals(SERVICE_UUID)) { characteristicData = service.getCharacteristic(CHAR_UUID); for (BluetoothGattDescriptor descriptor : characteristicData.getDescriptors()) { descriptor.setValue( BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); mGatt.writeDescriptor(descriptor); } gatt.setCharacteristicNotification(characteristicData, true); } } if (dialog.isShowing()){ mHandler.post(new Runnable() { @Override public void run() { dialog.hide(); } }); } } 

Теперь вы можете проверить, что ваше характеристическое значение – это изменение, например функция onCharacteristicRead:

 @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { Log.i("onCharacteristicRead", characteristic.toString()); byte[] value=characteristic.getValue(); String v = new String(value); Log.i("onCharacteristicRead", "Value: " + v); }