I am trying to connect to the i-phone via Android Bluetooth + BLE.
My goal is to read iOS notifications via Android Bluetooth + BLE.
I am able to show the i-phone Bluetooth in the android app and was able to connect to the i-phone but I am unable to found the Notification characteristic.
I got notification characteristic UUID from this link I am using Notification Source: UUID
Here is my BluetoothGattCallback:
public BluetoothGattCallback mCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (status == BluetoothGatt.GATT_SUCCESS) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
final BluetoothGatt mGatt = gatt;
Handler handler;
handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
#Override
public void run() {
mGatt.discoverServices();
}
});
//gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
try
{
Log.i("no_conn", "Connection unsuccessful with status"+status);
//mGatt.disconnect();
mGatt.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status != BluetoothGatt.GATT_SUCCESS) {
Log.i("Not success", "Device service discovery unsuccessful, status " + status);
return;
}
List<BluetoothGattService> matchingServices = gatt.getServices();
gatt.getService(UUID.fromString(SERVICE_STRING));
List<BluetoothGattCharacteristic> matchingCharacteristics = BluetoothUtils.findCharacteristics(gatt);
if (matchingCharacteristics.isEmpty()) {
Log.i("No characteristics", "Unable to find characteristics.");
showToast("No characteristic found");
return;
}else {
showToast("characteristic found");
}
}
};
Here is my findCharacteristics function:
public static List<BluetoothGattCharacteristic> findCharacteristics1(BluetoothGatt bluetoothGatt) {
List<BluetoothGattCharacteristic> matchingCharacteristics = new ArrayList<>();
List<BluetoothGattService> serviceList = bluetoothGatt.getServices();
BluetoothGattService service = null;
for (BluetoothGattService bgservice : serviceList) {
String serviceIdString = bgservice.getUuid()
.toString();
if (matchesServiceUuidString(serviceIdString)) {
service = bgservice;
}
}
if (service == null) {
Log.i("Null service", "Null service.");
return matchingCharacteristics;
}
return matchingCharacteristics;
}
Here I am matching with serviceIdString with the Notification Source: UUID.
Am I missing anything?
Related
android 10 for BLE Bluetooth connection is not connected , i will set all permission also but i get connection status 133 issues ,how to solve this issues ,here i declare the scanning and callback code ,please check and give your idea
but below android 10 version is working fine,only issues on android 10 device ,give an idea to solve the issues
private void scanLeDevice(final boolean enable) {
if (scanner == null) {
scanner = btAdapter.getBluetoothLeScanner();
}
if (scanCallback == null) setScanCallback(null);
scanner.startScan(createScanFilters(),createScanSettings(),scanCallback);
isScanning = true;
}
ScanCallback scanCallback = new ScanCallback() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onScanResult(int callbackType, #NonNull ScanResult scanResult) {
if (connectedDevices.containsKey(scanResult.getDevice().getAddress())) {
return;
}
if (connectingDevices.contains(scanResult.getDevice().getAddress())) {
// If we're already connected, forget it
//Timber.d("Denied connection. Already connecting to " + scanResult.getDevice().getAddress());
return;
}
if (connectionGovernor != null && !connectionGovernor.shouldConnectToAddress(scanResult.getDevice().getAddress())) {
// If the BLEConnectionGovernor says we should not bother connecting to this peer, don't
return;
}
final BluetoothDevice device = btAdapter.getRemoteDevice(scanResult.getDevice().getAddress());
if (device == null) {
Log.e(TAG, "Device not found. Unable to connect.");
}
connectingDevices.add(scanResult.getDevice().getAddress());
// connectToDevice(device);
Timber.d("Initiating connection to " + scanResult.getDevice().getAddress());
device.connectGatt(context, false, mGattCallback, BluetoothDevice.TRANSPORT_LE );
}
#Override
public void onScanFailed(int i) {
Timber.e("Scan failed with code " + i);
}
};
#NonNull
BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(#NonNull BluetoothGatt gatt, int status, int newState) {
synchronized (connectedDevices) {
// It appears that certain events (like disconnection) won't have a GATT_SUCCESS status
// even when they proceed as expected, at least with the Motorola bluetooth stack
if (status != BluetoothGatt.GATT_SUCCESS)
Timber.w("onConnectionStateChange with newState %d and non-success status %s", newState, gatt.getDevice().getAddress());
Set<BluetoothGattCharacteristic> characteristicSet;
switch (newState) {
case BluetoothProfile.STATE_DISCONNECTING:
Timber.d("Disconnecting from " + gatt.getDevice().getAddress());
characteristicSet = discoveredCharacteristics.get(gatt.getDevice().getAddress());
for (BluetoothGattCharacteristic characteristic : characteristicSet) {
if (notifyUUIDs.contains(characteristic.getUuid())) {
Timber.d("Attempting to unsubscribe on disconneting");
setIndictaionSubscription(gatt, characteristic, false);
}
}
discoveredCharacteristics.remove(gatt.getDevice().getAddress());
break;
case BluetoothProfile.STATE_DISCONNECTED:
Timber.d("Disconnected from " + gatt.getDevice().getAddress());
connectedDevices.remove(gatt.getDevice().getAddress());
connectingDevices.remove(gatt.getDevice().getAddress());
if (transportCallback != null)
transportCallback.identifierUpdated(BLETransportCallback.DeviceType.CENTRAL,
gatt.getDevice().getAddress(),
Transport.ConnectionStatus.DISCONNECTED,
null);
characteristicSet = discoveredCharacteristics.get(gatt.getDevice().getAddress());
if (characteristicSet != null) { // Have we handled unsubscription on DISCONNECTING?
for (BluetoothGattCharacteristic characteristic : characteristicSet) {
if (notifyUUIDs.contains(characteristic.getUuid())) {
Timber.d("Attempting to unsubscribe before disconnet");
setIndictaionSubscription(gatt, characteristic, false);
}
}
} else
if ( status != BluetoothGatt.GATT_SUCCESS ) {
if ( status == 133) {
refreshDeviceCache(gatt);
}
}
gatt.close(); discoveredCharacteristics.remove(gatt.getDevice().getAddress());
break;
case BluetoothProfile.STATE_CONNECTED:
boolean mtuSuccess = gatt.requestMtu(BLETransport.DEFAULT_MTU_BYTES);
Timber.d("Connected to %s. Requested MTU success %b", gatt.getDevice().getAddress(),
mtuSuccess);
break;
}
super.onConnectionStateChange(gatt, status, newState);
}
}
#Override
public void onMtuChanged(#NonNull BluetoothGatt gatt, int mtu, int status) {
Timber.d("Got MTU (%d bytes) for device %s. Was changed successfully: %b",
mtu,
gatt.getDevice().getAddress(),
status == BluetoothGatt.GATT_SUCCESS);
mtus.put(gatt.getDevice().getAddress(), mtu);
// TODO: Can we craft characteristics and avoid discovery step?
boolean discovering = gatt.discoverServices();
Timber.d("Discovering services : " + discovering);
}
#Override
public void onServicesDiscovered(#NonNull BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS)
Timber.d("Discovered services");
else
Timber.d("Discovered services appears unsuccessful with code " + status);
// TODO: Keep this here to examine characteristics
// eventually we should get rid of the discoverServices step
boolean foundService = false;
try {
List<BluetoothGattService> serviceList = gatt.getServices();
for (BluetoothGattService service : serviceList) {
if (service.getUuid().equals(serviceUUID)) {
Timber.d("Discovered Service");
foundService = true;
HashSet<BluetoothGattCharacteristic> characteristicSet = new HashSet<>();
characteristicSet.addAll(service.getCharacteristics());
discoveredCharacteristics.put(gatt.getDevice().getAddress(), characteristicSet);
for (BluetoothGattCharacteristic characteristic : characteristicSet) {
if (notifyUUIDs.contains(characteristic.getUuid())) {
setIndictaionSubscription(gatt, characteristic, true);
}
}
}
}
if (foundService) {
synchronized (connectedDevices) {
connectedDevices.put(gatt.getDevice().getAddress(), gatt);
}
connectingDevices.remove(gatt.getDevice().getAddress());
}
} catch (Exception e) {
Timber.d("Exception analyzing discovered services " + e.getLocalizedMessage());
e.printStackTrace();
}
if (!foundService)
Timber.d("Could not discover chat service!");
super.onServicesDiscovered(gatt, status);
}
/**
* Subscribe or Unsubscribe to/from indication of a peripheral's characteristic.
*
* After calling this method you must await the result via
* {#link #onDescriptorWrite(BluetoothGatt, BluetoothGattDescriptor, int)}
* before performing any other peripheral actions.
*/
private void setIndictaionSubscription(#NonNull BluetoothGatt peripheral,
#NonNull BluetoothGattCharacteristic characteristic,
boolean enable) {
boolean success = peripheral.setCharacteristicNotification(characteristic, enable);
Timber.d("Request notification %s %s with sucess %b", enable ? "set" : "unset", characteristic.getUuid().toString(), success);
BluetoothGattDescriptor desc = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG);
desc.setValue(enable ? BluetoothGattDescriptor.ENABLE_INDICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
boolean desSuccess = peripheral.writeDescriptor(desc);
Timber.d("Wrote descriptor with success %b", desSuccess);
}
#Override
public void onDescriptorWrite(#NonNull BluetoothGatt gatt, #NonNull BluetoothGattDescriptor descriptor,
int status) {
Timber.d("onDescriptorWrite");
if (status == BluetoothGatt.GATT_SUCCESS && transportCallback != null) {
if (Arrays.equals(descriptor.getValue(), BluetoothGattDescriptor.ENABLE_INDICATION_VALUE)) {
transportCallback.identifierUpdated(BLETransportCallback.DeviceType.CENTRAL,
gatt.getDevice().getAddress(),
Transport.ConnectionStatus.CONNECTED,
null);
} else if (Arrays.equals(descriptor.getValue(), BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE)) {
Timber.d("disabled indications successfully. Closing gatt");
gatt.close();
}
}
}
#Override
public void onCharacteristicChanged(#NonNull BluetoothGatt gatt, #NonNull BluetoothGattCharacteristic characteristic) {
Timber.d("onCharacteristicChanged %s with %d bytes", characteristic.getUuid().toString().substring(0,5),
characteristic.getValue().length);
if (transportCallback != null)
transportCallback.dataReceivedFromIdentifier(BLETransportCallback.DeviceType.CENTRAL,
characteristic.getValue(),
gatt.getDevice().getAddress());
super.onCharacteristicChanged(gatt, characteristic);
}
#Override
public void onCharacteristicWrite(#NonNull BluetoothGatt gatt,
#NonNull BluetoothGattCharacteristic characteristic, int status) {
Timber.d("onCharacteristicWrite with %d bytes", characteristic.getValue().length);
Exception exception = null;
if (status != BluetoothGatt.GATT_SUCCESS) {
String msg = "Write was not successful with code " + status;
Timber.w(msg);
exception = new UnknownServiceException(msg);
}
if (transportCallback != null)
transportCallback.dataSentToIdentifier(BLETransportCallback.DeviceType.CENTRAL,
characteristic.getValue(),
gatt.getDevice().getAddress(),
exception);
}
#Override
public void onReadRemoteRssi(#NonNull BluetoothGatt gatt, int rssi, int status) {
super.onReadRemoteRssi(gatt, rssi, status);
}
};
now the app is working for change the bluetooth device support type
device.connectGatt(context, false, mGattCallback, BluetoothDevice.DEVICE_TYPE_LE);
but now the app is not working on huawei device , if any have idea for the device huawei for this issue
I am using Android 4.4.2 on Moto X. I have a custom bluetooth low energy board, which has a red LED turned on when no devices connected to it. It supports just one connected device at a time. I am building an Android application that tries to connect to this BLE device and writes to its characteristic and then disconnects from it. I am having two problems: after writing a value to characteristic, I am doing:
mBluetoothGatt.disconnect();
mBluetoothGatt.close();
mBluetoothGatt = null;
mBluetoothAdapter.cancelDiscovery();
broadcastUpdate(ACTION_GATT_DISCONNECTED);
but that doesn't actually disconnect my smartphone (the LED on BLE device remains turned off, meaning that some device is still connected to it). However, when I turn off the bluetooth adapter on my smartphone, the LED immediately turns on.
The second problem is that I can't write to my characteristic from the first attempt, I have to call the same sequence for the second time.
Here's the procedure that is called to write my characterictic:
public void trytounlock() {
Context context = getApplicationContext();
if (connect("E2:0C:B9:4D:B9:56"))
{
Log.w(TAG, "connect returned true!");
}
else {
Log.w(TAG, "connect returned false - warum?");
};
if (mBluetoothAdapter == null ) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
else
{
Log.w(TAG, "BluetoothAdapter initialized successfully!");
}
if ( mBluetoothGatt == null) {
Log.w(TAG, "GATT not initialized");
return;
}
else
{
Log.w(TAG, "GATT initialized succesfully!");
}
/*check if the service is available on the device*/
BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("0000f00d-1212-efde-1523-785fef13d123"));
while (!mBluetoothGatt.discoverServices())
{
Log.w(TAG, "Waiting for service discovery");
}
int duration = Toast.LENGTH_SHORT;
if(mCustomService == null){
Log.w(TAG, "Custom BLE Service not found here. ");
return;
}
else
{
Log.w(TAG, "Custom BLE Service found successfully!");
}
BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(UUID.fromString("0000beef-1212-efde-1523-785fef13d123"));
byte[] raw={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
mWriteCharacteristic.setValue(raw);
if(mBluetoothGatt.writeCharacteristic(mWriteCharacteristic) == false){
Log.w(TAG, "Failed to write characteristic");
Toast.makeText(context, "Failed to write characteristic - ошибочка!!", duration).show();
}
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized, while trying to disconnect - weird!!!");
}
else {
mBluetoothGatt.disconnect();
}
mWriteCharacteristic = null;
mCustomService = null;
if (mBluetoothGatt == null) {
}
else {
mBluetoothGatt.disconnect();
mBluetoothGatt.close();
mBluetoothGatt = null;
mBluetoothAdapter.cancelDiscovery();
}
broadcastUpdate(ACTION_GATT_DISCONNECTED);
}
Here's my connect procedure:
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
return false;
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.w(TAG, "Device not found. Unable to connect.");
return false;
}
// We want to directly connect to the device, so we are setting the autoConnect
// parameter to false.
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
Log.d(TAG, "Trying to create a new connection.");
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}
// Implements callback methods for GATT events that the app cares about. For example,
// connection change and services discovered.
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
#Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
#Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
};
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
So, the questions are:
How to release my board properly, so that is sees no other devices connected to it?
What is the reason it only write my characteristic, when I call it for the second time after I initially turn on the bluetooth adapter?
I call on my bluetooth adapter mBluetoothAdapter.startDiscovery(); which then returns me a list of BluetoothDevices. When I press on 1 of those devices, I do this:
mBluetoothGatt = bluetoothDevice.connectGatt(MainActivity.this, false, mGattCallback);
Where my callback is:
private final BluetoothGattCallback mGattCallback =
new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
mConnectionState = STATE_CONNECTED;
Log.i(TAG, "Connected to GATT server.");
Log.i(TAG, "Attempting to start service discovery:" +
mBluetoothGatt.discoverServices());
List<BluetoothGattService> listBGS = mBluetoothGatt.getServices();
Log.i("","list size: " + listBGS.size());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
}
}
#Override
// New services discovered
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.w(TAG, "onServicesDiscovered GATT_SUCCESS: " + status);
List<BluetoothGattService> listBGS = mBluetoothGatt.getServices();
Log.i("","list size: " + listBGS.size());
} else {
Log.w(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) {
Log.w(TAG, "onCharacteristicRead GATT_SUCCESS: " + status + " / char: " + characteristic);
}
}
};
Now, when I try it on phones, I get STATE_CONNECTED on onConnectionStateChange , and I then call discoverServices, and I get back a GATT_SUCCESS onServicesDiscoveres. So I can take the uuids from my services.
BUT when I try it on a beacon, I get back STATE_CONNECTED and when I call discoverServices, I get back an status code: 129 -> GATT_INTERNAL_ERROR
Why is this happening for my beacons? Is there another way, how I can take the devices uuid?
I just need the UUID to be able to do this after, for the beaconManager:
try {
beaconManager.startMonitoringBeaconsInRegion(new Region("myMonitoringUniqueId", null, null, null));
} catch (RemoteException e) { }
EDIT
I know that the beacon should ask me for a code to pair, but it doesn't. Why?
I tried adding this code:
final IntentFilter pairingRequestFilter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
pairingRequestFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY - 1);
registerReceiver(mPairingRequestRecevier, pairingRequestFilter);
But still I don't get a request to pair and input my passkey
This is my pairingRequestReceiver:
private final BroadcastReceiver mPairingRequestRecevier = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(intent.getAction()))
{
final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
if (type == BluetoothDevice.PAIRING_VARIANT_PIN)
{
device.setPin(intToByteArray(123456));
abortBroadcast();
}
else
{
Log.e("","Unexpected pairing type: " + type);
}
}
}
};
After hours of trial and error I did manage to find a way to make it work like this:
1.I start the discovery the same, but when I select an bluetooth device, I ask to bond (pair) with it like this:
private void pairDevice(BluetoothDevice device) {
try {
Method method = device.getClass().getMethod("createBond", (Class[]) null);
method.invoke(device, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
I have a ACTION_BOND_STATE_CHANGED receiver:
private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);
if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {
Log.i("","Paired");
mBluetoothGatt = btDevice.connectGatt(MainActivity.this, false, mGattCallback);
} else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED){
Log.i("","Unpaired");
}
}
}
};
Which I register like this:
IntentFilter intent = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
registerReceiver(mPairReceiver, intent);
And only after this, I try to connect with my BluetoothGattCallback. Hence, I can discover the services, and so on
First, sorry for my english, second, I have a problem with a BluetoothGattCallback in Android studio for ble, the app runs, I go in research and connection and it's ok, but the method in the callback never starts, my principal interest is rssi.
This is my gattcallback:
private final BluetoothGattCallback mGattCallback =
new BluetoothGattCallback() {
#Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
Toast.makeText(MainActivity.this, "fin qui tutto ok", Toast.LENGTH_LONG).show();
TextView Rssitext = (TextView) findViewById(R.id.textView8);
Rssitext.setText("RSSI"+ "null");
if (status == gatt.STATE_CONNECTED) {
Toast.makeText(MainActivity.this,rssi, Toast.LENGTH_LONG).show();
Rssitext.setText("RSSI"+ rssi);
}
else {
Toast.makeText(MainActivity.this,"fail read rssi", Toast.LENGTH_LONG).show();
Rssitext.setText("RSSI"+ "null");
}
}
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
boolean rssiStatus = mBluetoothGatt.readRemoteRssi();
broadcastUpdate(intentAction);
Toast.makeText(MainActivity.this, "Connected to GATT server." , Toast.LENGTH_LONG).show();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Toast.makeText(MainActivity.this,"Disconnected from GATT server.", Toast.LENGTH_LONG).show();
broadcastUpdate(intentAction);
}
}
#Override
// New services discovered
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
} else {
Toast.makeText(MainActivity.this,"onServicesDiscovered received: " + status, Toast.LENGTH_LONG).show();
}
}
and now when I call, I use has for automatic connect to specific device when are found
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
Toast.makeText(MainActivity.this, device.getName() + " " + device.hashCode(), Toast.LENGTH_LONG).show();
if ((device.hashCode() == 676210690)|| (device.hashCode() == -1001190065))
{
mBluetoothGatt= device.connectGatt(context, false, mGattCallback);
Toast.makeText(MainActivity.this,
"sought after device found", Toast.LENGTH_LONG).show();
mBluetoothGatt.readRemoteRssi();
}
}
}
};
Attempting to read characteristics from a GATT service, the list is incomplete compared to the list I get from an iOS device, or the manufacturer guide.
I am reading the characteristics as follows:
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
#Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
mConnectionState = STATE_CONNECTED;
mBluetoothGatt = gatt;
if (shouldStartWriting && writeCharacteristicsQueue.peek() != null) {
mBluetoothGatt.writeCharacteristic(writeCharacteristicsQueue.poll());
} else {
EventBus.getDefault().post(new BTGattStatusEvent(BTGattStatusEvent.Status.CONNECTED));
Log.i(TAG, "Attempting to start service discovery:" +
gatt.discoverServices());
}
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
mConnectionState = STATE_DISCONNECTED;
mBluetoothGatt = null;
EventBus.getDefault().post(new BTGattDisconnectedEvent());
}
}
#Override
// New services discovered
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
EventBus.getDefault().post(new BTGattStatusEvent(BTGattStatusEvent.Status.DISCOVERED));
if (status == BluetoothGatt.GATT_SUCCESS) {
for (BluetoothGattService service : gatt.getServices()) {
LOGD(TAG, "Found Service " + service.getUuid().toString());
discoverCharacteristics(service);
}
gatt.readCharacteristic(readCharacteristicsQueue.poll());
} else {
Log.w(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) {
parseCharacteristic(characteristic);
LOGD(TAG, String.format("%s | %s ", characteristic.getUuid(), characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT16, 0)));//(BluetoothGattCharacteristic.FORMAT_UINT16));
if (readCharacteristicsQueue.peek() != null) {
gatt.readCharacteristic(readCharacteristicsQueue.poll());
} else {
EventBus.getDefault().post(new BTGattStatusEvent(BTGattStatusEvent.Status.DONE_DISCOVERING));
}
}
}
and
private void discoverCharacteristics(BluetoothGattService service) {
for (BluetoothGattCharacteristic gattCharacteristic : service.getCharacteristics()) {
LOGD(TAG, "Discovered UUID: " + gattCharacteristic.getUuid());
readCharacteristicsQueue.add(gattCharacteristic);
}
}
I also attempted to get this characteristic using getCharacteristic, but I received a null.
The characteristics found are:
Discovered UUID: 0000fff1-0000-1000-8000-00805f9b34fb
Discovered UUID: 0000fff2-0000-1000-8000-00805f9b34fb
Discovered UUID: 0000fff3-0000-1000-8000-00805f9b34fb
Discovered UUID: 0000fff4-0000-1000-8000-00805f9b34fb
Discovered UUID: 0000fff5-0000-1000-8000-00805f9b34fb
However, on iOS and according to the manufacturer, there should also be a 0000fff7.
Why isn't this characteristic being read?
UPDATE:
Nothing happened here. Not one of Android's BLE scanning apps can discover it.