Altbeacon 在 android 8+ 上找不到信标
Altbeacon not finding beacons on android 8+
我在我的项目中使用 Alt beacon 来检测信标,它在我的三星 s7 (Android 7) 上运行良好,但在三星 s10、Oneplus 6 和 Google Pixel 3 上运行良好XL (Android 9/10) 它根本不起作用。
代码似乎没有找到任何信标。
我的代码以权限检查开始:
if (ContextCompat.checkSelfPermission(view, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Requesting Permission.")
openPermissionDialog()
} else {
startBeacon()
}
然后在我的启动信标代码中打开蓝牙并创建我的信标管理器
val mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
if(mBluetoothAdapter != null){
if (!mBluetoothAdapter.isEnabled) {
mBluetoothAdapter.enable()
}
Log.d(TAG, "Permissions accepted, bluetooth is on.")
model.beaconManager = BeaconManager.getInstanceForApplication(view)
BeaconController.startBeacon(model.beaconManager, view)
}
最后,在 BeaconController 内部,我有一个单例伴随对象,它将每 20 分钟绑定一次信标。这是因为当我找到信标时它会解绑
class BeaconController {
companion object {
private val TAG = "HomePresenter"
private var hasTimerStarted = false
fun startBeacon(beaconManager: BeaconManager?, view: HomeActivityView) {
if (!hasTimerStarted) {
Log.d(TAG, "Timer starting")
hasTimerStarted = true
val handler = Handler()
Thread(object : Runnable {
override fun run() {
if (beaconManager?.isBound(view) != null) {
Log.d(TAG, "Beacon binding")
beaconManager.bind(view)
beaconManager.beaconParsers.clear()
beaconManager.beaconParsers.add(BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT))
} else {
Log.d(TAG, "Beacon is bound")
}
handler.postDelayed(this, 1200000) // 20 Minutes
}
}).start()
} else {
Log.d(TAG, "Timer already started.")
}
}
}
}
绑定信标后,我 运行 我的 onBeaconServiceConnect 中的一些逻辑会在我找到信标时发送分析
override fun onBeaconServiceConnect() {
model.beaconManager?.addRangeNotifier { beacons, _ ->
if (beacons.isNotEmpty()) {
val firstBeacon = beacons.iterator().next()
val firstBeaconNameSpace = "${firstBeacon.id1}".replace("0x", "")
val firstBeaconIdentifier = "${firstBeacon.id2}".replace("0x", "")
Log.d(TAG, "Beacon $firstBeaconNameSpace - $firstBeaconIdentifier is " + firstBeacon.distance + " meters away.")
}
}
/**
* Attach
*/
try {
model.beaconManager?.startRangingBeaconsInRegion(Region("com.MYAPP.MYAPP", null, null, null))
Log.d(TAG, "Added Range Notifier")
} catch (e: RemoteException) {
Log.d(TAG, "Error adding Range Notifier")
e.printStackTrace()
}
}
该问题可能与 Android 信标库无关,仅与 Android 操作系统在 Android 8+ 上使用计时器的限制有关。
从版本 8 开始,Android 应用程序在后台执行 10 分钟后被操作系统终止,除非 ForegroundService 处于活动状态。因此,除非您保持屏幕打开、解锁并且应用程序在屏幕上可见,否则此计时器永远不会触发:handler.postDelayed(this, 1200000) // 20 Minutes
您可以更改架构以使其在 Android 8+ 上运行,或者您可以将库配置为使用其内置的 ForegroundService 来绕过限制。有关说明,请参阅 here。
我知道,因为我在使用 Beacons 时遇到了问题,对于设备 运行 Oreo 和更高版本的后台任务不起作用。
对于那些设备,我使用了 JobScheduler....
这是关于它的教程
https://www.youtube.com/watch?v=3EQWmME-hNA
希望能帮到你;)
祝你好运
这不起作用的原因是因为我在实际添加信标布局之前绑定了信标...
之前:
beaconManager?.bind(view)
beaconManager?.beaconParsers?.clear()
beaconManager?.beaconParsers?.add(BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT))
之后:
beaconManager?.beaconParsers?.clear()
beaconManager?.beaconParsers?.add(BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT))
beaconManager?.bind(view)
我在我的项目中使用 Alt beacon 来检测信标,它在我的三星 s7 (Android 7) 上运行良好,但在三星 s10、Oneplus 6 和 Google Pixel 3 上运行良好XL (Android 9/10) 它根本不起作用。
代码似乎没有找到任何信标。
我的代码以权限检查开始:
if (ContextCompat.checkSelfPermission(view, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "Requesting Permission.")
openPermissionDialog()
} else {
startBeacon()
}
然后在我的启动信标代码中打开蓝牙并创建我的信标管理器
val mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
if(mBluetoothAdapter != null){
if (!mBluetoothAdapter.isEnabled) {
mBluetoothAdapter.enable()
}
Log.d(TAG, "Permissions accepted, bluetooth is on.")
model.beaconManager = BeaconManager.getInstanceForApplication(view)
BeaconController.startBeacon(model.beaconManager, view)
}
最后,在 BeaconController 内部,我有一个单例伴随对象,它将每 20 分钟绑定一次信标。这是因为当我找到信标时它会解绑
class BeaconController {
companion object {
private val TAG = "HomePresenter"
private var hasTimerStarted = false
fun startBeacon(beaconManager: BeaconManager?, view: HomeActivityView) {
if (!hasTimerStarted) {
Log.d(TAG, "Timer starting")
hasTimerStarted = true
val handler = Handler()
Thread(object : Runnable {
override fun run() {
if (beaconManager?.isBound(view) != null) {
Log.d(TAG, "Beacon binding")
beaconManager.bind(view)
beaconManager.beaconParsers.clear()
beaconManager.beaconParsers.add(BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT))
} else {
Log.d(TAG, "Beacon is bound")
}
handler.postDelayed(this, 1200000) // 20 Minutes
}
}).start()
} else {
Log.d(TAG, "Timer already started.")
}
}
}
}
绑定信标后,我 运行 我的 onBeaconServiceConnect 中的一些逻辑会在我找到信标时发送分析
override fun onBeaconServiceConnect() {
model.beaconManager?.addRangeNotifier { beacons, _ ->
if (beacons.isNotEmpty()) {
val firstBeacon = beacons.iterator().next()
val firstBeaconNameSpace = "${firstBeacon.id1}".replace("0x", "")
val firstBeaconIdentifier = "${firstBeacon.id2}".replace("0x", "")
Log.d(TAG, "Beacon $firstBeaconNameSpace - $firstBeaconIdentifier is " + firstBeacon.distance + " meters away.")
}
}
/**
* Attach
*/
try {
model.beaconManager?.startRangingBeaconsInRegion(Region("com.MYAPP.MYAPP", null, null, null))
Log.d(TAG, "Added Range Notifier")
} catch (e: RemoteException) {
Log.d(TAG, "Error adding Range Notifier")
e.printStackTrace()
}
}
该问题可能与 Android 信标库无关,仅与 Android 操作系统在 Android 8+ 上使用计时器的限制有关。
从版本 8 开始,Android 应用程序在后台执行 10 分钟后被操作系统终止,除非 ForegroundService 处于活动状态。因此,除非您保持屏幕打开、解锁并且应用程序在屏幕上可见,否则此计时器永远不会触发:handler.postDelayed(this, 1200000) // 20 Minutes
您可以更改架构以使其在 Android 8+ 上运行,或者您可以将库配置为使用其内置的 ForegroundService 来绕过限制。有关说明,请参阅 here。
我知道,因为我在使用 Beacons 时遇到了问题,对于设备 运行 Oreo 和更高版本的后台任务不起作用。
对于那些设备,我使用了 JobScheduler....
这是关于它的教程 https://www.youtube.com/watch?v=3EQWmME-hNA
希望能帮到你;)
祝你好运
这不起作用的原因是因为我在实际添加信标布局之前绑定了信标...
之前:
beaconManager?.bind(view)
beaconManager?.beaconParsers?.clear()
beaconManager?.beaconParsers?.add(BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT))
之后:
beaconManager?.beaconParsers?.clear()
beaconManager?.beaconParsers?.add(BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT))
beaconManager?.bind(view)