[Android Q&A, Help & Troubleshooting] tizFaver:
Hi,

I'm new in this forum so I don't know if i'm in the correct section...

I created this class named BLEConnection becuase i'm tring to connect to a esp32 via BLE but i'm having some problem in the connection part... the class:

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.os.ParcelUuid;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class BLEConnection {
private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mBluetoothLeScanner;
private String mTargetDeviceAddress;
private boolean mScanning;
private BLEConnectionListener mListener;
private BluetoothGatt mBluetoothGatt;
private Context mContext;

private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
// This callback is invoked when the connection state changes, e.g. from disconnected to connected.
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.e("bleee", "connected ");
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.e("bleee", "disconected");
}
}
};

private ScanCallback mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) { // This callback is invoked when a BLE advertisement is found.
Log.e("bleee", "scan result");
BluetoothDevice device = result.getDevice();
if (device.getAddress().equals(mTargetDeviceAddress)) {
Log.e("bleee", "device found 1");
mBluetoothLeScanner.stopScan(mScanCallback);
mScanning = false;
mListener.onDeviceFound(device);
}
}

@Override
public void onBatchScanResults(List<ScanResult> results) { // This callback is invoked when multiple BLE advertisements are found at once.
Log.e("bleee", "scan result multiple");
for (ScanResult result : results) {
BluetoothDevice device = result.getDevice();
if (device.getAddress().equals(mTargetDeviceAddress)) {
Log.e("bleee", "batch scan multiple");
mBluetoothLeScanner.stopScan(mScanCallback);
mScanning = false;
mListener.onDeviceFound(device);
break;
}
}
}

@Override
public void onScanFailed(int errorCode) {
Log.e("bleee", "scan failed 1");
mScanning = false;
mListener.onScanFailed(errorCode);
}
};

public BLEConnection(Context context, String targetDeviceAddress, BLEConnectionListener listener) {
mTargetDeviceAddress = targetDeviceAddress;
mListener = listener;

BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
}

public void startScan() {
Log.e("bleee", "starting scan..................");
if (mScanning) {
return;
}

List<ScanFilter> filters = new ArrayList<>();
ScanFilter filter = new ScanFilter.Builder()
.setDeviceAddress(mTargetDeviceAddress)
.build();
filters.add(filter);

ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
.setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
.setReportDelay(0L)
.build();

mBluetoothLeScanner.startScan(filters, settings, mScanCallback);
mScanning = true;
Log.e("bleee", "finished?");
}
public void stopScan() {
Log.e("bleee", "something stopped the scan");
if (mScanning) {
mBluetoothLeScanner.stopScan(mScanCallback);
mScanning = false;
}
}

public void writeMessage(byte[] message) {
Log.e("bleee", "writing message...............");
if (mBluetoothGatt == null) {
return;
}

BluetoothGattService service = mBluetoothGatt.getService(UUID.fromString("4fafc201-1fb5-459e-8fcc-c5c9c331914b"));
if (service == null) {
return;
}

BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString("beb5483e-36e1-4688-b7f5-ea07361b26a8"));
if (characteristic == null) {
return;
}

characteristic.setValue(message);
mBluetoothGatt.writeCharacteristic(characteristic);
}

public interface BLEConnectionListener {
void onDeviceFound(BluetoothDevice device);
void onScanFailed(int errorCode);
}

public void connectToDevice(BluetoothDevice device) {
Log.e("bleee", "Trying connecting");
mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback);
}

public void disconnectFromDevice() {
if (mBluetoothGatt != null) {
mBluetoothGatt.disconnect();
mBluetoothGatt.close();
mBluetoothGatt = null;
}
}

}

please ignore that android studio thinks that some code is an error (because could not be safe and could crash if Bluetooth is not enable, but i'll skip for now this).

So now, I have a service that is this (eliminated useless method for my problem):

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.util.Log;
//import com.welie.blessed.*;

public class SendNotifyService extends Service implements BLEConnection.BLEConnectionListener {
private volatile boolean shouldStopThread;
private volatile boolean oksend = false;
private String ESP32_MAC_ADDRESS = "84:F7:03:68:06:52";
private BLEConnection mBLEConnection;

public SendNotifyService() {}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
shouldStopThread = false;

mBLEConnection = new BLEConnection(this, ESP32_MAC_ADDRESS, this);
// Start scanning for the device
mBLEConnection.startScan();

new Thread(new Runnable() {
@Override
public void run() {
while (!shouldStopThread) {
//-----------------------------------------------------------------------------------------------------
if(oksend == true){
byte[] message = "Hello, device!".getBytes();
mBLEConnection.writeMessage(message);
}

Log.e("Service Ard_OS", "Service is running...");
Log.e("Service Ard_OS", mac);
pause(4000);

//-----------------------------------------------------------------------------------------------------
}}
public void pause(int millis){ try { Thread.sleep(millis); } catch (InterruptedException e) { e.printStackTrace(); } }
}).start();

return START_STICKY;
}

@Override
public void onDeviceFound(BluetoothDevice device) {
Log.e("bleee", "device found 2");
oksend = true;
mBLEConnection.connectToDevice(device);
}

@Override
public void onScanFailed(int errorCode) {
Log.e("bleee", "scan failed, i think...");
}
}

Now it comes the problem:

Obviously I'm using a real phone (samsung galaxy a20e) that runs API 30.

When I start the Service in the LOGCAT using the filter "bleee" i can only see theese two debug message:

So the problem is that i don't get nothing else, not in the BluetoothGattCallback and not even in the ScanCallback. It doesn't connect to the device... If I was not clear about something I will answer!

Thanks to everyone.