I'm testing an app with an Android N device (Moto G 5th gen), and it not find any beacon (beacons.size() == 0 always), but with other devices with lower API works fine... Only fails with this device.
I've checked the scan limitation than Google has added in Android N:
We’ve changed the BLE Scanning behavior starting in DP4. We’ll prevent applications from starting and stopping scans more than 5 times in 30 seconds. For long running scans, we’ll convert them into opportunistic scans.
This is the code:
public void startBeaconScan() {
Log.d(TAG, "App started up");
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout(iBeaconLayout));
long timeBetweenScans = 1100;
long timeScanPeriod = 500;
if(Build.VERSION.SDK_INT > 23){ //CHECK IF NOUGAT OR MORE
timeBetweenScans = 5000;
timeScanPeriod = 15000;
}
beaconManager.setForegroundBetweenScanPeriod(timeBetweenScans);
beaconManager.setForegroundScanPeriod(timeScanPeriod);
beaconManager.setBackgroundBetweenScanPeriod(timeBetweenScans);
beaconManager.setBackgroundScanPeriod(timeScanPeriod);
beaconManager.setRegionStatePeristenceEnabled(true);
region = new Region("myMonitoringUniqueId", Identifier.parse("2f234454-cf6d-4a0f-adf2-f4911ba9ffa6"), null, null);
new RegionBootstrap(this, region);
}
This functions is called from the Application's didDetermineStateForRegion() callback method from BootstrapNotifier interface.
Any idea of why I'm having this problem? With Android N, I only have tested with the Moto G 5th... But with other devices (Android L, Android M...) the code works fine.
----- UPDATE -----
Logcat with the Application start:
06-01 15:51:05.183 12251-12251/? D/MyApplication: App started up
06-01 15:51:05.187 12251-12251/? D/BeaconParser: Parsing beacon layout: m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25
06-01 15:51:05.189 12251-12251/? D/BeaconParser: Parsing beacon layout: m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25
06-01 15:51:05.200 21464-4646/? I/PBSessionCacheImpl: Deleted sessionId[4000692901285] from persistence.
06-01 15:51:05.202 21464-4534/? V/ConnectivityManager: isActiveNetworkMetered() returns:false
06-01 15:51:05.207 21464-4534/? V/ConnectivityManager: isActiveNetworkMetered() returns:false
06-01 15:51:05.211 21464-21464/? W/SearchService: Abort, client detached.
06-01 15:51:05.216 21464-5529/? E/ContentStoreEUAS: Failed to commit the deferred actions
06-01 15:51:05.351 12251-12267/? D/NetworkSecurityConfig: No Network Security Config specified, using platform default
06-01 15:51:05.366 12251-12251/? W/BluetoothCrashResolver: Can't read macs from BluetoothCrashResolverState.txt
06-01 15:51:05.371 12251-12251/? W/ModelSpecificDistanceCalculator: Cannot find match for this device. Using default
06-01 15:51:05.371 12251-12251/? W/ModelSpecificDistanceCalculator: Cannot find match for this device. Using default
06-01 15:56:17.210 16969-16969/? D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
Starting with Android Marshmallow (6.0) location must be turned on in settings in order to detect Bluetooth LE devices. This applies to both bluetooth beacons as well as other types of Bluetooth LE devices. Google made this change because scanning for Bluetooth LE devices may be used to infer your location. This same restriction does not apply to pre-6.0 devices.
One possible solution is to detect if location is off on a 6.0+ device and prompt the user to turn it on.
It is worth noting that runtime permissions for android.permission.ACCESS_FINE_LOCATION or android.permission.ACCESS_COARSE_LOCATION must also be obtained if your app targets SDK 23+. See here for more info.