Android 继续触发地理围栏事件

Android 继续触发地理围栏事件,android,google-maps,geolocation,location,android-geofence,Android,Google Maps,Geolocation,Location,Android Geofence,土工栅栏触发问题 我已在我的应用程序中设置geofence, 我正在使用IntetnService处理触发器事件 我的问题是多次触发事件 假设我在Geofence内的1个位置,不幸的是某个时间进入或退出事件触发器, 然后我会检查geoEvent.getRiggerdLocation()属性并检查geo-fence半径 如果触发位置到地理围栏位置的距离大于geofecen半径,则我将释放退出事件功能 但最终geofence触发事件2 3公里远,即使我已经进入围栏,我的上述逻辑将失败。见快照 我想

土工栅栏触发问题

我已在我的应用程序中设置geofence, 我正在使用IntetnService处理触发器事件

我的问题是多次触发事件

假设我在Geofence内的1个位置,不幸的是某个时间进入或退出事件触发器, 然后我会检查geoEvent.getRiggerdLocation()属性并检查geo-fence半径

如果触发位置到地理围栏位置的距离大于geofecen半径,则我将释放退出事件功能

但最终geofence触发事件2 3公里远,即使我已经进入围栏,我的上述逻辑将失败。见快照

我想把这些都修好

位置处于高优先级状态

当我靠近围栏的边界时,这种情况会发生得更多

添加地理围栏列表,截至目前,我只使用一个围栏

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());
PendidEnginentService

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);
}
import java.util.ArrayList;
导入java.util.List;
导入com.google.android.gms.location.geofense;
导入com.google.android.gms.location.GeofenceStatusCodes;
导入com.google.android.gms.location.GeofencingEvent;
导入android.R.bool;
导入android.app.IntentService;
导入android.app.usage.usagevents.Event;
导入android.content.Intent;
导入android.database.Cursor;
导入android.location.location;
导入android.text.TextUtils;
公共类GeofenceTransitionsIntentService扩展了IntentService{
受保护的静态最终字符串标记=“GeoFenceTransitions”;
公共地理围栏TransitionsIntentService(){
super(TAG);//使用TAG命名IntentService工作线程
}
@凌驾
公共空间{
//TODO自动生成的方法存根
super.ondestory();
}
私有静态字符串getGeofenceTransitionDetails(GeofencingEvent事件){
String transitionString=GeofenceStatusCodes.getStatusCodeString(event.getGeofenceTransition());
List triggeringIDs=new ArrayList();
对于(Geofence Geofence:event.getTriggeringGeofences()){
add(geofinence.getRequestId());
}
返回字符串.format(“%s:%s”,transitionString,TextUtils.join(“,”,triggeringId));
}
@凌驾
受保护的手部内容无效(意图){
GeofencingEvent事件=GeofencingEvent.fromIntent(intent);
Log.i(标签“地理围栏事件:+事件”);
if(event.hasError()){
Log.i(标记“GeofencingEvent Error:+event.getErrorCode());
返回;
}
//获取转换类型(入口或出口)
if(event.getGeofenceTransition()==Geofence.Geofence\u TRANSITION\u ENTER){
Log.i(标记“GeofencingEvent Enter”);
}
if(event.getGeofenceTransition()==Geofence.Geofence\u TRANSITION\u EXIT){
Log.i(标签“GeofencingEvent出口”);
?
字符串描述=getGeofenceTransitionDetails(事件);
Log.i(标签“GeofencingEvent描述:”+描述);
}
}

权限

<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" />


我已经陷入这个问题很多天了,请帮助完成这个问题。

以下是在
应用程序中使用
地理围栏时应该记住的要点

从官方

  • 为地理围栏选择最佳半径
为获得最佳效果,应设置土工栅栏的最小半径 在100-150米之间。当Wi-Fi可用时,定位精度为 通常在20-50米之间。当室内位置可用时 精度范围可以小到5米。除非你知道室内 地理围栏内的位置可用,假设Wi-Fi位置 精度约为50米

当Wi-Fi位置不可用时(例如,当您 在农村地区驾驶)定位精度下降 射程可以达到几百米到几公里。 在这种情况下,您应该使用更大的半径创建地理围栏

  • 使用暂停转换类型减少警报垃圾邮件
如果您在短暂驶过车辆时收到大量警报 geofence,减少警报的最佳方法是使用转换 土工围栏类型\u过渡\u驻留,而不是 GEOFENCE\u TRANSITION\u ENTER。这样,仅发送居住警报 当用户在地理围栏内停留一段时间时。您 可以通过设置游荡延迟来选择持续时间


找到一个修补程序以避免不必要的或虚假的事件

你可以在触发时间得到位置

Location loTriggerGeoFenceLocation = moEvent.getTriggeringLocation();
long ldAccuracy = loTriggerGeoFenceLocation.getAccuracy();
现在将您的地理围栏位置以横向和半径存储。 不获取触发器lat long并检查触发器位置和地理围栏位置lat long之间的距离。如果距离小于半径,则应为进入,距离大于半径,则应为退出事件

 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);
        }
}
if(event.getGeofenceTransition()==Geofence.Geofence\u TRANSITION\u EXIT){
ldGeoLatLong=moSharedPreferenceManager.getgeofenginetimelocation();
位置loExistGeoFenceLocation=新位置(“”);
loExistGeoFenceLocation.setLatitude(ldGeoLatLong[0]);
loexistgeofenseLocation.setLength(ldGeoLatLong[1]);
字符串lsRadius=moSharedPreferenceManager.getGeoFenceRadius();
float lfRadius=float.parseFloat(lsRadius);
Log.i(标签“GeofencingEvent出口”);
float lfDistance=loTriggerGeoFenceLocation.distanceTo(loExistGeoFenceLocation);

如果(lfDistance>=lfRadius&&ldaccurity发布更多代码。@kishorejethava可以吗?您是否检查了
geofrance
request Id?可能两者都是不同的请求Id。不,目前只有一个geofrance,因此没有唯一请求Id的机会。我还有打印日志。@kishorejethava区域半径有多长?1.选择选项imal半径为您的地理围栏-它将超过700米。2.使用驻留过渡类型减少警报垃圾邮件-我知道,但我想要这个功能