2016-08-08 21 views
0

Ich weiß, dass die Frage bereits gestellt wird, aber ich habe so viele vorgeschlagene Lösungen versucht, aber es funktioniert nicht.Geofence funktioniert nicht, wenn die App getötet wird

Mein Code für Geofence funktioniert, wenn App ausgeführt wird, aber sobald die App die Benachrichtigung getötet erscheint nicht mehr, auch wenn BroadcastReceiver

Sie können hier den Code finden, um die Aktivität zugeordnet ist, btn_reservation die Taste ist, dass Beginnt mit dem Hinzufügen des Geofence.

public class DetailsActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener, 
     ResultCallback<Status> { 

public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = 12 * 60 * 60 * 1000; 
public static final float GEOFENCE_RADIUS_IN_METERS = 500 
private List<Geofence> mGeofenceList; 
private GoogleApiClient mGoogleApiClient; 
private Button btn_reservation; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_details); 

    btn_reservation = (Button) findViewById(R.id.reserver); 

    mGeofenceList = new ArrayList<Geofence>(); 

    mGeofenceList.add(new Geofence.Builder() 

      .setRequestId("1") 

      .setCircularRegion(
        MapsActivity.getLatitude(), 
        MapsActivity.getLongitude(), 
        GEOFENCE_RADIUS_IN_METERS 
      ) 
      .setExpirationDuration(GEOFENCE_EXPIRATION_IN_MILLISECONDS) 
      .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER) 
      .build()); 


    // Create an instance of GoogleAPIClient. 
    if (mGoogleApiClient == null) { 
     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
    } 


    btn_reservation.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
       if (!mGoogleApiClient.isConnected()) { 
        Toast.makeText(getApplicationContext(), "Google API Client not connected!", Toast.LENGTH_SHORT).show(); 
        return; 
       } 

       try { 
        LocationServices.GeofencingApi.addGeofences(
          mGoogleApiClient, 
          getGeofencingRequest(), 
          getGeofencePendingIntent() 
        ).setResultCallback(DetailsActivity.this); // Result processed in onResult(). 
       } catch (SecurityException securityException) { 
        // Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission. 
        Toast.makeText(getApplicationContext(), "ACCESS_FINE_LOCATION permission unused ", Toast.LENGTH_SHORT).show(); 
       } 
      } 
    }); 

} 

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

private PendingIntent getGeofencePendingIntent() { 

    Intent intent = new Intent("ACTION_RECEIVE_GEOFENCE"); 

    return PendingIntent.getBroadcast(
      getApplicationContext(), 
      0, 
      intent, 
      PendingIntent.FLAG_UPDATE_CURRENT); 
} 

@Override 
protected void onStart() { 
    super.onStart(); 
    if (!mGoogleApiClient.isConnecting() || !mGoogleApiClient.isConnected()) { 
     mGoogleApiClient.connect(); 
    } 
} 

@Override 
protected void onStop() { 
    super.onStop(); 
    if (mGoogleApiClient.isConnecting() || mGoogleApiClient.isConnected()) { 
     mGoogleApiClient.disconnect(); 
    } 
} 

@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 

} 

@Override 
public void onConnected(Bundle bundle) { 

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     // TODO: Consider calling 
     // ActivityCompat#requestPermissions 
     // here to request the missing permissions, and then overriding 
     // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
     //           int[] grantResults) 
     // to handle the case where the user grants the permission. See the documentation 
     // for ActivityCompat#requestPermissions for more details. 
     return; 
    } 
    Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
      mGoogleApiClient); 
    if (mLastLocation != null) { 
     System.out.println("My lat " +String.valueOf(mLastLocation.getLatitude())); 
     System.out.println("My lon " +String.valueOf(mLastLocation.getLongitude())); 
    } 
} 

@Override 
public void onConnectionSuspended(int i) { 
    mGoogleApiClient.connect(); 
} 

@Override 
public void onResult(Status status) { 
    if (status.isSuccess()) { 
     System.out.println("Geofences Added"); 
    } else { 
     System.out.println(status.getStatusCode()); 
    } 
} 

Und das ist mein GeofenceReceiver.java

public class GeofenceReceiver extends BroadcastReceiver { 
Context context; 

Intent broadcastIntent = new Intent(); 

@Override 
public void onReceive(Context context, Intent intent) { 
    this.context = context; 

    broadcastIntent.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES); 

    GeofencingEvent event = GeofencingEvent.fromIntent(intent); 
    if (event.hasError()) { 
     handleError(intent); 
    } else { 
     handleEnterExit(intent); 
    } 

} 

private void handleError(Intent intent){ 
    GeofencingEvent event = GeofencingEvent.fromIntent(intent); 
    // Get the error code 
    int errorCode = event.getErrorCode(); 

    // Get the error message 
    String errorMessage = LocationServiceErrorMessages.getErrorString(
      context, errorCode); 

    // Log the error 
    Log.e(GeofenceUtils.APPTAG, 
      "geofence_transition_error_detail"+ 
        errorMessage); 

    // Set the action and error message for the broadcast intent 
    broadcastIntent 
      .setAction(GeofenceUtils.ACTION_GEOFENCE_ERROR) 
      .putExtra(GeofenceUtils.EXTRA_GEOFENCE_STATUS, errorMessage); 

    // Broadcast the error *locally* to other components in this app 
    LocalBroadcastManager.getInstance(context).sendBroadcast(
      broadcastIntent); 
} 


private void handleEnterExit(Intent intent) { 

    GeofencingEvent event = GeofencingEvent.fromIntent(intent); 
    int transition = event.getGeofenceTransition(); 

    // Test that a valid transition was reported 
    if ((transition == Geofence.GEOFENCE_TRANSITION_ENTER) 
      || (transition == Geofence.GEOFENCE_TRANSITION_EXIT)) { 

     // Post a notification 
     List<Geofence> geofences = event 
       .getTriggeringGeofences(); 
     String[] geofenceIds = new String[geofences.size()]; 
     String ids = TextUtils.join(GeofenceUtils.GEOFENCE_ID_DELIMITER, 
       geofenceIds); 
     int tran = Geofence.GEOFENCE_TRANSITION_ENTER; 
     String transitionType = String.valueOf(tran); 

     // Create an Intent to broadcast to the app 
     broadcastIntent 
       .setAction(GeofenceUtils.ACTION_GEOFENCE_TRANSITION) 
       .addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES); 

     LocalBroadcastManager.getInstance(context) 
       .sendBroadcast(broadcastIntent); 

     // Log the transition type and a message 
     Log.d(GeofenceUtils.APPTAG, transitionType + ": " + ids); 
     Log.d(GeofenceUtils.APPTAG, 
       context.getString(R.string.geofence_transition_notification_text)); 

     // In debug mode, log the result 
     Log.d(GeofenceUtils.APPTAG, "transition"); 

     // An invalid transition was reported 
    } else { 
     // Always log as an error 
     Log.e(GeofenceUtils.APPTAG, 
       "geofence_transition_invalid_type" 
         + transition); 
    } 

    sendNotification(String.valueOf(Geofence.GEOFENCE_TRANSITION_ENTER), "here"); 
} 

private void sendNotification(String transitionType, String locationName) { 

    // Create an explicit content Intent that starts the main Activity 
    Intent notificationIntent = new Intent(context, TicketActivity.class); 

    // Construct a task stack 
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); 

    // Adds the main Activity to the task stack as the parent 
    stackBuilder.addParentStack(TicketActivity.class); 

    // Push the content Intent onto the stack 
    stackBuilder.addNextIntent(notificationIntent); 

    // Get a PendingIntent containing the entire back stack 
    PendingIntent notificationPendingIntent = stackBuilder 
      .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); 

    // Get a notification builder that's compatible with platform versions 
    // >= 4 
    NotificationCompat.Builder builder = new NotificationCompat.Builder(
      context); 

    // Set the notification contents 
    builder.setSmallIcon(R.drawable.cast_ic_notification_0) 
      .setContentTitle(transitionType + ": " + locationName) 
      .setContentText(
        context.getString(R.string.geofence_transition_notification_text)) 
      .setContentIntent(notificationPendingIntent); 

    // Get an instance of the Notification manager 
    NotificationManager mNotificationManager = (NotificationManager) context 
      .getSystemService(Context.NOTIFICATION_SERVICE); 

    // Issue the notification 
    mNotificationManager.notify(0, builder.build()); 

    System.out.println("in radius"); 
    } 
} 

Und das ist mein Empfänger im Manifest

<receiver android:name="tn.odc.noq.receiver.GeofenceReceiver" android:exported="false"> 
    <intent-filter > 
     <action android:name="tn.odc.noq.receiver.ACTION_RECEIVE_GEOFENCE"/> 
     <category android:name="tn.odc.noq.receiver" /> 
    </intent-filter> 
    </receiver> 

Antwort

0

Businesses geofences von Grund ist es wirklich schwer, ich habe zusammen versucht worden Zeit mach das, aber ich habe keinen guten Stummel bekommen. Also habe ich angenommen

Hier einige tolle Libs einige Libs zu verwenden:

Smart-location-lib

Ex:

GeofenceModel mestalla = new GeofenceModel.Builder("id_mestalla") 
    .setTransition(Geofence.GEOFENCE_TRANSITION_ENTER) 
    .setLatitude(39.47453120000001) 
    .setLongitude(-0.358065799999963) 
    .setRadius(500) 
    .build(); 

Android-rxgeofence

RxGeoFence.with(this) //context 
     .dbUrl(GEO_FIRE_DB) //String 
     .geoFenceSource(...) // rx.Observable<List<Place>> 
     .locationSource(...) // rx.Observable<LatLng> 
     .build() 
     .subscribe(geoFenceEvent -> { 
     // do what you wanna do with the event 
    }); 

Android-ReactiveLocation

Ich gebe tatsächlich Verwendung libs, da es eine große Anzahl von Entwicklern arbeiten, um alle Probleme zu lösen, und Verhandlungen Ausnahme.