davidgyoung / android-beacon-library-reference-kotlin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Minimal reproducbible example stops detecting HolyIoT beacons after screen is locked

egeres opened this issue · comments

commented

Context:
I bought a small beacon from Aliexpress that uses the NRF52810 chip and a different beacon based on the NRF51822 from Amazon, both are supposed to be ibeacons. I attempted to create a minimal working example (I'm new to Kotlin, so I'm probably making a lot of mistakes) that just ranges the beacons. This works with no problem when I launch the code, and even if I switch the context to a different app. However, when I lock my screen, the Aliexpress beacon stops being detected, but the Amazon one keeps being detected. I quite can't tell if this is a library bug, if it's caused by my bad code, or if it comes from hardware...

Code:

import android.app.*
import android.content.*
import android.os.*
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationCompat
import androidx.lifecycle.Observer
import org.altbeacon.beacon.*

class BeaconService : Service(), BeaconConsumer {

    private lateinit var wakeLock: PowerManager.WakeLock
    private lateinit var beaconManager: BeaconManager
    private val FOREGROUND_NOTIFICATION_ID = 1
    private val CHANNEL_ID = "BeaconServiceChannel"
    private val TAG = "MainActivity"

    private val centralRangingObserver = Observer<Collection<Beacon>> { beacons ->
        Log.d(TAG, "Ranged: ${beacons.count()} beacons")
    }

    private fun createNotification(): Notification {
        val builder = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("My App")
            .setContentText("Scanning for beacons...")
            .setSmallIcon(R.drawable.ic_notification_0)
        return builder.build()
    }

    override fun onCreate() {
        super.onCreate()

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(CHANNEL_ID, "Beacon Service Channel", NotificationManager.IMPORTANCE_DEFAULT)
            getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
        }

        beaconManager = BeaconManager.getInstanceForApplication(this)
        beaconManager.getBeaconParsers().clear()
        beaconManager.getBeaconParsers().add(BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"))
        beaconManager.backgroundBetweenScanPeriod = 0
        beaconManager.backgroundScanPeriod        = 3000
        beaconManager.foregroundBetweenScanPeriod = 0
        beaconManager.foregroundScanPeriod        = 3000
        beaconManager.enableForegroundServiceScanning(createNotification(), FOREGROUND_NOTIFICATION_ID)
        beaconManager.setEnableScheduledScanJobs(false)

        val region = Region("all-beacons", null, null, null)
        val regionViewModel = BeaconManager.getInstanceForApplication(this).getRegionViewModel(region)
        regionViewModel.rangedBeacons.observeForever(centralRangingObserver)
        beaconManager.startRangingBeacons(region)
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        super.onStartCommand(intent, flags, startId)

        val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::MyWakelockTag")
        wakeLock.acquire()

        beaconManager.bind(this)

        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("My App")
            .setContentText("Scanning for beacons...")
            .setSmallIcon(R.drawable.ic_notification_0)
            .build()
        startForeground(1, notification)

        return START_STICKY
    }

    override fun onDestroy() {
        super.onDestroy()
        wakeLock.release()
        beaconManager.unbind(this) // Stop scanning for beacons
    }

    override fun onBeaconServiceConnect() {}
    override fun onBind(intent: Intent?): IBinder? { TODO("Not implemented yet") }
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val serviceIntent = Intent(this, BeaconService::class.java)
        startService(serviceIntent)
    }
}

It's not like the log output yields much new insight, but it looks like this:

2023-03-13 08:45:36.164 5494-5494/com.example.personal_beacon D/MainActivity: Ranged: 2 beacons
2023-03-13 08:45:39.172 5494-5494/com.example.personal_beacon D/MainActivity: Ranged: 2 beacons
2023-03-13 08:45:42.179 5494-5494/com.example.personal_beacon D/MainActivity: Ranged: 2 beacons (after this point the screen is locked)
2023-03-13 08:45:45.195 5494-5494/com.example.personal_beacon D/MainActivity: Ranged: 1 beacons
2023-03-13 08:45:48.204 5494-5494/com.example.personal_beacon D/MainActivity: Ranged: 1 beacons
2023-03-13 08:45:51.215 5494-5494/com.example.personal_beacon D/MainActivity: Ranged: 1 beacons
commented

Woops, wrong repo 🤦🏻‍♂️