Геозоны с Compose BroadcastReceiverAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Геозоны с Compose BroadcastReceiver

Сообщение Anonymous »

Я пытаюсь настроить некоторые геозоны, а затем уведомляю через BroadcastReceiver всякий раз, когда происходит выход или вход в какую-либо геозону. Geofence API должен инициировать события при входе и выходе из геозоны, но он не работает. Более того, я также пробовал срабатывать, как только оно зарегистрировано при статической установке моего текущего местоположения, но тоже не получается. Я делаю это с помощью Compose но нет возможности получить какое-либо событие... мой код выглядит следующим образом, учитывая, что я уже запросил разрешения и предоставил их:
Компонуемый приемник:
@Composable
fun GeofenceBroadcastReceiver(
systemAction: String,
systemEvent: (userActivity: String) -> Unit,
) {
val TAG = "GeofenceBroadcastReceiver"
val context = LocalContext.current
val currentSystemOnEvent by rememberUpdatedState(systemEvent)

DisposableEffect(context, systemAction) {
val intentFilter = IntentFilter(systemAction)
val broadcast = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val geofencingEvent = intent?.let { GeofencingEvent.fromIntent(it) } ?: return

if (geofencingEvent.hasError()) {
val errorMessage =
GeofenceStatusCodes.getStatusCodeString(geofencingEvent.errorCode)
Log.e(TAG, "onReceive: $errorMessage")
return
}

val alertString = "Geofence Alert :" +
" Trigger ${geofencingEvent.triggeringGeofences}" +
" Transition ${geofencingEvent.geofenceTransition}"
Log.d(TAG, alertString)
currentSystemOnEvent(alertString)
}
}

ContextCompat.registerReceiver(
context,
broadcast,
intentFilter,
ContextCompat.RECEIVER_NOT_EXPORTED
)

onDispose {
context.unregisterReceiver(broadcast)
}
}


Компонуемый экран
@Composable
private fun GeofencingControls() {
val context = LocalContext.current
val scope = rememberCoroutineScope()
val geofenceHelper = remember { GeofenceHelper(context) }
var geofenceTransitionEventInfo by remember { mutableStateOf(String.empty()) }

DisposableEffect(LocalLifecycleOwner.current) {
onDispose {
scope.launch(Dispatchers.IO) {
geofenceHelper.unregisterGeofence()
}
}
}

// Register a local broadcast to receive activity transition updates
GeofenceBroadcastReceiver(systemAction = CUSTOM_INTENT_GEOFENCE) { event ->
geofenceTransitionEventInfo = event
Toast.makeText(context, "Geofence EVENT RECEIVED $event", Toast.LENGTH_LONG).show()
}

Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center) {
Button(onClick = {
geofenceHelper.addGeofence(
"Random",
location = Location("").apply {
latitude = 40.375159
longitude = 1.147349
}
)
}) {
Text(text = "New geofence to list")
}

Button(onClick = {
geofenceHelper.registerGeofence {
Toast.makeText(context, "Geofence registered", Toast.LENGTH_LONG).show()
}
}) {
Text(text = "Register Geofence")
}
}
}

GeofenceHelper
class GeofenceHelper(context: Context) {
private val client = LocationServices.getGeofencingClient(context)
val geofenceList = mutableMapOf()

private val geofencingPendingIntent by lazy {
val intent = Intent(CUSTOM_INTENT_GEOFENCE)
intent.setPackage(context.packageName)

PendingIntent.getBroadcast(
context,
0,
intent,
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
} else {
PendingIntent.FLAG_IMMUTABLE
}
)
}

fun addGeofence(
key: String,
location: Location,
radiusInMeters: Float = 100.0f,
expirationTimeInMillis: Long = 30 * 60 * 1000,
) {
geofenceList[key] = createGeofence(key, location, radiusInMeters, expirationTimeInMillis)
}

fun removeGeofence(key: String) {
geofenceList.remove(key)
}

@SuppressLint("MissingPermission")
fun registerGeofence(onAdded: () -> Unit = {}) {
client.addGeofences(createGeofencingRequest(), geofencingPendingIntent)
.addOnSuccessListener {
Log.d(TAG, "registerGeofence: SUCCESS")
onAdded()
}.addOnFailureListener { exception ->
Log.d(TAG, "registerGeofence: Failure\n$exception")
}
}

suspend fun unregisterGeofence() = runCatching {
client.removeGeofences(geofencingPendingIntent).await()
geofenceList.clear()
}

private fun createGeofencingRequest(): GeofencingRequest {
return GeofencingRequest.Builder().apply {
addGeofences(geofenceList.values.toList())
setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
}.build()
}

private fun createGeofence(
key: String,
location: Location,
radiusInMeters: Float,
expirationTimeInMillis: Long,
): Geofence {
return Geofence.Builder()
.setRequestId(key)
.setTransitionTypes(GEOFENCE_TRANSITION_ENTER or GEOFENCE_TRANSITION_EXIT)
.setCircularRegion(location.latitude, location.longitude, radiusInMeters)
.setExpirationDuration(expirationTimeInMillis)
.build()
}

companion object {
private const val TAG = "GeofenceHelper"

const val CUSTOM_INTENT_GEOFENCE = "GEOFENCE-TRANSITION-INTENT-ACTION"
}
}


Подробнее здесь: https://stackoverflow.com/questions/792 ... streceiver
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»