Skip to content

Commit

Permalink
Merge pull request #569 from AltBeacon/stop-scanning-on-unbind
Browse files Browse the repository at this point in the history
Prevent scanning being left on after unbind
  • Loading branch information
davidgyoung authored Aug 29, 2017
2 parents 0c23e14 + d170b8c commit f9df156
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 9 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
### Development

Bug Fixes:
- Turn off scanning after unbind, which was previously left on forever in some cases.
(#569, David G. Young)

### 2.12.1 / 2017-08-16

Bug Fixes:
Expand Down
30 changes: 21 additions & 9 deletions src/main/java/org/altbeacon/beacon/BeaconManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -405,21 +405,23 @@ public void bind(@NonNull BeaconConsumer consumer) {
LogManager.w(TAG, "This device does not support bluetooth LE. Will not start beacon scanning.");
return;
}
if (mScheduledScanJobsEnabled) {
LogManager.d(TAG, "Not starting beacon scanning service. Using scheduled jobs");
consumer.onBeaconServiceConnect();
return;
}
synchronized (consumers) {
ConsumerInfo newConsumerInfo = new ConsumerInfo();
ConsumerInfo alreadyBoundConsumerInfo = consumers.putIfAbsent(consumer, newConsumerInfo);
if (alreadyBoundConsumerInfo != null) {
LogManager.d(TAG, "This consumer is already bound");
}
else {
LogManager.d(TAG, "This consumer is not bound. binding: %s", consumer);
Intent intent = new Intent(consumer.getApplicationContext(), BeaconService.class);
consumer.bindService(intent, newConsumerInfo.beaconServiceConnection, Context.BIND_AUTO_CREATE);
LogManager.d(TAG, "This consumer is not bound. Binding now: %s", consumer);
if (mScheduledScanJobsEnabled) {
LogManager.d(TAG, "Not starting beacon scanning service. Using scheduled jobs");
consumer.onBeaconServiceConnect();
}
else {
LogManager.d(TAG, "Binding to service");
Intent intent = new Intent(consumer.getApplicationContext(), BeaconService.class);
consumer.bindService(intent, newConsumerInfo.beaconServiceConnection, Context.BIND_AUTO_CREATE);
}
LogManager.d(TAG, "consumer count is now: %s", consumers.size());
}
}
Expand All @@ -439,7 +441,12 @@ public void unbind(@NonNull BeaconConsumer consumer) {
synchronized (consumers) {
if (consumers.containsKey(consumer)) {
LogManager.d(TAG, "Unbinding");
consumer.unbindService(consumers.get(consumer).beaconServiceConnection);
if (mScheduledScanJobsEnabled) {
LogManager.d(TAG, "Not unbinding from scanning service as we are using scan jobs.");
}
else {
consumer.unbindService(consumers.get(consumer).beaconServiceConnection);
}
consumers.remove(consumer);
if (consumers.size() == 0) {
// If this is the last consumer to disconnect, the service will exit
Expand All @@ -449,6 +456,11 @@ public void unbind(@NonNull BeaconConsumer consumer) {
// This way when we restart ranging or monitoring it will always be in
// foreground mode
mBackgroundMode = false;
// If we are using scan jobs, we cancel the active scan job
if (mScheduledScanJobsEnabled) {
// TODO: Cancel the active scan job. Without this is keeps scanning as if
// a consumer is bound.
}
}
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public abstract class CycledLeScanner {
private boolean mScanningEnabled = false;
protected final Context mContext;
private long mScanPeriod;
// indicates that we decided not to turn scanning off at the end of a scan cycle (e.g. to
// avoid doing too many scans in a limited time on Android 7.0 or because we are capable of
// multiple detections. If true, it indicates scanning needs to be stopped when we finish.
private boolean mScanningLeftOn = false;

protected long mBetweenScanPeriod;

Expand Down Expand Up @@ -224,6 +228,17 @@ public void stop() {
mScanningEnabled = false;
if (mScanCyclerStarted) {
scanLeDevice(false);
// If we have left scanning on between scan periods, now is the time to shut it off.
if (mScanningLeftOn) {
LogManager.d(TAG, "Stopping scanning previously left on.");
mScanningLeftOn = false;
try {
LogManager.d(TAG, "stopping bluetooth le scan");
finishScan();
} catch (Exception e) {
LogManager.w(e, TAG, "Internal Android exception scanning for beacons");
}
}
} else {
LogManager.d(TAG, "scanning already stopped");
}
Expand Down Expand Up @@ -397,18 +412,21 @@ private void finishScanCycle() {
LogManager.d(TAG, "Not stopping scan because this is Android N and we" +
" keep scanning for a minimum of 6 seconds at a time. "+
"We will stop in "+(ANDROID_N_MIN_SCAN_CYCLE_MILLIS-(now-mLastScanCycleStartTime))+" millisconds.");
mScanningLeftOn = true;
}
else {
try {
LogManager.d(TAG, "stopping bluetooth le scan");
finishScan();
mScanningLeftOn = false;
} catch (Exception e) {
LogManager.w(e, TAG, "Internal Android exception scanning for beacons");
}
}
}
else {
LogManager.d(TAG, "Not stopping scanning. Device capable of multiple indistinct detections per scan.");
mScanningLeftOn = true;
}

mLastScanCycleEndTime = SystemClock.elapsedRealtime();
Expand Down

0 comments on commit f9df156

Please sign in to comment.