Created
April 14, 2021 00:32
-
-
Save y-takagi/fe1b5aa36c9319c5cb006dcf6834001b to your computer and use it in GitHub Desktop.
iBeacon Plugin for capacitor2.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.ionic.starter.plugins | |
import android.Manifest | |
import android.content.Context | |
import android.content.Intent | |
import android.content.ServiceConnection | |
import android.content.pm.PackageManager | |
import com.getcapacitor.NativePlugin | |
import com.getcapacitor.Plugin | |
import com.getcapacitor.PluginCall | |
import com.getcapacitor.PluginMethod | |
import kotlinx.serialization.Serializable | |
import kotlinx.serialization.encodeToString | |
import kotlinx.serialization.json.Json | |
import org.altbeacon.beacon.* | |
@Serializable | |
data class BeaconDto(val id: String, val uuid: String, val major: Int, val minor: Int, val rssi: Int) | |
@Serializable | |
data class BeaconsDto(val data: List<BeaconDto>) | |
@NativePlugin( | |
permissions = [Manifest.permission.ACCESS_FINE_LOCATION], | |
permissionRequestCode = 1000 | |
) | |
class BeaconPlugin : Plugin(), BeaconConsumer, MonitorNotifier, RangeNotifier { | |
private var beaconManager: BeaconManager? = null | |
override fun load() { | |
super.load() | |
beaconManager = BeaconManager.getInstanceForApplication(activity) | |
beaconManager?.also { | |
it.beaconParsers.clear() | |
it.beaconParsers.add(BeaconParser().apply { setBeaconLayout(iBEACON_FORMAT) }) | |
it.bind(this) | |
} | |
} | |
override fun handleOnDestroy() { | |
super.handleOnDestroy() | |
beaconManager?.unbind(this) | |
} | |
override fun handleRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { | |
super.handleRequestPermissionsResult(requestCode, permissions, grantResults) | |
val savedCall = savedCall ?: return | |
for (result in grantResults) { | |
if (result == PackageManager.PERMISSION_DENIED) { | |
savedCall.reject("User denied location permission") | |
return | |
} | |
} | |
savedCall.resolve() | |
savedCall.release(bridge) | |
} | |
override fun onBeaconServiceConnect() { | |
beaconManager?.removeAllMonitorNotifiers() | |
beaconManager?.removeAllRangeNotifiers() | |
beaconManager?.addMonitorNotifier(this) | |
beaconManager?.addRangeNotifier(this) | |
} | |
override fun getApplicationContext(): Context { | |
return activity | |
} | |
override fun unbindService(connection: ServiceConnection) { | |
activity.unbindService(connection) | |
} | |
override fun bindService(intent: Intent, connection: ServiceConnection, mode: Int): Boolean { | |
return activity.bindService(intent, connection, mode) | |
} | |
override fun didEnterRegion(region: Region) { | |
} | |
override fun didExitRegion(region: Region) { | |
} | |
override fun didDetermineStateForRegion(state: Int, region: Region) { | |
when (state) { | |
MonitorNotifier.INSIDE -> beaconManager?.startRangingBeaconsInRegion(region) | |
MonitorNotifier.OUTSIDE -> beaconManager?.stopRangingBeaconsInRegion(region) | |
} | |
} | |
override fun didRangeBeaconsInRegion(beacons: MutableCollection<Beacon>, region: Region) { | |
if (beacons.isEmpty()) { | |
return | |
} | |
val beaconsDto = BeaconsDto(beacons.map { BeaconDto(region.uniqueId, it.id1.toString(), it.id2.toInt(), it.id3.toInt(), it.rssi) }) | |
val json = Json.encodeToString(beaconsDto) | |
bridge.triggerWindowJSEvent("didrangebeaconsinregion", json) | |
} | |
@PluginMethod | |
fun startMonitoring(call: PluginCall) { | |
val id = call.getString("id") | |
val uuid = call.getString("uuid") | |
val major = call.getInt("major") | |
val minor = call.getInt("minor") | |
try { | |
this.startMonitoring(id, uuid, major?.toString(), minor?.toString()) | |
call.resolve() | |
} catch (e: Exception) { | |
call.reject("Fail to start beacon monitoring.", e) | |
} | |
} | |
@PluginMethod | |
fun stopMonitoring(call: PluginCall) { | |
val id = call.getString("id") | |
try { | |
this.stopMonitoring(id) | |
call.resolve() | |
} catch (e: Exception) { | |
call.reject("Fail to stop beacon monitoring.", e) | |
} | |
} | |
@PluginMethod | |
fun stopMonitoringAll(call: PluginCall) { | |
try { | |
this.stopMonitoringAll() | |
call.resolve() | |
} catch (e: Exception) { | |
call.reject("Fail to stop beacon monitoring.", e) | |
} | |
} | |
private fun startMonitoring(id: String, uuid: String? = null, major: String? = null, minor: String? = null) { | |
val region = Region( | |
id, | |
uuid?.let { Identifier.parse(it) }, | |
major?.let { Identifier.parse(it) }, | |
minor?.let { Identifier.parse(it) } | |
) | |
beaconManager?.startMonitoringBeaconsInRegion(region) | |
} | |
private fun stopMonitoring(id: String) { | |
val monitoredRegion = beaconManager?.monitoredRegions?.find { it.uniqueId == id } | |
if (monitoredRegion != null) { | |
beaconManager?.stopRangingBeaconsInRegion(monitoredRegion) | |
beaconManager?.stopMonitoringBeaconsInRegion(monitoredRegion) | |
} | |
} | |
private fun stopMonitoringAll() { | |
val monitoredRegions = beaconManager?.monitoredRegions | |
monitoredRegions?.forEach { this.stopMonitoring(it.uniqueId) } | |
} | |
companion object { | |
private const val iBEACON_FORMAT = "m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment