2013-10-17 12 views
5

Robię poważne badania na ten temat od wielu dni ... Widziałem tu wiele tematów ... Niestety nie mogłem znaleźć rozwiązania ...Android Geofence działa tylko z otwartą aplikacją

Piszę aplikację, która korzysta z nowego interfejsu API Google dla Geofence ... Cóż, mogę obsłużyć "ins" i "out" geofence, ale tylko wtedy, gdy moja aplikacja jest otwarta! Nawet jeśli mam połączenie z Wi-Fi, GPS i 3G, ale aplikacja nie powoduje żadnego zdarzenia ... Tylko jeśli aplikacja jest otwarta ...

Używam dokładnie tego samego GeofenceRequestera klasa dokumentacji http://developer.android.com/training/location/geofencing.html.

Nawet klasa była taka sama będę pisać kod tutaj:

package br.com.marrs.imhere.geofence; 
import java.util.ArrayList; 
import java.util.List; 

import android.app.Activity; 
import android.app.PendingIntent; 
import android.content.Intent; 
import android.content.IntentSender.SendIntentException; 
import android.os.Bundle; 
import android.support.v4.content.LocalBroadcastManager; 
import android.util.Log; 
import br.com.marrs.imhere.services.ReceiveTransitionsIntentService; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesClient; 
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks; 
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener; 
import com.google.android.gms.location.Geofence; 
import com.google.android.gms.location.LocationClient; 
import com.google.android.gms.location.LocationClient.OnAddGeofencesResultListener; 
import com.google.android.gms.location.LocationStatusCodes; 

/** 
* Class for connecting to Location Services and requesting geofences. 
* <b> 
* Note: Clients must ensure that Google Play services is available before requesting geofences. 
* </b> Use GooglePlayServicesUtil.isGooglePlayServicesAvailable() to check. 
* 
* 
* To use a GeofenceRequester, instantiate it and call AddGeofence(). Everything else is done 
* automatically. 
* 
*/ 
public class GeofenceRequester 
       implements 
        OnAddGeofencesResultListener, 
        ConnectionCallbacks, 
        OnConnectionFailedListener { 

    // Storage for a reference to the calling client 
    private final Activity mActivity; 

    // Stores the PendingIntent used to send geofence transitions back to the app 
    private PendingIntent mGeofencePendingIntent; 

    // Stores the current list of geofences 
    private ArrayList<Geofence> mCurrentGeofences; 

    // Stores the current instantiation of the location client 
    private LocationClient mLocationClient; 

    /* 
    * Flag that indicates whether an add or remove request is underway. Check this 
    * flag before attempting to start a new request. 
    */ 
    private boolean mInProgress; 

    public GeofenceRequester(Activity activityContext) { 
     // Save the context 
     mActivity = activityContext; 

     // Initialize the globals to null 
     mGeofencePendingIntent = null; 
     mLocationClient = null; 
     mInProgress = false; 
    } 

    /** 
    * Set the "in progress" flag from a caller. This allows callers to re-set a 
    * request that failed but was later fixed. 
    * 
    * @param flag Turn the in progress flag on or off. 
    */ 
    public void setInProgressFlag(boolean flag) { 
     // Set the "In Progress" flag. 
     mInProgress = flag; 
    } 

    /** 
    * Get the current in progress status. 
    * 
    * @return The current value of the in progress flag. 
    */ 
    public boolean getInProgressFlag() { 
     return mInProgress; 
    } 

    /** 
    * Returns the current PendingIntent to the caller. 
    * 
    * @return The PendingIntent used to create the current set of geofences 
    */ 
    public PendingIntent getRequestPendingIntent() { 
     return createRequestPendingIntent(); 
    } 

    /** 
    * Start adding geofences. Save the geofences, then start adding them by requesting a 
    * connection 
    * 
    * @param geofences A List of one or more geofences to add 
    */ 
    public void addGeofences(List<Geofence> geofences) throws UnsupportedOperationException { 

     /* 
     * Save the geofences so that they can be sent to Location Services once the 
     * connection is available. 
     */ 
     mCurrentGeofences = (ArrayList<Geofence>) geofences; 

     // If a request is not already in progress 
     if (!mInProgress) { 

      // Toggle the flag and continue 
      mInProgress = true; 

      // Request a connection to Location Services 
      requestConnection(); 

     // If a request is in progress 
     } else { 

      // Throw an exception and stop the request 
      throw new UnsupportedOperationException(); 
     } 
    } 

    /** 
    * Request a connection to Location Services. This call returns immediately, 
    * but the request is not complete until onConnected() or onConnectionFailure() is called. 
    */ 
    private void requestConnection() 
    { 
     getLocationClient().connect(); 
    } 

    /** 
    * Get the current location client, or create a new one if necessary. 
    * 
    * @return A LocationClient object 
    */ 
    private GooglePlayServicesClient getLocationClient() 
    { 
     if (mLocationClient == null) { 

      mLocationClient = new LocationClient(mActivity, this, this); 
     } 
     return mLocationClient; 

    } 
    /** 
    * Once the connection is available, send a request to add the Geofences 
    */ 
    private void continueAddGeofences() { 

     // Get a PendingIntent that Location Services issues when a geofence transition occurs 
     mGeofencePendingIntent = createRequestPendingIntent(); 

     // Send a request to add the current geofences 
     mLocationClient.addGeofences(mCurrentGeofences, mGeofencePendingIntent, this); 
    } 

    /* 
    * Handle the result of adding the geofences 
    */ 
    @Override 
    public void onAddGeofencesResult(int statusCode, String[] geofenceRequestIds) 
    { 
     // Create a broadcast Intent that notifies other components of success or failure 
     Intent broadcastIntent = new Intent(); 

     // Temp storage for messages 
     String msg; 

     // If adding the geocodes was successful 
     if (LocationStatusCodes.SUCCESS == statusCode) 
     { 
      // Create a message containing all the geofence IDs added. 
      msg = geofenceRequestIds.toString(); 

      // In debug mode, log the result 
      Log.d("DEBUG", msg); 

      // Create an Intent to broadcast to the app 
      broadcastIntent.setAction("br.com.marrs.imhere.ACTION_GEOFENCES_ADDED") 
          .addCategory("br.com.marrs.imhere.CATEGORY_LOCATION_SERVICES") 
          .putExtra("br.com.marrs.imhere.EXTRA_GEOFENCE_STATUS", msg); 
     // If adding the geofences failed 
     } 
     else 
     { 

      /* 
      * Create a message containing the error code and the list 
      * of geofence IDs you tried to add 
      */ 
      msg = "Erro adicionando geofence"; 

      // Log an error 
      Log.e("DEBUG", msg); 

      // Create an Intent to broadcast to the app 
      broadcastIntent.setAction("br.com.marrs.imhere.ACTION_GEOFENCE_ERROR") 
          .addCategory("br.com.marrs.imhere.CATEGORY_LOCATION_SERVICES") 
          .putExtra("br.com.marrs.imhere.EXTRA_GEOFENCE_STATUS", msg); 
     } 

     // Broadcast whichever result occurred 
     LocalBroadcastManager.getInstance(mActivity).sendBroadcast(broadcastIntent); 

     // Disconnect the location client 
     requestDisconnection(); 
    } 

    /** 
    * Get a location client and disconnect from Location Services 
    */ 
    private void requestDisconnection() { 

     // A request is no longer in progress 
     mInProgress = false; 

     getLocationClient().disconnect(); 
    } 

    /* 
    * Called by Location Services once the location client is connected. 
    * 
    * Continue by adding the requested geofences. 
    */ 
    @Override 
    public void onConnected(Bundle arg0) { 
     // If debugging, log the connection 

     Log.d("DEBUG", "GeofenceRequester connected"); 

     // Continue adding the geofences 
     continueAddGeofences(); 
    } 

    /* 
    * Called by Location Services once the location client is disconnected. 
    */ 
    @Override 
    public void onDisconnected() { 


     // Turn off the request flag 
     mInProgress = false; 

     // In debug mode, log the disconnection 
     Log.d("DEBUG", "GeofenceRequester disconnected"); 

     // Destroy the current location client 
     mLocationClient = null; 
    } 

    /** 
    * Get a PendingIntent to send with the request to add Geofences. Location Services issues 
    * the Intent inside this PendingIntent whenever a geofence transition occurs for the current 
    * list of geofences. 
    * 
    * @return A PendingIntent for the IntentService that handles geofence transitions. 
    */ 
    private PendingIntent createRequestPendingIntent() { 

     // If the PendingIntent already exists 
     if (null != mGeofencePendingIntent) { 

      // Return the existing intent 
      return mGeofencePendingIntent; 

     // If no PendingIntent exists 
     } else { 

      // Create an Intent pointing to the IntentService 
      Intent intent = new Intent(mActivity, ReceiveTransitionsIntentService.class); 
      /* 
      * Return a PendingIntent to start the IntentService. 
      * Always create a PendingIntent sent to Location Services 
      * with FLAG_UPDATE_CURRENT, so that sending the PendingIntent 
      * again updates the original. Otherwise, Location Services 
      * can't match the PendingIntent to requests made with it. 
      */ 
      return PendingIntent.getService(
        mActivity, 
        0, 
        intent, 
        PendingIntent.FLAG_UPDATE_CURRENT); 
     } 
    } 

    /* 
    * Implementation of OnConnectionFailedListener.onConnectionFailed 
    * If a connection or disconnection request fails, report the error 
    * connectionResult is passed in from Location Services 
    */ 
    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 

     // Turn off the request flag 
     mInProgress = false; 

     /* 
     * Google Play services can resolve some errors it detects. 
     * If the error has a resolution, try sending an Intent to 
     * start a Google Play services activity that can resolve 
     * error. 
     */ 
     if (connectionResult.hasResolution()) { 

      try { 
       // Start an Activity that tries to resolve the error 
       connectionResult.startResolutionForResult(mActivity, 9000); 

      /* 
      * Thrown if Google Play services canceled the original 
      * PendingIntent 
      */ 
      } catch (SendIntentException e) { 
       // Log the error 
       e.printStackTrace(); 
      } 

     /* 
     * If no resolution is available, put the error code in 
     * an error Intent and broadcast it back to the main Activity. 
     * The Activity then displays an error dialog. 
     * is out of date. 
     */ 
     } else { 

      Intent errorBroadcastIntent = new Intent("br.com.marrs.imhere.ACTION_CONNECTION_ERROR"); 
      errorBroadcastIntent.addCategory("br.com.marrs.imhere.CATEGORY_LOCATION_SERVICES") 
           .putExtra("br.com.marrs.imhere.EXTRA_CONNECTION_ERROR_CODE", 
             connectionResult.getErrorCode()); 
      LocalBroadcastManager.getInstance(mActivity).sendBroadcast(errorBroadcastIntent); 
     } 
    } 
} 

a usługa:

package br.com.marrs.imhere.services; 
import br.com.marrs.imhere.ImHereActivity; 
import br.com.marrs.imhere.R; 

import com.google.android.gms.location.Geofence; 
import com.google.android.gms.location.LocationClient; 

import android.app.IntentService; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.support.v4.app.NotificationCompat; 
import android.support.v4.app.TaskStackBuilder; 
import android.support.v4.content.LocalBroadcastManager; 
import android.text.TextUtils; 
import android.util.Log; 

import java.util.List; 

/** 
* This class receives geofence transition events from Location Services, in the 
* form of an Intent containing the transition type and geofence id(s) that triggered 
* the event. 
*/ 
public class ReceiveTransitionsIntentService extends IntentService { 

    /** 
    * Sets an identifier for this class' background thread 
    */ 
    public ReceiveTransitionsIntentService() 
    { 
     super("ReceiveTransitionsIntentService"); 
    } 

    /** 
    * Handles incoming intents 
    * @param intent The Intent sent by Location Services. This Intent is provided 
    * to Location Services (inside a PendingIntent) when you call addGeofences() 
    */ 
    @Override 
    protected void onHandleIntent(Intent intent) { 

     // Create a local broadcast Intent 
     Intent broadcastIntent = new Intent(); 

     // Give it the category for all intents sent by the Intent Service 
     broadcastIntent.addCategory("br.com.marrs.imhere.CATEGORY_LOCATION_SERVICES"); 

     // First check for errors 
     if (LocationClient.hasError(intent)) { 

      // Get the error code 
      int errorCode = LocationClient.getErrorCode(intent); 


      // Log the error 
      Log.e("DEBUG", "Erro no service LocationClient has error"); 

      // Set the action and error message for the broadcast intent 
      broadcastIntent.setAction("br.com.marrs.imhere.ACTION_GEOFENCES_ERROR").putExtra("br.com.marrs.imhere.EXTRA_GEOFENCE_STATUS", "problemas"); 

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

     // If there's no error, get the transition type and create a notification 
     } else { 

      // Get the type of transition (entry or exit) 
      int transition = LocationClient.getGeofenceTransition(intent); 

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

       // Post a notification 
       List<Geofence> geofences = LocationClient.getTriggeringGeofences(intent); 
       String[] geofenceIds = new String[geofences.size()]; 
       for (int index = 0; index < geofences.size() ; index++) { 
        geofenceIds[index] = geofences.get(index).getRequestId(); 
       } 
       String ids = TextUtils.join(",",geofenceIds); 
       String transitionType = getTransitionString(transition); 

       sendNotification(transitionType, ids); 

       // Log the transition type and a message 
       Log.d("DEBUG","Ae...n sei pq isso....mas parece que tah ok"); 

      // An invalid transition was reported 
      } else { 
       // Always log as an error 
       Log.e("DEBUG","Erro, erro, erro"); 
      } 
     } 
    } 

    /** 
    * Posts a notification in the notification bar when a transition is detected. 
    * If the user clicks the notification, control goes to the main Activity. 
    * @param transitionType The type of transition that occurred. 
    * 
    */ 
    private void sendNotification(String transitionType, String ids) 
    { 

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

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

     // Adds the main Activity to the task stack as the parent 
     stackBuilder.addParentStack(ImHereActivity.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(this); 

     // Set the notification contents 
     builder.setSmallIcon(R.drawable.abs__ic_clear) 
       .setContentTitle(ids) 
       .setContentText(transitionType) 
       .setContentIntent(notificationPendingIntent); 

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

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

    /** 
    * Maps geofence transition types to their human-readable equivalents. 
    * @param transitionType A transition type constant defined in Geofence 
    * @return A String indicating the type of transition 
    */ 
    private String getTransitionString(int transitionType) { 
     switch (transitionType) { 

      case Geofence.GEOFENCE_TRANSITION_ENTER: 
       return "Entrando"; 

      case Geofence.GEOFENCE_TRANSITION_EXIT: 
       return "Saindo"; 

      default: 
       return "Desconhecido"; 
     } 
    } 
} 

i odbiornik Broadcast w działalność:

public class GeofenceSampleReceiver extends BroadcastReceiver 
    { 
     /* 
     * Define the required method for broadcast receivers 
     * This method is invoked when a broadcast Intent triggers the receiver 
     */ 
     @Override 
     public void onReceive(Context context, Intent intent) 
     { 

      // Check the action code and determine what to do 
      String action = intent.getAction(); 

      // Intent contains information about errors in adding or removing geofences 
      if (TextUtils.equals(action, "br.com.marrs.imhere.ACTION_GEOFENCE_ERROR")) 
      { 

       handleGeofenceError(context, intent); 

      // Intent contains information about successful addition or removal of geofences 
      } 
      else if (
        TextUtils.equals(action, "br.com.marrs.imhere.ACTION_GEOFENCES_ADDED") 
        || 
        TextUtils.equals(action, "br.com.marrs.imhere.ACTION_GEOFENCES_REMOVED")) 
      { 

       handleGeofenceStatus(context, intent); 

      // Intent contains information about a geofence transition 
      } else if (TextUtils.equals(action, "br.com.marrs.imhere.ACTION_GEOFENCE_TRANSITION")) 
      { 

       handleGeofenceTransition(context, intent); 

      // The Intent contained an invalid action 
      } 
      else 
      { 
       Log.e("DEBUG", "Invalid action detail"); 
       Toast.makeText(context, "Invalid action detail", Toast.LENGTH_LONG).show(); 
      } 
     } 

     /** 
     * If you want to display a UI message about adding or removing geofences, put it here. 
     * 
     * @param context A Context for this component 
     * @param intent The received broadcast Intent 
     */ 
     private void handleGeofenceStatus(Context context, Intent intent) { 

     } 

     /** 
     * Report geofence transitions to the UI 
     * 
     * @param context A Context for this component 
     * @param intent The Intent containing the transition 
     */ 
     private void handleGeofenceTransition(Context context, Intent intent) { 
      /* 
      * If you want to change the UI when a transition occurs, put the code 
      * here. The current design of the app uses a notification to inform the 
      * user that a transition has occurred. 
      */ 
     } 

     /** 
     * Report addition or removal errors to the UI, using a Toast 
     * 
     * @param intent A broadcast Intent sent by ReceiveTransitionsIntentService 
     */ 
     private void handleGeofenceError(Context context, Intent intent) 
     { 
      String msg = intent.getStringExtra("br.com.marrs.imhere.EXTRA_GEOFENCE_STATUS"); 
      Log.e("DEBUG", msg); 
      Toast.makeText(context, msg, Toast.LENGTH_LONG).show(); 
     } 
    } 

A tutaj jest fragment kodu, którego używam do tworzenia GEOFence przed wysłaniem do GeofenceRequestera.

int raio = Integer.parseInt(spinner.getAdapter().getItem(spinner.getSelectedItemPosition()).toString()); 
      int transitionType = (in.isChecked())?Geofence.GEOFENCE_TRANSITION_ENTER:Geofence.GEOFENCE_TRANSITION_EXIT; 
      Geofence geofence = new Geofence.Builder().setRequestId(nomeGeofence.getText().toString()).setTransitionTypes(transitionType).setCircularRegion(lat, lon, raio).setExpirationDuration(Geofence.NEVER_EXPIRE).build(); 
      geofences.add(geofence); 

      try 
      { 
       mGeofenceRequester.addGeofences(geofences); 
       addCircleGeofence(raio); 
      } 
      catch (UnsupportedOperationException e) 
      { 
       Toast.makeText(getActivity(), "Já existe uma requisição de add em andamento",Toast.LENGTH_LONG).show(); 
      } 

Każda pomoc będzie świetna! Dzięki!

Odpowiedz

15

Posiadałem dokładnie to samo, co problem. Oto, co tam odpowiedziałem: Więc po zabawie z tym trochę, wygląda na to, że ReceiveTransitionsIntentService (jak określono w przykładowym kodzie) przestanie otrzymywać powiadomienia, gdy aplikacja nie jest w pobliżu. Myślę, że jest to duży problem z przykładowym kodem ... Wygląda na to, że to potknie ludzi takich jak ja.

Użyłem zamiast tego odbiornika telewizyjnego, i jak dotąd wydaje się, że działa on z moich testów.

Dodaj do tego manifestu:

<receiver android:name="com.aol.android.geofence.GeofenceReceiver" 
     android:exported="false"> 
     <intent-filter > 
      <action android:name="com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE"/> 
     </intent-filter> 
    </receiver> 

Następnie w klasie GeofenceRequester trzeba zmienić metodę createRequestPendingIntent tak, że idzie do BroadcastReceiver zamiast ReceiveTransitionsIntentService. UPEWNIJ SIĘ I ZWRACAJ UWAGĘ na zmianę na .getBroadcast zamiast getService. Przez chwilę mnie rozłączyło.

private PendingIntent createRequestPendingIntent() { 

     // If the PendingIntent already exists 
     if (null != mGeofencePendingIntent) { 

      // Return the existing intent 
      return mGeofencePendingIntent; 

     // If no PendingIntent exists 
     } else { 

      // Create an Intent pointing to the IntentService 
      Intent intent = new Intent("com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE"); 

      //MAKE SURE YOU CHANGE THIS TO getBroadcast if you are coming from the sample code. 
      return PendingIntent.getBroadcast(
        context, 
        0, 
        intent, 
        PendingIntent.FLAG_UPDATE_CURRENT); 
     } 
    } 

Potem dodaje klasę GeofenceReceiver, który wygląda mniej więcej tak:

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

     if (LocationClient.hasError(intent)) { 
      handleError(intent); 
     } else { 
      handleEnterExit(intent); 
     } 
    } 

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

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

     // Log the error 
     Log.e(GeofenceUtils.APPTAG, 
       context.getString(R.string.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) { 
     // Get the type of transition (entry or exit) 
     int transition = LocationClient.getGeofenceTransition(intent); 

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

      // Post a notification 
      List<Geofence> geofences = LocationClient 
        .getTriggeringGeofences(intent); 
      String[] geofenceIds = new String[geofences.size()]; 
      String ids = TextUtils.join(GeofenceUtils.GEOFENCE_ID_DELIMITER, 
        geofenceIds); 
      String transitionType = GeofenceUtils 
        .getTransitionString(transition); 

      for (int index = 0; index < geofences.size(); index++) { 
       Geofence geofence = geofences.get(index); 
       ...do something with the geofence entry or exit. I'm saving them to a local sqlite db 

      } 
      // Create an Intent to broadcast to the app 
      broadcastIntent 
        .setAction(GeofenceUtils.ACTION_GEOFENCE_TRANSITION) 
        .addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES) 
        .putExtra(GeofenceUtils.EXTRA_GEOFENCE_ID, geofenceIds) 
        .putExtra(GeofenceUtils.EXTRA_GEOFENCE_TRANSITION_TYPE, 
          transitionType); 

      LocalBroadcastManager.getInstance(MyApplication.getContext()) 
        .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, 
        context.getString(R.string.geofence_transition_invalid_type, 
          transition)); 
     } 
    } 

    /** 
    * Posts a notification in the notification bar when a transition is 
    * detected. If the user clicks the notification, control goes to the main 
    * Activity. 
    * 
    * @param transitionType 
    *   The type of transition that occurred. 
    * 
    */ 
    private void sendNotification(String transitionType, String locationName) { 

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

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

     // Adds the main Activity to the task stack as the parent 
     stackBuilder.addParentStack(MainActivity.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.ic_notification) 
       .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()); 
    } 
} 

miejmy nadzieję, że pomaga kogoś innego.

+0

Witam, pobrać i pobiegł kod Geofence ze strony internetowej dewelopera i to działało dobrze dla mnie. Klasa ReceiveTransitionService jest wywoływana nawet wtedy, gdy aplikacja jest zamknięta i jest to broadcastIntent, który jest uruchamiany w każdym przypadku – Android2390

+0

kod nie działa dla mnie z próbką Google i innym przykładem, że mam – benoffi7

+0

@ b-ryce Ten kod był bardzo przydatne dla mnie, dziękuję za to! Zastanawiam się jednak, co to było "MyApplication.getContext()"? Czy jest to kontekst dla działania GeoFenceReciever.java lub dla Ciebie? – Smoore

2

Miałem podobny problem i po wypróbowaniu różnych sposobów mogłem w końcu naprawić problem. Niestety dokumentacja Androida nie wspomina o tych problemach.
Geofence w systemie Android są usuwane przy każdym ponownym uruchomieniu urządzenia lub przy każdym przełączaniu trybu lokalizacji. So Dodaj odbiornik transmisji, aby odsłuchać ponowne uruchomienie urządzenia i zmiany trybu lokalizacji, i ponownie dodać geofences w odbiorniku.

Pisałem szczegółowe wyjaśnienie here

+0

może to być prosty komentarz, a pytanie może zostać oznaczone jako duplikat? – arkoak

+0

Tak, masz rację. nowicjusz tutaj. – Neanderthal

Powiązane problemy