package my.package.ble
import android.bluetooth.BluetoothManager
import android.content.Context
import android.location.LocationManager
import android.util.Log
import androidx.core.location.LocationManagerCompat
import fr.maxcom.beacon.error.ScannerError
import fr.maxcom.beacon.log.LogLevel
import fr.maxcom.beacon.log.Logger
import fr.maxcom.beacon.manager.ProximityManager
import fr.maxcom.beacon.service.IScannerCallback
import fr.maxcom.libbeacon.Licensing
import my.package.BuildConfig
class ScannerManager(private val mContext: Context) {
private val mProximityManager = ProximityManager(mContext)
val isBluetoothDisabled: Boolean
get() {
val btAdapter = (mContext.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager).adapter
return btAdapter == null || !btAdapter.isEnabled
}
val isLocationDisabled: Boolean
get() = !LocationManagerCompat.isLocationEnabled((mContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager))
fun setUp(cfg: Configuration, statusCallback: IStatusCallback?) {
if (BuildConfig.DEBUG) Log.d(TAG, "setUp")
cfg.clear() // cleanup the stores of a possible previous run
configureScanner(cfg)
val listener = cfg.scanStatusListener
listener?.verbose = cfg.verbose
mProximityManager.setUp(
listener,
createScannerCallback(statusCallback),
null, null, null
)
}
private fun configureScanner(cfg: Configuration) {
val gc = mProximityManager.configuration()
gc
.preventDoze(cfg.preventDoze)
.verbose(cfg.verbose)
.scanFrequency(cfg.scanFrequency)
val interval = cfg.reminderIntervalSeconds
if (interval > 0) gc.reminderInterval(interval)
val scanMode = cfg.scanMode
if (scanMode != null) gc.scanMode(scanMode)
val rssiCalculator = cfg.rssiCalculator
if (rssiCalculator != null) gc.rssiCalculator(rssiCalculator)
val devicesUpdateEventSlowdown = cfg.devicesUpdateEventSlowdown
if (devicesUpdateEventSlowdown != -1L) gc.devicesUpdateEventSlowdown(devicesUpdateEventSlowdown)
val registrar = mProximityManager.registrar()
cfg.processors?.forEach { registrar.registerProcessor(it) }
cfg.processorPlugins?.forEach { registrar.registerProcessorPlugin(it) }
cfg.explorerPlugins?.forEach { registrar.registerExplorerPlugin(it) }
cfg.parserPlugins?.forEach { registrar.registerParserPlugin(it) }
}
fun tearDown(statusCallback: IStatusCallback? = null) {
if (BuildConfig.DEBUG) Log.d(TAG, "tearDown")
mProximityManager.tearDown(createScannerCallback(statusCallback))
}
private fun createScannerCallback(cb: IStatusCallback?): IScannerCallback? {
return if (cb == null) null else object : IScannerCallback {
override fun onStarted() {
if (BuildConfig.DEBUG) Log.d(TAG, "result onStarted")
cb.onResult(true)
}
override fun onStopped() {
if (BuildConfig.DEBUG) Log.d(TAG, "result onStopped")
cb.onResult(false)
}
override fun onError(error: ScannerError) {
if (BuildConfig.DEBUG) Log.d(TAG, "result onError $error")
val message = ErrorCodeMessages[error.ordinal, error.toString()]
cb.onError(message)
}
}
}
companion object {
private val TAG = ScannerManager::class.java.simpleName
fun init(context: Context) {
Log.i(TAG, "init")
Licensing.allow(context) // mandatory call to allow further calls to the library
Licensing.developerMode = true // log some traces, only useful for a debugging session
// By default, all levels are enabled, which is helpful for development.
// For a production release, it is advised to discard low level traces.
if (!BuildConfig.DEBUG) Logger.mute(true, LogLevel.DEBUG, LogLevel.VERBOSE)
}
}
}
package my.package.ble
import android.util.SparseArray
import fr.maxcom.beacon.error.ScannerError
/**
* A static mapping from error codes to human readable strings (for UI and logcat).
*/
object ErrorCodeMessages : SparseArray<String>() {
init {
// from ProximityManager
append(ScannerError.UNEXPECTED_ONSTARTED.ordinal, "Unexpected onStarted event for a stop request")
append(ScannerError.OPERATION_ALREADY_IN_PROGRESS.ordinal, "Operation already in progress")
append(ScannerError.ALREADY_STOPPED.ordinal, "Scan already stopped")
append(ScannerError.UNABLE_TO_BIND_TO_SERVICE.ordinal, "Unabled to bind to the service")
append(ScannerError.UNABLE_TO_START_SERVICE.ordinal, "Unabled to start the service")
// from ProximityService
append(ScannerError.NO_BT_ADAPTER.ordinal, "No Bluetooth adaptor")
append(ScannerError.UNEXPECTEDLY_STILL_NOT_RUNNING.ordinal, "Scan unexpectedly still not running")
append(ScannerError.UNEXPECTEDLY_STILL_RUNNING.ordinal, "Scan unexpectedly still running")
}
}