diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fd104b04..0eb794e3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +### Development + +- Fix ConcurrentModificationException crash on background detection reported in #929. (#940, David G. Young) +- Expedite beacon detections on Samsung when transitionoing from screen on to screen onff (#941, David G. Young) + ### 2.16.3 / 2019-09-18 - Fix thread leak with 0 regions and settings applied, (#888, David G. Young) diff --git a/lib/src/main/java/org/altbeacon/beacon/service/ScanJob.java b/lib/src/main/java/org/altbeacon/beacon/service/ScanJob.java index ede97b84f..062aab6ae 100644 --- a/lib/src/main/java/org/altbeacon/beacon/service/ScanJob.java +++ b/lib/src/main/java/org/altbeacon/beacon/service/ScanJob.java @@ -77,7 +77,7 @@ public void run() { LogManager.i(TAG, "Running periodic scan job: instance is "+ScanJob.this); } - List queuedScanResults = ScanJobScheduler.getInstance().dumpBackgroundScanResultQueue(); + List queuedScanResults = new ArrayList<>(ScanJobScheduler.getInstance().dumpBackgroundScanResultQueue()); LogManager.d(TAG, "Processing %d queued scan resuilts", queuedScanResults.size()); for (ScanResult result : queuedScanResults) { ScanRecord scanRecord = result.getScanRecord(); diff --git a/lib/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScannerForLollipop.java b/lib/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScannerForLollipop.java index 1cc98bbaf..2f53d2981 100644 --- a/lib/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScannerForLollipop.java +++ b/lib/src/main/java/org/altbeacon/beacon/service/scanner/CycledLeScannerForLollipop.java @@ -7,8 +7,10 @@ import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanResult; import android.bluetooth.le.ScanSettings; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.os.Build; import android.os.ParcelUuid; import android.os.PowerManager; @@ -199,7 +201,16 @@ protected void startScan() { mBeaconManager.getBeaconParsers()); } else { - LogManager.d(TAG, "Using an empty scan filter since this is 8.1+ on Non-Samsung"); + if (Build.MANUFACTURER.equalsIgnoreCase("samsung")) { + LogManager.d(TAG, "Using a wildcard scan filter on Samsung because the screen is on. We will switch to a non-empty filter if the screen goes off"); + // if this is samsung, as soon as the screen goes off we will need to start a different scan + // that has scan filters + IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); + mContext.getApplicationContext().registerReceiver(mSamsungScreenOffReceiver, filter); + LogManager.d(TAG, "registering SamsungScreenOffReceiver "+mSamsungScreenOffReceiver); + } else { + LogManager.d(TAG, "Using an empty scan filter since this is 8.1+ on Non-Samsung"); + } // The wildcard filter matches everything. filters = new ScanFilterUtils().createWildcardScanFilters(); } @@ -214,6 +225,14 @@ protected void startScan() { } } + @MainThread + public void stop() { + super.stop(); + LogManager.d(TAG, "unregistering SamsungScreenOffReceiver as we stop the cycled scanner"); + // Catch the exception in case it has not been registered + try { mContext.getApplicationContext().unregisterReceiver(mSamsungScreenOffReceiver); } catch (IllegalArgumentException e) {} + } + @Override protected void finishScan() { LogManager.d(TAG, "Stopping scan"); @@ -391,4 +410,18 @@ public void onScanFailed(int errorCode) { } return leScanCallback; } + + private BroadcastReceiver mSamsungScreenOffReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (!mMainScanCycleActive) { + LogManager.d(TAG, "Screen has gone off while outside the main scan cycle on Samsung. We will do nothing."); + } + else { + LogManager.d(TAG, "Screen has gone off while using a wildcard scan filter on Samsung. Restarting scanner with non-empty filters."); + stopScan(); + startScan(); + } + } + }; }