I am using https://github.com/AltBeacon/android-beacon-library library to detect iBeacon. But sometimes RangingBeacons
returns zero.
My application runs as follows:
Call startRangingBeacons
to detect the iBeacon. After getting the beacon, call stopRangingBeacons
.
And User can call startRangingBeacons
function again to detect other iBeacon.
This is the case quite often. Sometimes after a few seconds the detection can return to normal, but sometimes nothing can be detected.
class EllaBeaconManger(context: Context) : MonitorNotifier {
private var currentContext: Context = context
private val mBeaconManager: BeaconManager = BeaconManager.getInstanceForApplication(context)
private val mRegion: Region = Region("*Masked*", Identifier.parse("*Masked*"), null, null)
var didDetectElla: ((deviceId: String) -> Unit)? = null
private var canFindBeacon: Boolean = false
lateinit var activity: MainActivity
// I don't know why but when I call startBeacon again,
// the library will sometimes return the result that the Beacon was previously connected.
private var count = 0
companion object : SingletonHolder<EllaBeaconManger, Context>(::EllaBeaconManger)
private val rangingObserver = Observer<Collection<Beacon>> { beacons ->
if (BeaconManager.getInstanceForApplication(context).rangedRegions.isNotEmpty()) {
if(beacons.isNotEmpty()) {
for (beacon in beacons) {
val statusBeacon = EllaManager.shared.deviceIdByMajor(beacon.id2.toInt())
if (statusBeacon != null && statusBeacon == EllaStatus.UNAUTHORIZED) {
if (beacon.distance <= 1.0 && !canFindBeacon && count >= 1) {
stopBeacon()
val deviceId = EllaManager.shared.deviceId(beacon.id2.toInt(), beacon.id3.toInt(), EllaManager.environment)
didDetectElla?.invoke(deviceId)
} else {
count++
}
}
}
}
}
}
fun initBeacon() {
mBeaconManager.beaconParsers.clear()
mBeaconManager.beaconParsers.add(BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"))
// Set up a Live Data observer for beacon data
val regionViewModel = mBeaconManager.getRegionViewModel(mRegion)
// observer will be called each time a new list of beacons is ranged (typically ~1 second in the foreground)
regionViewModel.rangedBeacons.observe(activity, rangingObserver)
}
fun startBeacon() {
canFindBeacon = false
count = 0
mBeaconManager.startRangingBeacons(mRegion)
}
fun stopBeacon() {
canFindBeacon = true
count = 0
mBeaconManager.stopRangingBeacons(mRegion)
}
override fun didEnterRegion(region: Region?) {
if (region != null) {
Log.d("ToiHK", "I detected a beacon in the region with namespace id " + region.id1 +
" and instance id: " + region.id2
)
}
}
override fun didExitRegion(region: Region?) {
Log.d("ToiHK", "I Exit a beacon in the region with namespace id " + region?.id1 +
" and instance id: " + region?.id2
)
}
override fun didDetermineStateForRegion(state: Int, region: Region?) {
Log.d("ToiHK", "I State $state a beacon in the region with namespace id " + region?.id1 +
" and instance id: " + region?.id2
)
}
}