因此,我正在构建一个应用程序,当收到Firebase的消息时,需要异步添加Geofences。该消息是在FirebaseMessagingService
(扩展为EnhancedIntentService
)上接收的。从那时起,我按照this指南中所述创建地理围栏。但是,即使我确定已正确添加地理围栏,也无法在IntentService上重新获得任何意图。我觉得原因是我的PendingIntent
中的FirebaseMessagingService
由于无法在适当的上下文中通过而无法正常工作,但是我不确定解决方案是什么。我尝试使用BroadcastReceiver
来代替,因为可以通过一个动作来触发它,但是也不会产生任何结果。
我创建地理围栏的FirebaseMessagingService
:
class EventStatusMessagingService : FirebaseMessagingService() {
private lateinit var geoFencingClient: GeofencingClient
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
remoteMessage?.data?.isNotEmpty()?.let {
val data = remoteMessage.data
// Create GeoFence w/ data
geoFencingClient = LocationServices.getGeofencingClient(this)
val geoFence = createGeofence(data, remoteMessage.from!!.replace("/topic",""))
val geoFenceRequest = getGeoFencingRequest(geoFence)
if(ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
geoFencingClient.addGeofences(geoFenceRequest, geoFencingPendingIntent)?.run {
addOnSuccessListener {
Log.i("test", "Successfully added GeoFences")
}
addOnFailureListener {
Log.w("test", "Could not add GeoFences")
}
}
}
}
}
private fun createGeofence(data: Map<String, String>, key: String): Geofence {
return Geofence.Builder().apply {
setRequestId(key)
setCircularRegion(
data.getValue("latitude").toDouble(),
data.getValue("longitude").toDouble(),
data.getValue("radius").toFloat()
)
setExpirationDuration(data.getValue("duration").toLong() * 3600000) // to Milliseconds
setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT
or Geofence.GEOFENCE_TRANSITION_DWELL)
setLoiteringDelay(120000)
}.build()
}
private fun getGeoFencingRequest(geoFence: Geofence) : GeofencingRequest {
return GeofencingRequest.Builder().apply {
setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
addGeofence(geoFence)
}.build()
}
private val geoFencingPendingIntent: PendingIntent by lazy {
val intent = Intent(applicationContext, GeoFenceIntentService::class.java)
PendingIntent.getService(applicationContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
}
我的准系统IntentService仅用于测试
class GeoFenceIntentService : IntentService("GeoFenceService") {
override fun onHandleIntent(intent: Intent?) {
Log.d("test", "got geofence callback")
val geoFencingEvent = GeofencingEvent.fromIntent(intent)
when(geoFencingEvent.geofenceTransition) {
Geofence.GEOFENCE_TRANSITION_ENTER -> {
}
Geofence.GEOFENCE_TRANSITION_EXIT -> {
}
Geofence.GEOFENCE_TRANSITION_DWELL -> {
}
}
}
}
是的,我已将服务添加到AndroidManifest.xml
<service
android:name=".gps.services.GeoFenceIntentService"/>
<service
android:name=".events.services.EventStatusMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
我来自Messaging服务的Log.i
消息确实出现在控制台中,但是无论我如何测试它,都没有出现来自IntentService的日志消息。
从我收集到的信息来看,问题在于尝试从另一个Service启动IntentService,但是我不确定应该如何解决。我还尝试了从applicationContext
到baseContext
到this
的切换,都无济于事。
真的不可能吗?如果是这样,如果我要像这样初始化Geofences,应该采取什么策略?