我正在使用BLE开发心率检测代码。我能够连接到gatt服务器,甚至广播更新。但我似乎无法发现任何心率。我错过了什么吗?
这是我的代码。
public class BleActivity extends Activity {
public final static String ACTION_GATT_CONNECTED =
"com.example.bluetooth.le.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED =
"com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED =
"com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE =
"com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA =
"com.example.bluetooth.le.EXTRA_DATA";
private BluetoothDevicesAdapter bluetoothDevicesAdapter;
private BluetoothAdapter mBluetoothAdapter;
private Handler mHandler = new Handler();
private static final long SCAN_PERIOD = 5000;
private ProgressDialog progressDialog;
private BluetoothGatt mGatt;
@Bind(R.id.bleDeviceListView)
ListView listView;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ble);
ButterKnife.bind(this);
bluetoothDevicesAdapter = new BluetoothDevicesAdapter(getApplicationContext());
listView.setAdapter(bluetoothDevicesAdapter);
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
}
@OnClick(R.id.scanButton)
public void onScanClicked() {
scanLeDevice();
}
@OnItemClick(R.id.bleDeviceListView)
public void onItemClicked(int position) {
connectToDevice((BluetoothDevice) bluetoothDevicesAdapter.getItem(position));
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mGattUpdateReceiver);
}
@Override
protected void onResume() {
super.onResume();
registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
//CONFIRMS IF BLUETOOTH IS ENABLED
if (!mBluetoothAdapter.isEnabled()) {
if (!mBluetoothAdapter.isEnabled()) {
GenericDialogBox.EnableBluetoothBox(BleActivity.this, "Notice", "This app requires bluetooth. Enable?", mBluetoothAdapter);
}
}
}
private void scanLeDevice() {
bluetoothDevicesAdapter.clear();
bluetoothDevicesAdapter.notifyDataSetChanged();
progressDialog = new ProgressDialog(BleActivity.this);
progressDialog.setCancelable(false);
progressDialog.setMessage("Scanning Devices");
progressDialog.show();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mBluetoothAdapter.stopLeScan(leScanCallback);
progressDialog.hide();
mBluetoothAdapter.stopLeScan(leScanCallback);
progressDialog.dismiss();
progressDialog = null;
}
}, SCAN_PERIOD);
mBluetoothAdapter.startLeScan(leScanCallback);
}
private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
bluetoothDevicesAdapter.addDevice(device);
bluetoothDevicesAdapter.notifyDataSetChanged();
}
});
}
};
public void connectToDevice(BluetoothDevice device) {
if (mGatt == null) {
mGatt = device.connectGatt(this, false, btleGattCallback);
progressDialog = new ProgressDialog(BleActivity.this);
progressDialog.setMessage("Connecting to Gatt Server.");
progressDialog.setCancelable(false);
progressDialog.show();
}
}
private final BluetoothGattCallback btleGattCallback = new BluetoothGattCallback() {
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
@Override
public void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) {
String intentAction;
Log.e("onConnectionStateChange", "Status: " + status);
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
intentAction = ACTION_GATT_CONNECTED;
Log.e("gattCallback", "STATE_CONNECTED");
progressDialog.dismiss();
progressDialog = null;
broadcastUpdate(intentAction);
mGatt.discoverServices();
break;
case BluetoothProfile.STATE_DISCONNECTED:
intentAction = ACTION_GATT_DISCONNECTED;
Log.e("gattCallback", "STATE_DISCONNECTED");
BluetoothDevice mDevice = gatt.getDevice();
mGatt = null;
broadcastUpdate(intentAction);
break;
default:
Log.e("gattCallback", "STATE_OTHER");
}
}
@Override
public void onServicesDiscovered(final BluetoothGatt gatt, final int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
List<BluetoothGattService> services = gatt.getServices();
BluetoothGattCharacteristic therm_char;
for (int i = 0; i < services.size(); i++) {
therm_char = services.get(i).getCharacteristics().get(0);
if(therm_char.getUuid().equals(SampleGattAttributes.HEART_RATE_MEASUREMENT)){
gatt.setCharacteristicNotification(therm_char, true);
BluetoothGattDescriptor descriptor = therm_char.getDescriptor(
UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mGatt.writeDescriptor(descriptor);
}
}
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
Log.e("gattCallback", "Service discovered" + gatt.getServices() + " Status: " + status);
} else {
Log.e("BluetoothServices: ", "onServicesDiscovered received: " + status);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
};
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
// This is special handling for the Heart Rate Measurement profile. Data
// parsing is carried out as per profile specifications.
if (UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT).equals(characteristic.getUuid())) {
int flag = characteristic.getProperties();
int format = -1;
if ((flag & 0x01) != 0) {
format = BluetoothGattCharacteristic.FORMAT_UINT16;
Log.d("Bluetooth Service: ", "Heart rate format UINT16.");
} else {
format = BluetoothGattCharacteristic.FORMAT_UINT8;
Log.d("Bluetooth Service: ", "Heart rate format UINT8.");
}
final int heartRate = characteristic.getIntValue(format, 1);
Log.d("Bluetooth Service: ", String.format("Received heart rate: %d", heartRate));
intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));
} else {
// For all other profiles, writes the data formatted in HEX.
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for(byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
intent.putExtra(EXTRA_DATA, new String(data) + "\n" +
stringBuilder.toString());
}
}
sendBroadcast(intent);
}
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (ACTION_GATT_CONNECTED.equals(action)) {
Toast.makeText(getApplicationContext(), "Connected to Service.", Toast.LENGTH_SHORT).show();
invalidateOptionsMenu();
} else if (ACTION_GATT_DISCONNECTED.equals(action)) {
Toast.makeText(getApplicationContext(), "Connected to Service.", Toast.LENGTH_SHORT).show();
} else if (ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
//Update Connection State
} else if (ACTION_DATA_AVAILABLE.equals(action)) {
Toast.makeText(getApplicationContext(), intent.getStringExtra(EXTRA_DATA), Toast.LENGTH_SHORT).show();
}
}
};
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_GATT_CONNECTED);
intentFilter.addAction(ACTION_GATT_DISCONNECTED);
intentFilter.addAction(ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(ACTION_DATA_AVAILABLE);
return intentFilter;
}
这是sampleAttributes类。
public class SampleGattAttributes {
private static HashMap<String, String> attributes = new HashMap();
public static String HEART_RATE_MEASUREMENT = "00002a37-0000-1000-8000-00805f9b34fb";
public static String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";
static {
// Sample Services.
attributes.put("0000180d-0000-1000-8000-00805f9b34fb", "Heart Rate Service");
attributes.put("0000180a-0000-1000-8000-00805f9b34fb", "Device Information Service");
// Sample Characteristics.
attributes.put(HEART_RATE_MEASUREMENT, "Heart Rate Measurement");
attributes.put("00002a29-0000-1000-8000-00805f9b34fb", "Manufacturer Name String");
}
public static String lookup(String uuid, String defaultName) {
String name = attributes.get(uuid);
return name == null ? defaultName : name;
}
}
如果设备不时搜索任何更改,还有一种方法可以记录吗?
谢谢!