0

我已阅读各种教程,论坛和Google官方文档,但仍无法理解为什么我的代码无法按预期工作。有相关部分:地理栅栏不会触发我的服务

活动

public class MainMap extends FragmentActivity implements OnMarkerClickListener, OnMapReadyCallback, 
     ConnectionCallbacks, OnConnectionFailedListener, LocationListener, ActivityCompat.OnRequestPermissionsResultCallback, ResultCallback<Status> { 

    private static final int REQUEST_ACCESS_FINE_LOCATION = 0; 
    protected GoogleApiClient mGoogleApiClient; 
    protected Location mCurrentLocation; 
    protected LocationRequest mLocationRequest; 
    private GoogleMap m_map; 
    private SupportMapFragment m_map_fragment; 

    protected ArrayList<Geofence> mGeofenceList; 
    private PendingIntent mGeofencePendingIntent; 
    private boolean m_geofences_added; 
    private SharedPreferences m_preferences; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main_map); 
     m_preferences = this.getSharedPreferences("com.example",Context.MODE_PRIVATE); 
     // map fragment 
     m_map_fragment= (SupportMapFragment) getSupportFragmentManager() 
       .findFragmentById(R.id.map); 
     m_map_fragment.getMapAsync(this); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     // location and geofences 
     add_location_and_geofences(); 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    protected void onStop() { 
     // remove geofences 
     LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient, getGeofencePendingIntent()); 
     super.onStop(); 
     mGoogleApiClient.disconnect(); 
    } 

    @Override 
    public void onConnected(Bundle connectionHint) { 
     // permissions 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      request_fine_location_permission(); 
     } 
     // location 
     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
     // geofencing 
     try { 
      LocationServices.GeofencingApi.addGeofences(
        mGoogleApiClient, 
        getGeofencingRequest(), 
        getGeofencePendingIntent() 
      ).setResultCallback(this); 
     } catch (SecurityException securityException) { 
      Log.e(TAG, "Invalid location permission. " + 
        "You need to use ACCESS_FINE_LOCATION with geofences", securityException); 
     } 
    } 

    public void onResult(Status status) { 
     if (status.isSuccess()) { 
     } else { 
      String errorMessage = GeofenceErrorMessages.getErrorString(this, 
        status.getStatusCode()); 
      Log.e(TAG, errorMessage); 
     } 
    } 

    private void add_location_and_geofences() { 
     for (int i =0; i < 3; i++) { 
      mGeofencePendingIntent = null; 
      mGeofenceList = new ArrayList<>(); 
      mGeofenceList.add(new Geofence.Builder() 
        .setRequestId(Integer.toString(i)) // request id is the index so that I can later retrieve it 
        .setCircularRegion(/* I set coordinates here and a radius of 10meters*/) 
        .setExpirationDuration(NEVER_EXPIRE) 
        .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_DWELL) 
        .setLoiteringDelay(4000) 
        .build()); 
      mGoogleApiClient = new GoogleApiClient.Builder(this) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .addApi(LocationServices.API) 
        .build(); 
      mLocationRequest = new LocationRequest(); 
      mLocationRequest.setInterval(1000); 
      mLocationRequest.setFastestInterval(500); 
      mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     } 
    } 

    private PendingIntent getGeofencePendingIntent() { 
     if (mGeofencePendingIntent != null) { 
      return mGeofencePendingIntent; 
     } 
     Intent intent = new Intent(this, GeofenceTransitionsIntentService.class); 
     return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
    } 

    private GeofencingRequest getGeofencingRequest() { 
     GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); 
     builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL); 
     builder.addGeofences(mGeofenceList); 
     return builder.build(); 
    } 
} 

我的服务:

public class GeofenceTransitionsIntentService extends IntentService { 

    private Intent m_intent; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     m_intent = new Intent(this, Guide.class); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); 
     if (geofencingEvent.hasError()) { 
      String errorMessage = GeofenceErrorMessages.getErrorString(this, 
        geofencingEvent.getErrorCode()); 
      Log.e(TAG, errorMessage); 
     } else { 
      if (debug_mode) { 
       Log.i(TAG, "something has been received"); 
      } 
      int geofenceTransition = geofencingEvent.getGeofenceTransition(); 
      if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL) { 
       List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences(); 
       for (Geofence geofence : triggeringGeofences) { 
         Log.i(TAG, "INSIDE GEOFENCE"); 
       } 
      } else { 
       Log.e(TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition)); 
      } 
     } 
    } 
} 

和我的清单

<service android:name="com.example.GeofenceTransitionsIntentService" /> 

有了这个代码地理围栏静静地失败 - 我的服务永远不会触发,无论是在室内使用wifi还是在户外使用3G/4G网络。

+0

是'onLocationChanged'执行? –

+0

是的,我得到定期更新 –

+0

然后,你应该'onLocationChanged'内添加'geofence' –

回答

0

你只是在寻找停顿事件还是进入和退出事件?如果是后者,请将您的初始触发设置为INITIAL_TRIGGER_ENTER,并将转换类型设置为GEOFENCE_TRANSITION_ENTER| GEOFENCE_TRANSITION_EXIT

如果您正在寻找居住事件,您需要在地理围栏内停留约5分钟才能获得初始触发。当你离开时,你不会得到任何关于它的事件,但是一旦你重新进入它,你需要再次停留在你的地理围栏里再过5分钟才能得到你的活动。