Я использую Android Beacon Library для сканирования сигналов Eddystone Beacons для Android. Я запускаю мониторинг после того, как услуга радиомаяка подключена, а затем начните колебаться, когда найден маяк.Остановить сканирование маяков: stopRangingBeaconsInRegion() не работает
Мне нужно прекратить сканирование маяков (остановить мониторинг и настройку) по выбору пользователя. Я использую
beaconManager.stopMonitoringBeaconsInRegion(region);
beaconManager.stopRangingBeaconsInRegion(region);
, чтобы остановить сканирование внутри моей остановкиScan(). Но ранжирование не прекращается, хотя мониторинг останавливается. Есть ли что-то, что я делаю неправильно?
Вот полный код:
public class BlankFragment extends Fragment implements BeaconConsumer {
public BlankFragment() {
// Required empty public constructor
}
private static final int PERMISSION_REQUEST_FINE_LOCATION = 1;
private Region region;
private Map<String /* uid */, Beacon> deviceToBeaconMap = new HashMap<>();
String LOG_TAG = BlankFragment.class.getSimpleName();
SharedPreferences sp;
View rootView;
private BeaconManager beaconManager;
boolean isScanning = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
sp.registerOnSharedPreferenceChangeListener(listener);
beaconManager = BeaconManager.getInstanceForApplication(getContext());
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19"));
beaconManager.bind(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_near_me, container, false);
return rootView;
}
@Override
public void onStop() {
super.onStop();
if (isScanning)
stopScan();
}
@Override
public void onDestroy() {
super.onDestroy();
deviceToBeaconMap.clear();
beaconManager.unbind(this);
}
@Override
public void onBeaconServiceConnect() {
region = new Region("nearMeScanning", null, null, null);
Log.i(LOG_TAG, "OnBeaconServiceConnect called");
beaconManager.addMonitorNotifier(new MonitorNotifier() {
@Override
public void didEnterRegion(Region region) {
try {
beaconManager.startRangingBeaconsInRegion(region);
Log.i(LOG_TAG, "In beacon region");
} catch (RemoteException e) {
Log.e(LOG_TAG, "Remote Exception while starting Ranging", e);
}
}
@Override
public void didExitRegion(Region region) {
try {
beaconManager.stopRangingBeaconsInRegion(region);
Log.i(LOG_TAG, "Exited beacon region");
} catch (RemoteException e) {
Log.e(LOG_TAG, "Remote Exception while stoping Ranging", e);
}
}
@Override
public void didDetermineStateForRegion(int i, Region region) {
Log.i(LOG_TAG, "State of region changed " + i);
}
});
beaconManager.addRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<org.altbeacon.beacon.Beacon> beacons, Region region) {
if (beacons.size() > 0) {
for (org.altbeacon.beacon.Beacon scannedBeacon : beacons) {
setOnLostRunnable();
String deviceUUID = scannedBeacon.getId1().toString().substring(2) + scannedBeacon.getId2().toString().substring(2);
String deviceAddress = scannedBeacon.getBluetoothAddress();
int rssi = scannedBeacon.getRssi();
Beacon beacon;
if (!deviceToBeaconMap.containsKey(deviceUUID)) {
beacon = new Beacon(deviceAddress, rssi, deviceUUID);
deviceToBeaconMap.put(deviceUUID, beacon);
if (BuildConfig.DEBUG)
Log.d(LOG_TAG, "New Beacon added " + deviceUUID + " DeviceAddress " + deviceAddress);
} else {
deviceToBeaconMap.get(deviceUUID).lastSeenTimestamp = System.currentTimeMillis();
deviceToBeaconMap.get(deviceUUID).rssi = rssi;
}
}
}
}
});
if (sp.getBoolean(Constants.SharedPreferences.IS_VISIBILITY_ON, false)) {
refreshScan();
} else {
visbilityOffTasks();
}
}
@Override
public Context getApplicationContext() {
return getActivity().getApplicationContext();
}
@Override
public void unbindService(ServiceConnection serviceConnection) {
getActivity().unbindService(serviceConnection);
}
@Override
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int i) {
return getActivity().bindService(intent, serviceConnection, i);
}
private void refreshScan() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (getActivity().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (BuildConfig.DEBUG)
Log.d(LOG_TAG, "Will check for permissions");
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_FINE_LOCATION);
} else {
if (sp.getBoolean(Constants.SharedPreferences.IS_VISIBILITY_ON, false))
startScan();
}
} else {
if (sp.getBoolean(Constants.SharedPreferences.IS_VISIBILITY_ON, false))
startScan();
}
}
private void startScan() {
if (sp.getBoolean(Constants.SharedPreferences.IS_VISIBILITY_ON, false)) {
Log.i(LOG_TAG, "Starting scanning");
try {
beaconManager.startMonitoringBeaconsInRegion(region);
isScanning = true;
} catch (RemoteException e) {
Log.e(LOG_TAG, "Remote Exception while starting Ranging", e);
}
}
}
private void stopScan() {
try {
beaconManager.stopMonitoringBeaconsInRegion(region);
beaconManager.stopRangingBeaconsInRegion(region);
isScanning = false;
} catch (RemoteException e) {
Log.e(LOG_TAG, "Remote Exception while stoping Ranging", e);
}
Log.i(LOG_TAG, "Stopping scanning");
}
SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
if (key.equalsIgnoreCase(Constants.SharedPreferences.IS_VISIBILITY_ON) && getActivity() != null) {
if (sp.getBoolean(Constants.SharedPreferences.IS_VISIBILITY_ON, false)) {
Log.i(LOG_TAG, "Visibility turned ON");
refreshScan();
} else {
Log.i(LOG_TAG, "Visibility turned off");
visbilityOffTasks();
}
}
}
};
private void visbilityOffTasks() {
stopScan();
deviceToBeaconMap.clear();
}
int onLostTimeoutMillis = 15000;
private void setOnLostRunnable() {
removeHandler.postDelayed(removeLostDevices, onLostTimeoutMillis);
}
private static final Handler removeHandler = new Handler(Looper.getMainLooper());
Runnable removeLostDevices = new Runnable() {
@Override
public void run() {
long time = System.currentTimeMillis();
Iterator<Map.Entry<String, Beacon>> itr = deviceToBeaconMap.entrySet().iterator();
while (itr.hasNext()) {
Beacon beacon = itr.next().getValue();
if (beacon != null && !beacon.deviceAddress.equalsIgnoreCase("default"))
if ((time - beacon.lastSeenTimestamp) > onLostTimeoutMillis) {
itr.remove();
if (BuildConfig.DEBUG)
Log.d(LOG_TAG, "Removing beacon " + beacon.deviceAddress + " Time is " + (time - beacon.lastSeenTimestamp));
}
}
removeHandler.postDelayed(this, onLostTimeoutMillis);
}
};
}
Вот журналы, которые я наблюдал для сканирования. Даже после того, как сканирование маяков остановлено, они продолжают появляться.
12-25 22:27:59.103 30207-30207/com.robocats.main I/BlankFragment: Visibility turned ON
12-25 22:27:59.104 30207-30207/com.robocats.main I/BlankFragment: Starting scanning
12-25 22:27:59.105 30207-30207/com.robocats.main I/BlankFragment: State of region changed 0
12-25 22:27:59.105 30207-30207/com.robocats.main I/BlankFragment: State of region changed 0
12-25 22:27:59.105 30207-30207/com.robocats.main I/BlankFragment: State of region changed 0
12-25 22:27:59.105 30207-30207/com.robocats.main I/BlankFragment: State of region changed 0
12-25 22:27:59.105 30207-30207/com.robocats.main I/BlankFragment: State of region changed 0
12-25 22:27:59.105 30207-30207/com.robocats.main I/BlankFragment: State of region changed 0
12-25 22:27:59.105 30207-30207/com.robocats.main I/BlankFragment: State of region changed 0
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: State of region changed 1
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: In beacon region
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: State of region changed 1
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: In beacon region
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: State of region changed 1
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: In beacon region
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: State of region changed 1
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: In beacon region
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: State of region changed 1
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: In beacon region
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: State of region changed 1
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: In beacon region
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: State of region changed 1
12-25 22:28:00.061 30207-2969/com.robocats.main I/BlankFragment: In beacon region
12-25 22:28:09.515 30207-30207/com.robocats.main D/BlankFragment: Removing beacon 0C:F3:EE:09:3A:77 Time is 15036
12-25 22:28:09.642 30207-30207/com.robocats.main D/BlankFragment: Removing beacon 0C:F3:EE:09:3A:77 Time is 15161
12-25 22:28:13.497 30207-3224/com.robocats.main D/BlankFragment: New Beacon added 6bd54ac521c218b8f418000000000073 DeviceAddress 0C:F3:EE:09:3A:77
12-25 22:28:13.510 30207-3224/com.robocats.main D/BlankFragment: New Beacon added 6bd54ac521c218b8f418000000000073 DeviceAddress 0C:F3:EE:09:3A:77
12-25 22:28:19.086 30207-3381/com.robocats.main D/BlankFragment: New Beacon added 2f234454f4911ba9ffa100000d5181da DeviceAddress 0C:F3:EE:09:3C:63
12-25 22:28:19.096 30207-3381/com.robocats.main D/BlankFragment: New Beacon added 2f234454f4911ba9ffa100000d5181da DeviceAddress 0C:F3:EE:09:3C:63
12-25 22:28:22.886 30207-30207/com.robocats.main I/BlankFragment: Visibility turned off
12-25 22:28:22.887 30207-30207/com.robocats.main I/BlankFragment: Stopping scanning
12-25 22:28:23.586 30207-3468/com.robocats.main D/BlankFragment: New Beacon added 2f234454f4911ba9ffa100000d5181da DeviceAddress 0C:F3:EE:09:3C:63
12-25 22:28:23.589 30207-3468/com.robocats.main D/BlankFragment: New Beacon added 4b3833f4b99a463283e84bfcc601a926 DeviceAddress 48:59:02:49:FA:3F
12-25 22:28:24.706 30207-3483/com.robocats.main D/BlankFragment: New Beacon added 6bd54ac521c218b8f418000000000073 DeviceAddress 0C:F3:EE:09:3A:77
По какой-то причине, я вижу, что код внутри onBeaconServiceConnect() работает в два раза. Это может быть причиной. Позвольте мне знать, почему это могло произойти.
Код выглядит нормально. Вы говорите, что продолжаете получать разнообразные обратные вызовы, несмотря на то, что вы остановитесь? Добавление строки журнала в диапазон обратного вызова и добавление выдержки из LogCat может оказаться полезным для выяснения того, что происходит. – davidgyoung
Да, я получаю диапазон обратных вызовов даже после остановки диапазона. Написал LogCat, чтобы помочь вам лучше понять. Взгляни, пожалуйста. –