Anonymous
Die Android -App kann keine BLE -Benachrichtigungsdaten empfangen
Post
by Anonymous » 09 Apr 2025, 04:16
Ich habe zwei Android -Geräte. Mein Android -Telefon und RK Motherboard. Installieren Sie die App in meinem Android -Telefon und können das BLE -Gerät anschließen und Benachrichtigungsdaten vom BLE -Gerät erhalten. Wenn ich die App mit der RK -Karte installiere, verbindet sie das BLE -Gerät, aber es können keine Benachrichtigungsdaten empfangen. Ich habe die Nrf Connect -App auf dem RK -Motherboard getestet und es empfängt Benachrichtigungsdaten.
Kann jemand helfen, warum?
Code: Select all
public class BluetoothHelper {
private BluetoothAdapter bluetoothAdapter = null;
private BluetoothLeScanner bluetoothLeScanner = null;
private OnScanResultListener onScanResultListener =null;
private BluetoothHelper() {
}
private static volatile BluetoothHelper sInstance;
public static BluetoothHelper getInstance() {
if(sInstance == null){
synchronized (BluetoothHelper.class) {
if (sInstance == null) {
sInstance = new BluetoothHelper();
}
}
}
return sInstance;
}
public void init(Context mContext) {
BluetoothManager bluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
if(bluetoothAdapter != null){
bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
}
}
public void initPermission(Context mContext,int requestCode) {
List permissionsNeeded = getPermissionsStrings();
List permissionsToRequest = new ArrayList();
for (String permission : permissionsNeeded) {
if (ContextCompat.checkSelfPermission(mContext, permission) != PackageManager.PERMISSION_GRANTED) {
permissionsToRequest.add(permission);
}
}
if (!permissionsToRequest.isEmpty()) {
ActivityCompat.requestPermissions((Activity) mContext,
permissionsToRequest.toArray(new String[0]),
requestCode);
} else {
Log.d("TAG", "BluetoothHelper -> permission ok");
}
}
@NonNull
private static List getPermissionsStrings() {
List permissionsNeeded = new ArrayList();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
permissionsNeeded.add(Manifest.permission.BLUETOOTH_SCAN);
permissionsNeeded.add(Manifest.permission.BLUETOOTH_ADVERTISE);
permissionsNeeded.add(Manifest.permission.BLUETOOTH_CONNECT);
} else {
permissionsNeeded.add(Manifest.permission.ACCESS_COARSE_LOCATION);
permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
return permissionsNeeded;
}
public boolean isBluetoothEnable() {
if (bluetoothAdapter == null) {
return false;
}
return bluetoothAdapter.isEnabled();
}
@SuppressLint("MissingPermission")
public void startScanBle() {
if(bluetoothLeScanner != null){
bluetoothLeScanner.startScan(scanCallback);
}
}
@SuppressLint("MissingPermission")
public void stopScanBle() {
if(bluetoothLeScanner != null){
bluetoothLeScanner.stopScan(scanCallback);
}
}
public void setOnScanResultListener(OnScanResultListener onScanResultListener) {
this.onScanResultListener = onScanResultListener;
}
public interface OnScanResultListener{
void onScanResult(BluetoothDevice device);
void onScanFailed();
}
private final ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
BluetoothDevice device = result.getDevice();
if(onScanResultListener != null){
onScanResultListener.onScanResult(device);
}
}
@Override
public void onBatchScanResults(List results) {
super.onBatchScanResults(results);
}
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
if(onScanResultListener != null){
onScanResultListener.onScanFailed();
}
}
};
}
< /code>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final int REQUEST_CODE_BLUETOOTH = 0x100;
private ActivityMainBinding binding;
private BluetoothHelper bluetoothHelper = null;
private SimpleAdapter simpleAdapter = null;
private final List devicesList = new ArrayList();
private final List mDeviceList = new ArrayList();
private BluetoothGatt bluetoothGatt = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
ViewCompat.setOnApplyWindowInsetsListener(binding.main, (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
bluetoothHelper = BluetoothHelper.getInstance();
bluetoothHelper.init(this);
bluetoothHelper.setOnScanResultListener(onScanResultListener);
bluetoothHelper.initPermission(this, REQUEST_CODE_BLUETOOTH);
initView();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_BLUETOOTH) {
boolean allPermissionsGranted = true;
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
allPermissionsGranted = false;
break;
}
}
if (allPermissionsGranted) {
Log.d(TAG, "permission ok");
} else {
boolean shouldShowRationale = false;
for (String permission : permissions) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
shouldShowRationale = true;
break;
}
}
if (shouldShowRationale) {
showPermissionDeniedDialog();
} else {
showErrorMessage();
}
}
}
}
private void showPermissionDeniedDialog() {
new AlertDialog.Builder(this)
.setTitle("Permission denied")
.setMessage("You have permanently denied the necessary permissions, please go to the settings page to grant them manually.")
.setPositiveButton("Settings", (dialog, which) -> {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
})
.setNegativeButton("Cancel", null)
.show();
}
private void showErrorMessage() {
new AlertDialog.Builder(this)
.setTitle("Error")
.setMessage("Permission denied, please grant permission to continue using the Bluetooth feature")
.setPositiveButton("Confirm", null)
.show();
}
private void initView() {
binding.scan.setOnClickListener(v -> {
boolean isEnable = bluetoothHelper.isBluetoothEnable();
if (isEnable) {
bluetoothHelper.startScanBle();
}
});
simpleAdapter = new SimpleAdapter(
this,
devicesList,
android.R.layout.simple_list_item_2,
new String[]{"title", "subtitle"},
new int[]{android.R.id.text1, android.R.id.text2}
);
binding.showBleDevices.setAdapter(simpleAdapter);
binding.showBleDevices.setOnItemClickListener((parent, view, position, id) -> {
Map map = devicesList.get(position);
String address = map.get("subtitle");
Log.d(TAG, "onItemClick -> position:" + position + ", address:" + address);
for (BluetoothDevice device : mDeviceList) {
if (address != null) {
if (address.equals(device.getAddress())) {
if (bluetoothHelper != null) {
bluetoothHelper.stopScanBle();
}
Log.d(TAG, "onItemClick -> name:" + device.getName());
connectDevice(device);
break;
}
}
}
});
}
private final BluetoothHelper.OnScanResultListener onScanResultListener =
new BluetoothHelper.OnScanResultListener() {
@SuppressLint("MissingPermission")
@Override
public void onScanResult(BluetoothDevice device) {
if (device.getName() != null) {
boolean existsByAddress = mDeviceList.stream()
.anyMatch(device1 -> device1.getAddress().equals(device.getAddress()));
if (!existsByAddress) {
mDeviceList.add(device);
devicesList.clear();
for (BluetoothDevice bluetoothDevice : mDeviceList) {
devicesList.add(new HashMap() {{
put("title", bluetoothDevice.getName());
put("subtitle", bluetoothDevice.getAddress());
}});
}
}
simpleAdapter.notifyDataSetChanged();
}
}
@Override
public void onScanFailed() {
}
};
protected void onPause() {
super.onPause();
if (bluetoothHelper != null) {
bluetoothHelper.stopScanBle();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (bluetoothHelper != null) {
bluetoothHelper.stopScanBle();
}
if (bluetoothGatt != null) {
bluetoothGatt.disconnect();
bluetoothGatt.close();
}
}
private void connectDevice(BluetoothDevice device) {
if (bluetoothGatt != null) {
bluetoothGatt.disconnect();
bluetoothGatt.close();
bluetoothGatt = null;
}
bluetoothGatt = device.connectGatt(this, false, new BluetoothGattCallback() {
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
startCommunicationWithDevice(gatt);
}
}
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if(status == BluetoothGatt.GATT_SUCCESS) {
String message;
if (newState == BluetoothGatt.STATE_CONNECTED) {
message = "Connect success";
gatt.discoverServices();
} else if (newState == BluetoothGatt.STATE_DISCONNECTED) {
message = "disconnect";
} else {
message = "";
}
runOnUiThread(() -> Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show());
}else {
Log.i(TAG, "onConnectionStateChange----: " + "Connection status is abnormal:" + status);
}
}
@Override
public void onCharacteristicRead(@NonNull BluetoothGatt gatt, @NonNull BluetoothGattCharacteristic characteristic, @NonNull byte[] value, int status) {
super.onCharacteristicRead(gatt, characteristic, value, status);
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
}
@Override
public void onCharacteristicChanged(@NonNull BluetoothGatt gatt, @NonNull BluetoothGattCharacteristic characteristic, @NonNull byte[] value) {
super.onCharacteristicChanged(gatt, characteristic, value);
Log.i(TAG, "Characteristic changed: " + bytesToHexHasSpace(characteristic.getValue()));
runOnUiThread(() -> {
binding.bleOriginalData.setText(bytesToHexHasSpace(characteristic.getValue()));
});
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status);
}
});
}
private void startCommunicationWithDevice(BluetoothGatt gatt) {
BluetoothGattCharacteristic characteristic =
gatt.getService(UUID.fromString("00001826-0000-1000-8000-00805f9b34fb"))
.getCharacteristic(UUID.fromString("00002ace-0000-1000-8000-00805f9b34fb")); //cross trainer data
setCharacteristicNotificationInternal(gatt, characteristic, true);
}
private void setCharacteristicNotificationInternal(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, boolean enabled){
if (characteristic == null){
Log.e(TAG, "characteristic is null");
return;
}
gatt.setCharacteristicNotification(characteristic, enabled);
//If the number of descriptors in the eigenvalue of the notification is greater than zero
List descriptors = characteristic.getDescriptors();
if (!descriptors.isEmpty()) {
//Filter descriptors based on the uuid of the descriptor
for(BluetoothGattDescriptor descriptor : descriptors){
if (descriptor != null) {
//Write the description value
if((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0){
descriptor.setValue(enabled?BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE:BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
}else if((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0){
descriptor.setValue(enabled?BluetoothGattDescriptor.ENABLE_INDICATION_VALUE:BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
}
gatt.writeDescriptor(descriptor);
Log.d(TAG, "setCharacteristicNotificationInternal is "+enabled);
}
}
}
}
private String bytesToHexHasSpace(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X ", b));
}
return sb.toString();
}
}
< /code>
undroidManifest.xml
1744165008
Anonymous
Ich habe zwei Android -Geräte. Mein Android -Telefon und RK Motherboard. Installieren Sie die App in meinem Android -Telefon und können das BLE -Gerät anschließen und Benachrichtigungsdaten vom BLE -Gerät erhalten. Wenn ich die App mit der RK -Karte installiere, verbindet sie das BLE -Gerät, aber es können keine Benachrichtigungsdaten empfangen. Ich habe die Nrf Connect -App auf dem RK -Motherboard getestet und es empfängt Benachrichtigungsdaten. Kann jemand helfen, warum?[code]public class BluetoothHelper { private BluetoothAdapter bluetoothAdapter = null; private BluetoothLeScanner bluetoothLeScanner = null; private OnScanResultListener onScanResultListener =null; private BluetoothHelper() { } private static volatile BluetoothHelper sInstance; public static BluetoothHelper getInstance() { if(sInstance == null){ synchronized (BluetoothHelper.class) { if (sInstance == null) { sInstance = new BluetoothHelper(); } } } return sInstance; } public void init(Context mContext) { BluetoothManager bluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); if(bluetoothAdapter != null){ bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); } } public void initPermission(Context mContext,int requestCode) { List permissionsNeeded = getPermissionsStrings(); List permissionsToRequest = new ArrayList(); for (String permission : permissionsNeeded) { if (ContextCompat.checkSelfPermission(mContext, permission) != PackageManager.PERMISSION_GRANTED) { permissionsToRequest.add(permission); } } if (!permissionsToRequest.isEmpty()) { ActivityCompat.requestPermissions((Activity) mContext, permissionsToRequest.toArray(new String[0]), requestCode); } else { Log.d("TAG", "BluetoothHelper -> permission ok"); } } @NonNull private static List getPermissionsStrings() { List permissionsNeeded = new ArrayList(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { permissionsNeeded.add(Manifest.permission.BLUETOOTH_SCAN); permissionsNeeded.add(Manifest.permission.BLUETOOTH_ADVERTISE); permissionsNeeded.add(Manifest.permission.BLUETOOTH_CONNECT); } else { permissionsNeeded.add(Manifest.permission.ACCESS_COARSE_LOCATION); permissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION); } return permissionsNeeded; } public boolean isBluetoothEnable() { if (bluetoothAdapter == null) { return false; } return bluetoothAdapter.isEnabled(); } @SuppressLint("MissingPermission") public void startScanBle() { if(bluetoothLeScanner != null){ bluetoothLeScanner.startScan(scanCallback); } } @SuppressLint("MissingPermission") public void stopScanBle() { if(bluetoothLeScanner != null){ bluetoothLeScanner.stopScan(scanCallback); } } public void setOnScanResultListener(OnScanResultListener onScanResultListener) { this.onScanResultListener = onScanResultListener; } public interface OnScanResultListener{ void onScanResult(BluetoothDevice device); void onScanFailed(); } private final ScanCallback scanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); BluetoothDevice device = result.getDevice(); if(onScanResultListener != null){ onScanResultListener.onScanResult(device); } } @Override public void onBatchScanResults(List results) { super.onBatchScanResults(results); } @Override public void onScanFailed(int errorCode) { super.onScanFailed(errorCode); if(onScanResultListener != null){ onScanResultListener.onScanFailed(); } } }; } < /code> MainActivity.java public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private static final int REQUEST_CODE_BLUETOOTH = 0x100; private ActivityMainBinding binding; private BluetoothHelper bluetoothHelper = null; private SimpleAdapter simpleAdapter = null; private final List devicesList = new ArrayList(); private final List mDeviceList = new ArrayList(); private BluetoothGatt bluetoothGatt = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); ViewCompat.setOnApplyWindowInsetsListener(binding.main, (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); bluetoothHelper = BluetoothHelper.getInstance(); bluetoothHelper.init(this); bluetoothHelper.setOnScanResultListener(onScanResultListener); bluetoothHelper.initPermission(this, REQUEST_CODE_BLUETOOTH); initView(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE_BLUETOOTH) { boolean allPermissionsGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allPermissionsGranted = false; break; } } if (allPermissionsGranted) { Log.d(TAG, "permission ok"); } else { boolean shouldShowRationale = false; for (String permission : permissions) { if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { shouldShowRationale = true; break; } } if (shouldShowRationale) { showPermissionDeniedDialog(); } else { showErrorMessage(); } } } } private void showPermissionDeniedDialog() { new AlertDialog.Builder(this) .setTitle("Permission denied") .setMessage("You have permanently denied the necessary permissions, please go to the settings page to grant them manually.") .setPositiveButton("Settings", (dialog, which) -> { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivity(intent); }) .setNegativeButton("Cancel", null) .show(); } private void showErrorMessage() { new AlertDialog.Builder(this) .setTitle("Error") .setMessage("Permission denied, please grant permission to continue using the Bluetooth feature") .setPositiveButton("Confirm", null) .show(); } private void initView() { binding.scan.setOnClickListener(v -> { boolean isEnable = bluetoothHelper.isBluetoothEnable(); if (isEnable) { bluetoothHelper.startScanBle(); } }); simpleAdapter = new SimpleAdapter( this, devicesList, android.R.layout.simple_list_item_2, new String[]{"title", "subtitle"}, new int[]{android.R.id.text1, android.R.id.text2} ); binding.showBleDevices.setAdapter(simpleAdapter); binding.showBleDevices.setOnItemClickListener((parent, view, position, id) -> { Map map = devicesList.get(position); String address = map.get("subtitle"); Log.d(TAG, "onItemClick -> position:" + position + ", address:" + address); for (BluetoothDevice device : mDeviceList) { if (address != null) { if (address.equals(device.getAddress())) { if (bluetoothHelper != null) { bluetoothHelper.stopScanBle(); } Log.d(TAG, "onItemClick -> name:" + device.getName()); connectDevice(device); break; } } } }); } private final BluetoothHelper.OnScanResultListener onScanResultListener = new BluetoothHelper.OnScanResultListener() { @SuppressLint("MissingPermission") @Override public void onScanResult(BluetoothDevice device) { if (device.getName() != null) { boolean existsByAddress = mDeviceList.stream() .anyMatch(device1 -> device1.getAddress().equals(device.getAddress())); if (!existsByAddress) { mDeviceList.add(device); devicesList.clear(); for (BluetoothDevice bluetoothDevice : mDeviceList) { devicesList.add(new HashMap() {{ put("title", bluetoothDevice.getName()); put("subtitle", bluetoothDevice.getAddress()); }}); } } simpleAdapter.notifyDataSetChanged(); } } @Override public void onScanFailed() { } }; protected void onPause() { super.onPause(); if (bluetoothHelper != null) { bluetoothHelper.stopScanBle(); } } @Override protected void onDestroy() { super.onDestroy(); if (bluetoothHelper != null) { bluetoothHelper.stopScanBle(); } if (bluetoothGatt != null) { bluetoothGatt.disconnect(); bluetoothGatt.close(); } } private void connectDevice(BluetoothDevice device) { if (bluetoothGatt != null) { bluetoothGatt.disconnect(); bluetoothGatt.close(); bluetoothGatt = null; } bluetoothGatt = device.connectGatt(this, false, new BluetoothGattCallback() { @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { super.onServicesDiscovered(gatt, status); if (status == BluetoothGatt.GATT_SUCCESS) { startCommunicationWithDevice(gatt); } } @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { super.onConnectionStateChange(gatt, status, newState); if(status == BluetoothGatt.GATT_SUCCESS) { String message; if (newState == BluetoothGatt.STATE_CONNECTED) { message = "Connect success"; gatt.discoverServices(); } else if (newState == BluetoothGatt.STATE_DISCONNECTED) { message = "disconnect"; } else { message = ""; } runOnUiThread(() -> Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show()); }else { Log.i(TAG, "onConnectionStateChange----: " + "Connection status is abnormal:" + status); } } @Override public void onCharacteristicRead(@NonNull BluetoothGatt gatt, @NonNull BluetoothGattCharacteristic characteristic, @NonNull byte[] value, int status) { super.onCharacteristicRead(gatt, characteristic, value, status); } @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicWrite(gatt, characteristic, status); } @Override public void onCharacteristicChanged(@NonNull BluetoothGatt gatt, @NonNull BluetoothGattCharacteristic characteristic, @NonNull byte[] value) { super.onCharacteristicChanged(gatt, characteristic, value); Log.i(TAG, "Characteristic changed: " + bytesToHexHasSpace(characteristic.getValue())); runOnUiThread(() -> { binding.bleOriginalData.setText(bytesToHexHasSpace(characteristic.getValue())); }); } @Override public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { super.onDescriptorWrite(gatt, descriptor, status); } }); } private void startCommunicationWithDevice(BluetoothGatt gatt) { BluetoothGattCharacteristic characteristic = gatt.getService(UUID.fromString("00001826-0000-1000-8000-00805f9b34fb")) .getCharacteristic(UUID.fromString("00002ace-0000-1000-8000-00805f9b34fb")); //cross trainer data setCharacteristicNotificationInternal(gatt, characteristic, true); } private void setCharacteristicNotificationInternal(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, boolean enabled){ if (characteristic == null){ Log.e(TAG, "characteristic is null"); return; } gatt.setCharacteristicNotification(characteristic, enabled); //If the number of descriptors in the eigenvalue of the notification is greater than zero List descriptors = characteristic.getDescriptors(); if (!descriptors.isEmpty()) { //Filter descriptors based on the uuid of the descriptor for(BluetoothGattDescriptor descriptor : descriptors){ if (descriptor != null) { //Write the description value if((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0){ descriptor.setValue(enabled?BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE:BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); }else if((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_INDICATE) != 0){ descriptor.setValue(enabled?BluetoothGattDescriptor.ENABLE_INDICATION_VALUE:BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE); } gatt.writeDescriptor(descriptor); Log.d(TAG, "setCharacteristicNotificationInternal is "+enabled); } } } } private String bytesToHexHasSpace(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02X ", b)); } return sb.toString(); } } < /code> undroidManifest.xml [/code]