Altbeacon не находит маяки на android 8+ - PullRequest
0 голосов
/ 21 января 2020

Я использую маяк Alt в своем проекте для обнаружения маяков, он отлично работает на моем Samsung s7 (Android 7), но на Samsung 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()
}

Затем внутри моего кода запуска маяка включается Bluetooth, и я создаю свой менеджер маяков

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.")
            }

        }

    }

}

Как только маяк привязан, я запускаю некоторые logi c в моем onBeaconServiceConnect для отправки аналитику c, когда я нахожу маяк

  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()
        }


    }

Ответы [ 3 ]

0 голосов
/ 21 января 2020

Я знаю, потому что у меня были проблемы, когда я работал с Beacons, что для устройств под управлением Oreo и выше фоновая задача не работает.

Для этих устройств я использовал JobScheduler ....

Это учебник об этом https://www.youtube.com/watch?v=3EQWmME-hNA

Я надеюсь, что это поможет вам;)

Удачи

0 голосов
/ 21 января 2020

Причина, по которой это не сработало, заключается в том, что я привязывал маяк до фактического добавления макета маяка ...

До:

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)
0 голосов
/ 21 января 2020

Эта проблема, вероятно, не имеет ничего общего с библиотекой маяков Android и просто связана с ограничениями операционной системы Android на использование таймеров на Android 8+.

Начиная с версии 8, приложения Android завершаются операционной системой через 10 минут фонового выполнения, если ForegroundService не активен. Поэтому этот таймер НИКОГДА не сработает, если вы не будете держать экран включенным, разблокированным и приложение, видимое на экране: handler.postDelayed(this, 1200000) // 20 Minutes

Вы можете изменить свою архитектуру, чтобы она работала на Android 8+, или Вы можете настроить библиотеку на использование встроенного ForegroundService, чтобы обойти ограничение. См. здесь для получения инструкций.

...