Hello I am making a bluetooth connecting android app.
I followed the instruction from developer.android.com
while I am testing my app, I look forward to it works properly, but it didn't.
I tried to get detected BLE devices names, but don't know the reason why it doesn't show me the devices name...
Arduino nano 33 IOT is adverstising bluetooth next to my android phone, and I am trying to detect it and get the Adrduino's BLE device name and address.
here is my MainActivity.java
public class MainActivity extends AppCompatActivity {
//View Contents Elements
public Button btnActivateBluetooth;
public Button btnSearchBluetooth;
public Button btnSendData;
public ListView lvSearchedDevice;
public ListView lvLog;
public TextView tvStatus;
public EditText etData;
//etc values
public ArrayAdapter<String> logAdapter;
private final int REQUEST_ENABLE_BT = 1;
private boolean mScanning = true;
//bluetooth values
public BluetoothAdapter btAdapter;
public BluetoothManager btManager;
private Handler handler;
@SuppressLint("MissingPermission")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//View Elements
btnSearchBluetooth = (Button) findViewById(R.id.btnSearchBluetooth);
btnSendData = (Button) findViewById(R.id.btnSendData);
lvSearchedDevice = (ListView) findViewById(R.id.lvSearchedDevice);
lvLog = (ListView) findViewById(R.id.log);
tvStatus = (TextView) findViewById(R.id.tvStatus);
etData = (EditText) findViewById(R.id.etData);
//etc
logAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
lvLog.setAdapter(logAdapter);
handler = new Handler();
// Initializes Bluetooth adapter.
btManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
btAdapter = btManager.getAdapter();
// displays a dialog requesting user permission to enable Bluetooth.
if (btAdapter == null || !btAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
btnSearchBluetooth.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
scanLeDevice(true);
}
});
}
//Scan devices
@SuppressLint("MissingPermission")
private void scanLeDevice(final boolean enable){
if(enable){
handler.postDelayed(new Runnable() {
@SuppressLint("MissingPermission")
@Override
public void run() {
btAdapter.stopLeScan(leScanCallback);
}
},5000);
btAdapter.startLeScan(leScanCallback);
}
else
{
btAdapter.stopLeScan(leScanCallback);
}
}
//Callback method
private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
@SuppressLint("MissingPermission")
@Override
public void run() {
Toast.makeText(MainActivity.this, device.getName(), Toast.LENGTH_SHORT).show();
}
});
}
};
}
and this is my Arduino nano 33 IOT's code.
#include <ArduinoBLE.h>
BLEService Toothbrush("00001101-0000-1000-8000-00805F9B34FB");
BLEStringCharacteristic ToothbrushChar("00001101-0000-1000-8000-00805F9B34FB",BLEWrite|BLERead | BLENotify, 10);
void setup() {
Serial.begin(9600);
if(!BLE.begin()){
Serial.println("Starting BLE failed.");
while(1);
}
BLE.setLocalName("HayanToothbrush");
BLE.setAdvertisedService(Toothbrush);
Toothbrush.addCharacteristic(ToothbrushChar);
BLE.addService(Toothbrush);
BLE.advertise();
Serial.println("Bluetooth device active, wating for connections...");
}
void loop() {
BLEDevice central = BLE.central();
if(central) {
Serial.print("Connected to central : ");
Serial.println(central.address());
while(central.connected()){
}
Serial.print("Disconnected from central:");
Serial.println(central.address());
}
}
I add permissions in the Mainfest as below.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.bluetooth0523">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Bluetooth0523"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
But it still doesn't find me scanned device name. I think it's on LeScanCallBack problem. When running startLeScan, It seems not running callback method. in addition, I am running this app on SDK_VERSION_30 and Arduino nano IOT 33 is discoverable If I use the Bluetooth function that my phone has, not my application, it will be displayed in the scan result list. I want to get scan result on my own app. but don't know where is the problem.
Permissions must be declared and requested depending on Android version. Main differences are:
Target Android 12 or higher
BLUETOOTH_SCAN
Target Android 11 or lower
ACCESS_FINE_LOCATION
See Bluetooth permissions for details.