GeoFence触发问题
我在我的应用中设置了地理围栏, 我正在使用IntetnService来处理句柄触发事件。
我的问题是多次触发事件。
假设我在Geofence内的1个位置,不幸的是有时进入或退出事件触发器, 然后我想检查geoEvent.getTriggerdLocation()属性并检查geo fence radius,
如果触发位置到地理围栏位置距离大于geofecen半径然后我将释放我的退出事件功能,
但最终地理围栏触发事件2 3 km远甚至我已进入围栏,我的上述逻辑将失败。见snap
我想要一些可靠的解决方案。
位置已启用高优先级
当我接近栅栏的边界时,这将发生更多添加地理围栏列表,截至目前我只使用一个围栏。
mGeofenceList.add(new Geofence.Builder().setRequestId(String.valueOf(loGeoFenceModels.liGeoFenceID))
.setCircularRegion(loGeoFenceModels.ldGeoLatitude, loGeoFenceModels.ldGeoLongitude,
loGeoFenceModels.lfRadius)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
PendidngIntentService
moGeofencePendingIntent = getGeofencePendingIntent();
LocationServices.GeofencingApi
.addGeofences(moLocationClient, getGeofencingRequest(), moGeofencePendingIntent)
.setResultCallback(this);
getGeofencingRequest()和moGeofencePendingIntent
private GeofencingRequest getGeofencingRequest() {
return new GeofencingRequest.Builder().setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofences(mGeofenceList).build();
}
private PendingIntent getGeofencePendingIntent() {
// Reuse the PendingIntent if we already have it.
if (moGeofencePendingIntent != null) {
return moGeofencePendingIntent;
}
Intent intent = new Intent(moContext, GeofenceTransitionsIntentService.class);
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent
// back when calling addgeoFences()
return PendingIntent.getService(moContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
GeofenceTransitionsIntentService.class
import java.util.ArrayList;
import java.util.List;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofenceStatusCodes;
import com.google.android.gms.location.GeofencingEvent;
import android.R.bool;
import android.app.IntentService;
import android.app.usage.UsageEvents.Event;
import android.content.Intent;
import android.database.Cursor;
import android.location.Location;
import android.text.TextUtils;
public class GeofenceTransitionsIntentService extends IntentService {
protected static final String TAG = "GeofenceTransitionsIS";
public GeofenceTransitionsIntentService() {
super(TAG); // use TAG to name the IntentService worker thread
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
private static String getGeofenceTransitionDetails(GeofencingEvent event) {
String transitionString = GeofenceStatusCodes.getStatusCodeString(event.getGeofenceTransition());
List<String> triggeringIDs = new ArrayList<String>();
for (Geofence geofence : event.getTriggeringGeofences()) {
triggeringIDs.add(geofence.getRequestId());
}
return String.format("%s: %s", transitionString, TextUtils.join(", ", triggeringIDs));
}
@Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent event = GeofencingEvent.fromIntent(intent);
Log.i(TAG, "Geofencing Event : " + event);
if (event.hasError()) {
Log.i(TAG, "GeofencingEvent Error : " + event.getErrorCode());
return;
}
// Get the type of transition (entry or exit)
if (event.getGeofenceTransition() == Geofence.GEOFENCE_TRANSITION_ENTER) {
Log.i(TAG, "GeofencingEvent Enter");
}
if (event.getGeofenceTransition() == Geofence.GEOFENCE_TRANSITION_EXIT) {
Log.i(TAG, "GeofencingEvent Exit");
?
String description = getGeofenceTransitionDetails(event);
Log.i(TAG, "GeofencingEvent description : " + description);
}
}
权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.hardware.location.gps" />
我坚持这个问题很多天,请帮助完成这个问题。
答案 0 :(得分:0)
在Geofence
Application
时,请注意以下几点
来自官方documentation
为获得最佳效果,应设置地理围栏的最小半径 在100 - 150米之间。当Wi-Fi可用时,位置准确性是 通常在20-50米之间。当室内位置可用时, 精度范围可小至5米。除非你知道室内 位于地理围栏内的位置,假设Wi-Fi位置 精度约为50米。
当Wi-Fi位置不可用时(例如,当你的时候 在农村地区开车)位置准确性降低。准确性 范围可以达到几百米到几公里。 在这种情况下,您应该使用更大的半径创建地理围栏。
如果您在短暂驾车时收到大量警报 地理围栏,减少警报的最佳方法是使用过渡 GEOFENCE_TRANSITION_DWELL的类型而不是 GEOFENCE_TRANSITION_ENTER。这样,仅发送住宅警报 当用户在地理围栏内停留一段时间。您 可以通过设置游荡延迟来选择持续时间。
答案 1 :(得分:0)
找到一个补丁,以避免不必要的或虚假的事件。
您可以在触发时间获取位置
Location loTriggerGeoFenceLocation = moEvent.getTriggeringLocation();
long ldAccuracy = loTriggerGeoFenceLocation.getAccuracy();
现在存储您的地理围栏位置纬度和半径。 不要长时间触发lat并检查触发位置和geo fence位置lat之间的距离。如果距离小于半径则应该是输入,距离是半径,它应该是退出事件
if (event.getGeofenceTransition() == Geofence.GEOFENCE_TRANSITION_EXIT) {
ldGeoLatLong = moSharedPreferenceManager.getGeoFenceTimeLocation();
Location loExistGeoFenceLocation = new Location("");
loExistGeoFenceLocation.setLatitude(ldGeoLatLong[0]);
loExistGeoFenceLocation.setLongitude(ldGeoLatLong[1]);
String lsRadius = moSharedPreferenceManager.getGeoFenceRadius();
float lfRadius = Float.parseFloat(lsRadius);
Log.i(TAG, "GeofencingEvent Exit");
float lfDistance = loTriggerGeoFenceLocation.distanceTo(loExistGeoFenceLocation);
if (lfDistance >= lfRadius && ldAccuracy <= 100f) {
moSharedPreferenceManager.setGeoFenceExit(true);
}
}