在Android 8或9上的背景中进行地理围栏不起作用
作者:互联网
当他到达定义的区域时,我尝试向用户显示推送警报.
所以我编写了我的应用程序:https://developer.android.com/training/location/geofencing
如果我的应用程序在用户位置之后运行服务,它可以正常工作.
如果我开始谷歌地图,它也会工作,也会跟踪我的位置.推送会出现.
但是,如果我关闭我的应用程序,则不会显示推送,因此如果没有应用程序跟踪我的位置,则无法检测到地理围栏.
这是正常的吗?
如何让它始终有效?
如果您需要在您的位置之后使用前台服务,那么地理围栏的重点是什么?
public void createGeofenceAlerts(LatLng latLng, int radius) {
final Geofence enter = buildGeofence(ID_ENTER, latLng, radius, Geofence.GEOFENCE_TRANSITION_ENTER);
final Geofence exit = buildGeofence(ID_EXIT, latLng, radius, Geofence.GEOFENCE_TRANSITION_EXIT);
final Geofence dwell = buildGeofence(ID_DWELL, latLng, radius, Geofence.GEOFENCE_TRANSITION_DWELL);
GeofencingRequest request = new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofence(enter)
.addGeofence(exit)
.addGeofence(dwell)
.build();
fencingClient.addGeofences(request, getGeofencePendingIntent()).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Timber.i("succes");
Toast.makeText(mContext, "Geofence added", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Timber.e(e,"failure");
Toast.makeText(mContext, "Geofence ERROR", Toast.LENGTH_LONG).show();
}
});
}
private PendingIntent getGeofencePendingIntent() {
Intent intent = new Intent(mContext, GeofenceTransitionsIntentService.class);
PendingIntent pending = PendingIntent.getService(
mContext,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
return pending;
}
private Geofence buildGeofence(String id, LatLng center, int radius, int transitionType) {
Geofence.Builder builder = new Geofence.Builder()
// 1
.setRequestId(id)
// 2
.setCircularRegion(
center.getLatitude(),
center.getLongitude(),
radius)
// 3
.setTransitionTypes(transitionType)
// 4
.setExpirationDuration(Geofence.NEVER_EXPIRE);
if (transitionType == Geofence.GEOFENCE_TRANSITION_DWELL) {
builder.setLoiteringDelay(LOITERING_DELAY);
}
return builder.build();
}
解决方法:
我想我找到了一个在Android 9上测试过的解决方案.我使用了Google文档https://developer.android.com/training/location/geofencing但是我用广播接收器替换了这个服务.
我的GeofenceManager:
private val braodcastPendingIntent: PendingIntent
get() {
val intent = Intent(mContext, GeofenceTransitionsBroadcastReceiver::class.java)
val pending = PendingIntent.getBroadcast(
mContext.applicationContext,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT)
return pending
}
fun createGeofenceAlerts(latLng: LatLng, radiusMeter: Int, isBroadcast: Boolean) {
val enter = buildGeofence(ID_ENTER, latLng, radiusMeter, Geofence.GEOFENCE_TRANSITION_ENTER)
val exit = buildGeofence(ID_EXIT, latLng, radiusMeter, Geofence.GEOFENCE_TRANSITION_EXIT)
val dwell = buildGeofence(ID_DWELL, latLng, radiusMeter, Geofence.GEOFENCE_TRANSITION_DWELL)
val request = GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofence(enter)
.addGeofence(exit)
.addGeofence(dwell)
.build()
val pending = if (isBroadcast) {
braodcastPendingIntent
} else {
servicePendingIntent
}
fencingClient.addGeofences(request, pending).addOnSuccessListener {
Timber.i("succes")
Toast.makeText(mContext, "Geofence added", Toast.LENGTH_LONG).show()
}.addOnFailureListener { e ->
Timber.e(e, "failure")
Toast.makeText(mContext, "Geofence ERROR", Toast.LENGTH_LONG).show()
}
}
private fun buildGeofence(id: String, center: LatLng, radius: Int, transitionType: Int): Geofence {
val builder = Geofence.Builder()
// 1
.setRequestId(id)
// 2
.setCircularRegion(
center.latitude,
center.longitude,
radius.toFloat())
// 3
.setTransitionTypes(transitionType)
// 4
.setExpirationDuration(Geofence.NEVER_EXPIRE)
if (transitionType == Geofence.GEOFENCE_TRANSITION_DWELL) {
builder.setLoiteringDelay(LOITERING_DELAY)
}
return builder.build()
}
我的BroadcastReceiver,显然你需要在manfifest中声明它:
class GeofenceTransitionsBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Timber.i("received")
val geofencingEvent = GeofencingEvent.fromIntent(intent)
if (geofencingEvent.hasError()) {
Timber.e("Geofence error")
return
}
// Get the transition type.
val geofenceTransition = geofencingEvent.geofenceTransition
// Test that the reported transition was of interest.
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT
|| geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL) {
// Get the geofences that were triggered. A single event can trigger
// multiple geofences.
val triggeringGeofences = geofencingEvent.triggeringGeofences
// Get the transition details as a String.
val geofenceTransitionDetails = GeofenceManager.getGeofenceTransitionDetails(
geofenceTransition,
triggeringGeofences, true
)
// Send notification and log the transition details.
GeofenceManager.sendNotification(context, geofenceTransition, geofenceTransitionDetails)
Timber.i(geofenceTransitionDetails)
} else {
// Log the error.
Timber.e("Unknown geo event : %d", geofenceTransition)
}
}
重要的是要知道在Android 8和9上,地理围栏的延迟时间为2分钟.
标签:geofencing,android,background,location,maps 来源: https://codeday.me/bug/20191008/1873566.html