Я студент, работающий с BLE, и я не очень хорошо владею английским sh, поэтому, пожалуйста, разберитесь с этим с помощью переводчика Google. Поскольку уведомление BLE не работает во время работы, трудно прикрепить источник, поэтому, пожалуйста, помогите.
boolean success4 = mBluetoothGatt.writeDescriptor(descriptor);
ложно, но я не знаю почему.
// Debugging
private static final String TAG = "BleManager";
// Constants that indicate the current connection state
public static final int STATE_ERROR = -1;
public static final int STATE_NONE = 0; // Initialized
public static final int STATE_IDLE = 1; // Not connected
public static final int STATE_SCANNING = 2; // Scanning
public static final int STATE_CONNECTING = 13; // Connecting
public static final int STATE_CONNECTED = 16; // Connected
// Message types sent from the BluetoothManager to Handler
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
public static final long SCAN_PERIOD = 10000; // Stops scanning after a pre-defined scan period.
public static final long SCAN_INTERVAL = 5 * 60 * 1000;
// System, Management
private static Context mContext = null;
Handler mHandler;
private boolean connect = false;
// Bluetooth
private BluetoothAdapter mBluetoothAdapter;
private BluetoothManager mBluetoothManager;
private BluetoothGattCharacteristic mcharacteristic;
private ArrayList<BluetoothDevice> mDeviceList = new ArrayList<BluetoothDevice>();
private BluetoothDevice mDefaultDevice = null;
private BluetoothGatt mBluetoothGatt = null;
private ArrayList<BluetoothGattService> mGattServices
= new ArrayList<BluetoothGattService>();
private BluetoothGattService mDefaultService = null;
private ArrayList<BluetoothGattCharacteristic> mGattCharacteristics
= new ArrayList<BluetoothGattCharacteristic>();
private ArrayList<BluetoothGattCharacteristic> mWritableCharacteristics
= new ArrayList<BluetoothGattCharacteristic>();
private BluetoothGattCharacteristic mDefaultChar = null;
// Parameters
private int mState = -1;
private void BleManager() {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = mBluetoothManager.getAdapter();
//mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mContext = this;
if (mContext == null) {return;}
else
{
scanLeDevice(true);
}
}
public synchronized void finalize() {
// Make sure we're not doing discovery anymore
if (mBluetoothAdapter != null) {
mState = STATE_IDLE;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
disconnect();
}
mDefaultDevice = null;
mBluetoothGatt = null;
mDefaultService = null;
mGattServices.clear();
mGattCharacteristics.clear();
mWritableCharacteristics.clear();
if (mContext == null)
return;
// Don't forget this!!
// Unregister broadcast listeners
// mContext.unregisterReceiver(mReceiver);
}
/*****************************************************
* Private methods
******************************************************/
/**
* This method extracts UUIDs from advertised data
* Because Android native code has bugs in parsing 128bit UUID
* use this method instead.
*/
private void stopScanning() {
if (mState < STATE_CONNECTING) {
mState = STATE_IDLE;
}
scanLeDevice(false);
//mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
/**
* Check services and looking for writable characteristics
*/
private int checkGattServices(List<BluetoothGattService> gattServices) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.e("# BluetoothAdapter", " not initialized");
return -1;
}
for (BluetoothGattService gattService : gattServices) {
// Default service info
Log.e("# GATT Service:", " " + gattService.getUuid().toString());
// Remember service
mGattServices.add(gattService);
// Extract characteristics
List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
// Remember characteristic
mGattCharacteristics.add(gattCharacteristic);
for (BluetoothGattDescriptor descriptor:gattCharacteristic.getDescriptors()){
Log.e("# GATT Char:", gattCharacteristic.getUuid().toString());
Log.e(TAG, "BluetoothGattDescriptor: " + descriptor.getUuid().toString());
}
boolean isWritable = isWritableCharacteristic(gattCharacteristic);
if (isWritable) {
mWritableCharacteristics.add(gattCharacteristic);
}
boolean isReadable = isReadableCharacteristic(gattCharacteristic);
if (isReadable) {
readCharacteristic(gattCharacteristic);
}
if (isNotificationCharacteristic(gattCharacteristic) && gattCharacteristic.getUuid().toString().equals("0000ffe1-0000-1000-8000-00805f9b34fb")) {
setCharacteristicNotification(gattCharacteristic, true);
if (gattCharacteristic.getUuid().toString().equals("0000ffe1-0000-1000-8000-00805f9b34fb")) {
Log.e("default", "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
mDefaultChar = gattCharacteristic;
Log.e("default", "////////////////////////////////////////////// " + mDefaultChar.getUuid().toString());
//break;
}
}
}
}
return mWritableCharacteristics.size();
}
private boolean isWritableCharacteristic(BluetoothGattCharacteristic chr) {
if (chr == null) return false;
final int charaProp = chr.getProperties();
if (((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE) |
(charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) > 0) {
Log.e("# Found writable", " characteristic");
return true;
} else {
Log.e("# Not writable", " characteristic");
return false;
}
}
private boolean isReadableCharacteristic(BluetoothGattCharacteristic chr) {
if (chr == null) return false;
final int charaProp = chr.getProperties();
if ((charaProp & BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
Log.e("# Found readable", " characteristic");
return true;
} else {
Log.e("# Not readable", " characteristic");
return false;
}
}
private boolean isNotificationCharacteristic(BluetoothGattCharacteristic chr) {
if (chr == null) return false;
final int charaProp = chr.getProperties();
if ((charaProp & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
Log.e("# Found notification", " characteristic");
return true;
} else {
Log.e("# Not notification", " characteristic");
return false;
}
}
/**
* Request a read on a given {@code BluetoothGattCharacteristic}. The read result is reported
* asynchronously through the {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)}
* callback.
*
* @param characteristic The characteristic to read from.
*/
public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.e("# BluetoothAdapter", " not initialized");
return;
}
mBluetoothGatt.readCharacteristic(characteristic);
}
/**
* Enables or disables notification on a give characteristic.
*
* @param characteristic Characteristic to act on.
* @param enabled If true, enable notification. False otherwise.
*/
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
boolean enabled) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.e("# BluetoothAdapter ", "not initialized");
return;
}
characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
boolean success1 = mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
//00002902-0000-1000-8000-00805f9b34fb
//public static String CLIENT_CHARACTERISTIC_CONFIG = "0000ffe1-0000-1000-8000-00805f9b34fb";
Log.e("info1",characteristic.getUuid().toString() + " // " + characteristic.getValue() + " // " + enabled + " // " + success1);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
Log.e("info2",characteristic.getUuid().toString() + " // " + characteristic.getValue() + " // " + enabled);
boolean success3 = descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
boolean success2 = descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
Log.e("info3",characteristic.getUuid().toString() + " // " + characteristic.getValue() + " // " + enabled + " // " + success3 + " // " + success2);
//boolean success5 = mBluetoothGatt.writeCharacteristic(characteristic);
boolean success4 = mBluetoothGatt.writeDescriptor(descriptor);
Log.e("info4",descriptor.getCharacteristic() + " // " + descriptor.getValue() + " // " + descriptor.getPermissions() + " // " + descriptor.getUuid() + " // " + enabled + " // " + success4);
//mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
}
/*****************************************************
* Public methods
******************************************************/
public int getState() {
return mState;
}
private void scanLeDevice(final boolean enable) {
mHandler = new Handler();
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if(device.getName() != null && device.getName().equals("AINTEL_MFD") && connect == false){
connect = true;
scanLeDevice(false);
Log.e("ScanDevice",device.getName() + " // " + device.getUuids() + " // " + device.getAddress() + " // " + rssi + " // " + scanRecord[0] + " // " + scanRecord[1]);
connectGatt(Vars.mContext,false, device);
}
}
});
}
};
public boolean scanLeDevice(final boolean enable, UUID[] uuid) {
boolean isScanStarted = false;
if (enable) {
if (mState == STATE_SCANNING)
return false;
if (mBluetoothAdapter.startLeScan(uuid, mLeScanCallback)) {
mState = STATE_SCANNING;
mDeviceList.clear();
// If you want to scan for only specific types of peripherals
// call below function instead
//startLeScan(UUID[], BluetoothAdapter.LeScanCallback);
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
stopScanning();
}
}, SCAN_PERIOD);
isScanStarted = true;
}
} else {
if (mState < STATE_CONNECTING) {
mState = STATE_IDLE;
}
stopScanning();
}
return isScanStarted;
}
public boolean connectGatt(Context c, boolean bAutoReconnect, BluetoothDevice device) {
if (c == null || device == null)
return false;
mGattServices.clear();
mGattCharacteristics.clear();
mWritableCharacteristics.clear();
mBluetoothGatt = device.connectGatt(c, bAutoReconnect, mGattCallback);
mDefaultDevice = device;
mState = STATE_CONNECTING;
return true;
}
public boolean connectGatt(Context c, boolean bAutoReconnect, String address) {
if (c == null || address == null)
return false;
if (mBluetoothGatt != null && mDefaultDevice != null
&& address.equals(mDefaultDevice.getAddress())) {
if (mBluetoothGatt.connect()) {
mState = STATE_CONNECTING;
return true;
}
}
BluetoothDevice device =
BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address);
if (device == null) {
Log.e("# Device not found. ", "Unable to connect.");
return false;
}
mGattServices.clear();
mGattCharacteristics.clear();
mWritableCharacteristics.clear();
mBluetoothGatt = device.connectGatt(c, bAutoReconnect, mGattCallback);
mDefaultDevice = device;
mState = STATE_CONNECTING;
return true;
}
/**
* Disconnects an existing connection or cancel a pending connection. The disconnection result
* is reported asynchronously through the
* {@code BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)}
* callback.
*/
public void disconnect() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.e("# BluetoothAdapter", " not initialized");
return;
}
mBluetoothGatt.disconnect();
}
public boolean write(BluetoothGattCharacteristic chr, byte[] data) {
if (mBluetoothGatt == null) {
Log.e(TAG, "# BluetoothGatt not initialized");
return false;
}
BluetoothGattCharacteristic writableChar = null;
if (chr == null) {
if (mDefaultChar == null) {
for (BluetoothGattCharacteristic bgc : mWritableCharacteristics) {
if (isWritableCharacteristic(bgc)) {
writableChar = bgc;
}
}
if (writableChar == null) {
Log.e(TAG, "# Write failed - No available characteristic");
return false;
}
} else {
if (isWritableCharacteristic(mDefaultChar)) {
Log.e("# Default", "is PROPERY_WRITE | PROPERTY_WRITE_NO_RESPONSE");
writableChar = mDefaultChar;
} else {
Log.e("# De ", "is not writable");
mDefaultChar = null;
return false;
}
}
} else {
if (isWritableCharacteristic(chr)) {
Log.e("# user ", "GattCharacteristic is PROPERY_WRITE | PROPERTY_WRITE_NO_RESPONSE");
writableChar = chr;
} else {
Log.e("# user ", "GattCharacteristic is not writable");
return false;
}
}
writableChar.setValue(data);
writableChar.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
mBluetoothGatt.writeCharacteristic(writableChar);
mDefaultChar = writableChar;
return true;
}
public void setWritableCharacteristic(BluetoothGattCharacteristic chr) {
mDefaultChar = chr;
}
public ArrayList<BluetoothGattService> getServices() {
return mGattServices;
}
public ArrayList<BluetoothGattCharacteristic> getCharacteristics() {
return mGattCharacteristics;
}
public ArrayList<BluetoothGattCharacteristic> getWritableCharacteristics() {
return mWritableCharacteristics;
}
/*****************************************************
* Handler, Listener, Timer, Sub classes
******************************************************/
// Various callback methods defined by the BLE API.
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
mState = STATE_CONNECTED;
Log.e(TAG, "# Connected to GATT server.");
gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
mState = STATE_IDLE;
Log.e(TAG, "# Disconnected from GATT server.");
mBluetoothGatt = null;
mGattServices.clear();
mDefaultService = null;
mGattCharacteristics.clear();
mWritableCharacteristics.clear();
mDefaultChar = null;
mDefaultDevice = null;
}
}
@Override
// New services discovered
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.e(TAG, "# New GATT service discovered.");
checkGattServices(gatt.getServices());
} else {
Log.e(TAG, "# onServicesDiscovered received: " + status);
}
}
@Override
// Result of a characteristic read operation
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
// We've received data from remote
Log.e(TAG, "# Read characteristic11111: " + String.format("%02X",characteristic.getValue()));
/*
* onCharacteristicChanged callback receives same message
*
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));
stringBuilder.append(data);
Log.e(TAG, stringBuilder.toString());
mHandler.obtainMessage(MESSAGE_READ, new String(data)).sendToTarget();
}
if(mDefaultChar == null && isWritableCharacteristic(characteristic)) {
mDefaultChar = characteristic;
}
*/
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
// We've received data from remote
byte[] newValue = characteristic.getValue();
Log.e(TAG, "# onCharacteristicChanged: " + String.format("%02X",newValue));
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));
stringBuilder.append(data);
Log.e(TAG, stringBuilder.toString());
}
if (mDefaultChar == null && isWritableCharacteristic(characteristic)) {
mDefaultChar = characteristic;
}
}
};
}