I am trying to scan Bluetooth Devices but startDiscovery just won't work, I have tried some old solutions of this but still no solution is working here. I have tried using some packages but they don't provide the solution I want.
package com.bt67;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import androidx.annotation.NonNull;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.WritableMap;
import java.util.ArrayList;
import java.util.Objects;
public class discover extends ReactContextBaseJavaModule {
ReactApplicationContext reactContext;
ArrayList<BluetoothDevice> discoveredDevices;
WritableMap reactDiscoveredDevices;
BluetoothAdapter bluetoothAdapter;
@NonNull
@Override
public String getName() {
return "discover";
}
discover(ReactApplicationContext reactApplicationContext){
super(reactApplicationContext);
reactContext = reactApplicationContext;
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
discoveredDevices = new ArrayList<>();
IntentFilter intentActionFound = new IntentFilter(BluetoothDevice.ACTION_FOUND);
reactContext.registerReceiver(discoveryReceiver,intentActionFound);
IntentFilter scanIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
reactContext.registerReceiver(scanModeReceiver,scanIntentFilter);
}
BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, @NonNull Intent intent) {
String action = intent.getAction();
Log.d(Constants.TAG,"in discoveryReceiver");
if(BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
discoveredDevices.add(device);
Log.d(Constants.TAG,"Found: " device.getName());
reactDiscoveredDevices.putString(device.getAddress(), device.getName());
}
}
};
BroadcastReceiver scanModeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, @NonNull Intent intent) {
String action = intent.getAction();
if(action.equals(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)) {
int modeValue = intent.getIntExtra(
BluetoothAdapter.EXTRA_SCAN_MODE,BluetoothAdapter.ERROR);
if (modeValue == BluetoothAdapter.SCAN_MODE_CONNECTABLE) {
Log.d(Constants.TAG,"Device can receive connection");
} else if (modeValue == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Log.d(Constants.TAG,"Device is Discoverable and can receive connection");
} else if (modeValue == BluetoothAdapter.SCAN_MODE_NONE) {
Log.d(Constants.TAG,
"Device is NOT Discoverable and can't receive connection");
} else {
Log.d(Constants.TAG,"ERROR");
}
}
}
};
@ReactMethod
public void doDiscovery(@NonNull Callback callback) {
// If we're already discovering, stop it
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
// Request discover from BluetoothAdapter
bluetoothAdapter.startDiscovery();
callback.invoke("Started Discovery");
}
@ReactMethod
public void getDiscoveredDevices(@NonNull Callback callback) {
callback.invoke(reactDiscoveredDevices);
}
@ReactMethod
public void makeDeviceDiscoverable(int duration, @NonNull Callback callback) {
Intent intentDiscoverable = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
intentDiscoverable.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,duration);
Objects.requireNonNull(getCurrentActivity()).startActivity(intentDiscoverable);
callback.invoke("Device is discoverable for " duration " seconds");
}
}
This is the code I have written to startDiscovery() of Bluetooth Device but it is not discovering any devices. I have made the other device discoverable.
I have added below permissions:
<!-- For Android 11 or lower -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
android:maxSdkVersion="28"/>
<!-- For Android Q -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- For Android 12 or higher -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
CodePudding user response:
are you shure your app has granted these permissions? I don't see perm-asking-code, and Android 12 new permissions are runtime ones
The BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECT, and BLUETOOTH_SCAN permissions are runtime permissions. Therefore, you must explicitly request user approval in your app before you can look for Bluetooth devices, make a device discoverable to other devices, or communicate with already-paired Bluetooth devices.
HERE you can find some examples how to implement
CodePudding user response:
I solved the issue I was getting... The problem was in my Log message in ACTION_FOUND Broadcast receiver I had Log.d("TAG",device.getName()); of non-string value, so I change it to Log.d("TAG",String.valueOf(device.getName()));
And there is some WritableMap issue in the above code where I solved the initialisation using Aruguments.createMap();