I used for the first time react-native-ble-manager. The app has all the permissions, however when I run the BleManager.scan() the app is closing without any error or logs. I know the code is a little ugly but it's just for testing, the first second I run the bluetooth manager start and after 5 seconds I run the scan. But the crash happen immediately after 5 seconds. Any idea why?
import BleManager from 'react-native-ble-manager';
const BleManagerModule = NativeModules.BleManager;
const bleManagerEmitter = new NativeEventEmitter(BleManagerModule);
const handleDiscoverPeripheral = (peripheral) => {
console.log('Got ble peripheral', peripheral);
if (!peripheral.name) {
peripheral.name = 'NO NAME';
}
peripherals.set(peripheral.id, peripheral);
setList(Array.from(peripherals.values()));
}
const handleStopScan = () => {
console.log('Scan is stopped');
}
let interval;
let gImageShow = true;
let gTime = 0;
BleManager.enableBluetooth()
.then(() => {
// Success code
console.log("The bluetooth is already enabled or the user confirm");
})
.catch((error) => {
// Failure code
console.log("The user refuse to enable bluetooth");
});
function App(props) {
const [shouldShow, setShouldShow] = useState(gImageShow);
useEffect(() => {
interval = setInterval(() => {
if (gTime == 1)
{
BleManager.start({showAlert: true});
bleManagerEmitter.addListener('BleManagerDiscoverPeripheral', handleDiscoverPeripheral);
bleManagerEmitter.addListener('BleManagerStopScan', handleStopScan );
PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION).then((result) => {
if (result) {
console.log("Permission is OK");
}
});
}
if (gTime == 5)
{
BleManager.scan([], 10, true);
}
gImageShow = !gImageShow;
setShouldShow(gImageShow);
gTime = gTime + 1;
},1000);
return () => clearInterval(interval);
}, []);
useEffect(() => {
});
the manifest is like:
xmlns:tools="http://schemas.android.com/tools"
package="com.diagnostic_ble">
<uses-permission android:name="android.permission.INTERNET" />
<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"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" tools:targetApi="Q"/>
<!-- Needed only if your app looks for Bluetooth devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
The problem has been solved. The new android 12 (I think from this one), needs a different permission that it hasn't been updated in react-native-ble-manager webpage. In the manifest you need to add
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
Also, In the app.js you need to call once requestPermissions(); that it can be like
const requestPermissions = async () => {
if (Platform.OS === 'android') {
const apiLevel = await DeviceInfo.getApiLevel();
if (apiLevel < 31) {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: 'Location Permission',
message: 'Bluetooth Low Energy requires Location',
buttonNeutral: 'Ask Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
} else {
const result = await requestMultiple([
PERMISSIONS.ANDROID.BLUETOOTH_SCAN,
PERMISSIONS.ANDROID.BLUETOOTH_CONNECT,
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
]);
const isGranted =
result['android.permission.BLUETOOTH_CONNECT'] ===
PermissionsAndroid.RESULTS.GRANTED &&
result['android.permission.BLUETOOTH_SCAN'] ===
PermissionsAndroid.RESULTS.GRANTED &&
result['android.permission.ACCESS_FINE_LOCATION'] ===
PermissionsAndroid.RESULTS.GRANTED;
}
} else {
}
};