2017-08-11 5 views
0

GooglePlayServices最新バージョンでAndroid上でジオフェンシングを実装しようとしています。Android Geocing with play-services-location 11.0.2

私はジオフェンシングを使用することに決めました。私はジオフェンシングを使用することに決めました。なぜなら、移動するときだけユーザーの位置を知る必要があり、私のアプリは24時間365日でバックグラウンドで実行されるため、

私のコードでは、LocationServicesの "requestLocationUpdates"を実装していないと、ジオフェンシングは発生しません。私はこれを使用する必要は通常ありません、それはもう低消費電力ではないことを読んで本当に変です。

「requestLocationUpdates」を実装せずに、最新のGooglePlayServiceでジオフェンシングを実装したことはありますか?

マイコード:

マニフェスト:

<service 
     android:name=".gps.GeofencingService" 
     android:enabled="true" 
     android:exported="true" /> 
    <receiver 
     android:name=".gps.GeofenceReceiver" 
     android:exported="true" 
     > 
     <intent-filter> 
      <action android:name="android.location.MODE_CHANGED" /> 
      <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> 
      <action android:name="android.location.PROVIDERS_CHANGED" /> 
     </intent-filter> 
    </receiver> 

サービス:

public class GeofencingService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { 

//My singleton 
private static GeofencingService mInstant; 
public static GeofencingService getInstant(){ 
    return mInstant; 
} 

@Override 
public void onCreate() { 
    super.onCreate(); 
    mInstant = this; 
    mFusedLocationClient = getFusedLocationProviderClient(this); 
    mGeofencingClient = LocationServices.getGeofencingClient(this); 
    buildGoogleApiClient(); 
} 

protected synchronized void buildGoogleApiClient() { 
    mGoogleApiClient = new GoogleApiClient.Builder(this) 
      .addConnectionCallbacks(this) 
      .addOnConnectionFailedListener(this) 
      .addApi(LocationServices.API) 
      .build(); 
} 


public void addGeofence() { 
    if (mGoogleApiClient.isConnected()) { 

     LocationRequest mLocationRequest = LocationRequest.create(); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     mLocationRequest.setInterval(100); // Update location every second 

     //use to initiate the geofence region on my position 
     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
     Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     if (location != null) { 
      mGeofenceList = new ArrayList(); 
      mGeofenceList.add(new Geofence.Builder() 
        // Set the request ID of the geofence. This is a string to identify this 
        // geofence. 
        .setRequestId(idGeofence) 
        .setCircularRegion(
          location.getLatitude(), 
          location.getLongitude(), 
          Constantes.GEOFENCE_RADIUS_IN_METERS 
        ) 
        .setExpirationDuration(Geofence.NEVER_EXPIRE) 
        .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT) 
        .build()); 
      mGeofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent()) 
        .addOnSuccessListener(new OnSuccessListener<Void>() { 
         @Override 
         public void onSuccess(Void aVoid) { 
          Log.d(TAG, "Geofence added"); 
         } 
        }) 
        .addOnFailureListener(new OnFailureListener() { 
         @Override 
         public void onFailure(@NonNull Exception e) { 
          // Failed to add geofences 
          Log.d(TAG, "Failed to add geofences"); 
          e.printStackTrace(); 
         } 
        }); 

    //if this line is removed, geofence is not triggered anymore 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
     } 


    } 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    //super.onStartCommand(intent, flags, startId); 
    mGoogleApiClient.connect(); 
    return START_STICKY; 
} 

@Override 
public void onConnected(Bundle bundle) { 
    Log.i(TAG, "GoogleApiClient connected"); 
    addGeofence(); 
} 

@Override 
public void onConnectionSuspended(int i) { 
    Log.i(TAG, "GoogleApiClient connection has been suspend"); 
} 

@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 
    Log.i(TAG, "GoogleApiClient connection has failed"); 
} 

public void getCurrentLocation() { 
    //mFusedLocationClient.getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() { 
    FusedLocationProviderClient locationClient = getFusedLocationProviderClient(this); 
    locationClient.getLastLocation().addOnSuccessListener(new OnSuccessListener<Location>() { 
     @Override 
     public void onSuccess(Location location) { 
      // Got last known location. In some rare situations this can be null. 
      if (location != null) { 
       Log.d(TAG, location.getLatitude() + "/" + location.getLongitude()); 
      } else { 

      } 
     } 
    }); 

} 

private PendingIntent getGeofencePendingIntent() { 
    // Reuse the PendingIntent if we already have it. 
    if (mGeofencePendingIntent != null) { 
     return mGeofencePendingIntent; 
    } 
//Call a BroadcastReceiver 
    mGeofencePendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, GeofenceReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT); 
    return mGeofencePendingIntent; 
} 

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

@Override 
public void onLocationChanged(Location location) { 
    Log.d(TAG, "Location Changed : " + location.getLatitude() + "/" + location.getLongitude()); 
} 

}

受信機:

public class GeofenceReceiver extends BroadcastReceiver { 

protected static final String TAG = "GeofenceReceiver"; 

protected Context applicationContext; 

@Override 
public void onReceive(final Context context, final Intent intent) { 
    applicationContext = context; 
    GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent); 
    if (geofencingEvent.hasError()) { 
     String errorMessage = GeofenceErrorMessages.getErrorString(context, geofencingEvent.getErrorCode()); 
     Log.e(TAG, errorMessage); 
     return; 
    } 

    // Get the transition type. 
    int geofenceTransition = geofencingEvent.getGeofenceTransition(); 

    // Test that the reported transition was of interest. 
    if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || 
      geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { 

     // Get the geofences that were triggered. A single event can trigger 
     // multiple geofences. 
     List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences(); 

     // Get the transition details as a String. 
     String geofenceTransitionDetails = getGeofenceTransitionDetails(geofenceTransition, triggeringGeofences); 
     Log.d(TAG, geofenceTransitionDetails); 
     Toast.makeText(context, geofenceTransitionDetails, Toast.LENGTH_LONG).show(); 
     // Send notification and log the transition details. 
     sendNotification(geofenceTransitionDetails); 
     Log.i(TAG, geofenceTransitionDetails); 
    } else { 
     // Log the error. 
     Log.e(TAG, context.getString(R.string.geofence_transition_invalid_type, 
       geofenceTransition)); 
    } 
} 

}あなたの助け

+1

でフェンスを入力すると、それはGeofenceReceiverに通知されますにどのを受け取ることになります簡単なアクティビティを使用してmGeofencePendingIntentを添付? –

+0

いいえ、私はこのapiについて聞いたのは初めてです!強力に見えます!私はそれを使うことができるかどうかを見に行くでしょう...ありがとうTim! – Anthony

答えて

0

ため

ありがとうございますジオフェンスを追加するためのrequestLocationUpdatesを呼び出す必要はありません。

モニタするには、位置(緯度、経度)のジオフェンスが必要です。これにはサービス(GeofencingService)を使用する必要はありません。 GeofenceReceiver

タスクのこの種の意識APIを検討しているあなたはGeofence.GEOFENCE_TRANSITION_ENTER