使用Google Play服务6.5.87进行Android Geofencing

时间:2014-12-14 17:33:47

标签: java android google-play-services google-api-client geofencing

我对Google Play Services 6.1.71没有任何问题(因为一切正常)但与新版本(6.5.87)不一样。

我已经知道在6.5.87 Google Play服务课程中不推荐使用LocationClient课程,转换old GeofenceDetection sample.

时我没什么问题
  1. 我有第一个问题,有了新的Play服务我找不到OnAddGeofencesResultListenerOnRemoveGeofencesResultListener我曾经在控制台上处理错误;
  2. 第二个问题(主要问题)是添加地理围栏点。当我尝试添加一个请求时,我收到一个待定的无限期......
  3. 我修改过的代码是:

    ReceiveTransitionsIntentService.java

    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(GeofenceUtils.CATEGORY_LOCATION_SERVICES);
            GeofencingEvent geoFenceEvent = GeofencingEvent.fromIntent(intent);
    
            // First check for errors
            if (geoFenceEvent.hasError()) {
                // Get the error code
                int errorCode = geoFenceEvent.getErrorCode();
    
                // Get the error message
                String errorMessage = LocationServiceErrorMessages.getErrorString(this, errorCode);
    
                // Log the error
                Log.e(GeofenceUtils.APPTAG, 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(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 = geoFenceEvent.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 = geoFenceEvent.getTriggeringGeofences();
                    String[] geofenceIds = new String[geofences.size()];
                    for (int index = 0; index < geofences.size(); index++) {
                        geofenceIds[index] = geofences.get(index).getRequestId();
                    }
                    String ids = TextUtils.join(GeofenceUtils.GEOFENCE_ID_DELIMITER, geofenceIds);
                    String transitionType = getTransitionString(transition);
    
                    sendNotification(transitionType, ids);
    
                    // Log the transition type and a message
                    Log.d(GeofenceUtils.APPTAG, getString(R.string.geofence_transition_notification_title, transitionType, ids));
                    Log.d(GeofenceUtils.APPTAG, getString(R.string.geofence_transition_notification_text));
    
                    // An invalid transition was reported
                } else {
                    // Always log as an error
                    Log.e(GeofenceUtils.APPTAG,
                            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 ids) {
    
            // Create an explicit content Intent that starts the main Activity
            Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
    
            // Construct a task stack
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    
            // 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(this);
    
            // Set the notification contents
            builder.setSmallIcon(R.drawable.ic_notification)
                    .setContentTitle(getString(R.string.geofence_transition_notification_title, transitionType, ids))
                    .setContentText(getString(R.string.geofence_transition_notification_text))
                    .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 getString(R.string.geofence_transition_entered);
                case Geofence.GEOFENCE_TRANSITION_EXIT:
                    return getString(R.string.geofence_transition_exited);
                default:
                    return getString(R.string.geofence_transition_unknown);
            }
        }
    }
    

    GeofenceRequester.java

    public class GeofenceRequester implements
            ConnectionCallbacks,
            OnConnectionFailedListener,
            GoogleApiClient.ConnectionCallbacks,
            GoogleApiClient.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 GoogleApiClient mGoogleApiClient;
    
        /*
         * 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;
            mGoogleApiClient = 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 GoogleApiClient getLocationClient() {
            if (mGoogleApiClient == null) {
    
                mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
                        .addApi(LocationServices.API)
                        .addConnectionCallbacks(this)
                        .addOnConnectionFailedListener(this)
                        .build();
            }
            return mGoogleApiClient;
    
        }
    
        /**
         * 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
            LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, mCurrentGeofences, mGeofencePendingIntent);
        }
    
        /**
         * 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(GeofenceUtils.APPTAG, mActivity.getString(R.string.connected));
    
            // Continue adding the geofences
            continueAddGeofences();
        }
    
        @Override
        public void onConnectionSuspended(int i) {
    
        }
    
        /*
         * 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(GeofenceUtils.APPTAG, mActivity.getString(R.string.disconnected));
    
            // Destroy the current location client
            mGoogleApiClient = 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,
                            GeofenceUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);
    
                    /*
                     * 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(GeofenceUtils.ACTION_CONNECTION_ERROR);
                errorBroadcastIntent.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES)
                        .putExtra(GeofenceUtils.EXTRA_CONNECTION_ERROR_CODE,
                                connectionResult.getErrorCode());
                LocalBroadcastManager.getInstance(mActivity).sendBroadcast(errorBroadcastIntent);
            }
        }
    }
    

1 个答案:

答案 0 :(得分:2)

要替换OnAddGeofencesResultListener,请使用ResultCallback

LocationServices.GeofencingApi
  .addGeofences(mGoogleApiClient, mCurrentGeofences, mGeofencePendingIntent)
  .setResultCallback(new ResultCallback<Status>() {
    @Override
    public void onResult(Status status) {
      if (status.isSuccess()) {
        // Success
      }
    }
 });