2016-08-08 5 views
0

Я знаю, что вопрос уже задан, но я пробовал так много предлагаемых решений, но он не работает.Geofence не работает, когда приложение убито

Моего код геозоны работает, когда приложение работает, но после того, как приложение будет убито уведомление не появляется больше, даже когда BroadcastReceiver

Вы можете найти здесь код, связанный с деятельностью, btn_reservation является кнопкой, начинает добавлять геозонность.

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

И это мой 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"); 
    } 
} 

И это мой приемник в проявленном

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

ответ

0

Работе с геозонами с нуля это очень трудно, я пытался для по время сделайте это, но я не получил хорошую заглушку. Таким образом, я принял использовать несколько библиотек

Вот некоторые удивительные ЛИЭС:

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

Geofence geofence = new Geofence.Builder() 
        .setRequestId("GEOFENCE") 
        .setCircularRegion(latitude, longitude, radius) 
        .setExpirationDuration(Geofence.NEVER_EXPIRE) 
        .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT) 
        .build(); 

Я на самом деле указываю использование libs, так как существует большое количество разработчиков, работающих над решением всех проблем и исключением для переговоров.