Java tutorial
/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.spire.activity_recognition; import android.app.Activity; import android.app.Dialog; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.IntentSender.SendIntentException; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.util.Log; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks; import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.location.ActivityRecognitionClient; import com.spire.debug.Debug; import com.spire.parking_procedure.TrackingService; /** * Class for connecting to Location Services and activity recognition updates. * <b> * Note: Clients must ensure that Google Play services is available before requesting updates. * </b> Use GooglePlayServicesUtil.isGooglePlayServicesAvailable() to check. * * * To use a DetectionRequester, instantiate it and call requestUpdates(). Everything else is done * automatically. * */ public class DetectionRequester implements ConnectionCallbacks, OnConnectionFailedListener { private static final String TAG = "DetectionRequester"; // Storage for a context from the calling client private Context mContext; // Stores the PendingIntent used to send activity recognition events back to the app private PendingIntent mActivityRecognitionPendingIntent; // Stores the current instantiation of the activity recognition client private ActivityRecognitionClient mActivityRecognitionClient; public DetectionRequester(Context context) { Debug.log(TAG, "Class constructor executed."); // Save the context mContext = context; // Initialize the globals to null mActivityRecognitionPendingIntent = null; mActivityRecognitionClient = null; } /** * Returns the current PendingIntent to the caller. * * @return The PendingIntent used to request activity recognition updates */ public PendingIntent getRequestPendingIntent() { return mActivityRecognitionPendingIntent; } /** * Sets the PendingIntent used to make activity recognition update requests * @param intent The PendingIntent */ public void setRequestPendingIntent(PendingIntent intent) { mActivityRecognitionPendingIntent = intent; } /** * Start the activity recognition update request process by * getting a connection. */ public void requestUpdates() { // Log.e(TAG, "requestUpdates"); Debug.log(TAG, "requestUpdates"); requestConnection(); } /** * Make the actual update request. This is called from onConnected(). */ private void continueRequestActivityUpdates() { /* * Request updates, using the default detection interval. * The PendingIntent sends updates to ActivityRecognitionIntentService */ Debug.log(TAG, "continueRequestActivityUpdates"); getActivityRecognitionClient().requestActivityUpdates(ActivityUtils.DETECTION_INTERVAL_MILLISECONDS, createRequestPendingIntent()); // MJR was "createRequestPendingIntent" from Citat // Disconnect the client requestDisconnection(); } /** * 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() { Debug.log(TAG, "requestConnection"); if (!getActivityRecognitionClient().isConnected()) getActivityRecognitionClient().connect(); } /** * Get the current activity recognition client, or create a new one if necessary. * This method facilitates multiple requests for a client, even if a previous * request wasn't finished. Since only one client object exists while a connection * is underway, no memory leaks occur. * * @return An ActivityRecognitionClient object */ private ActivityRecognitionClient getActivityRecognitionClient() { Debug.log(TAG, "getActivityRecognitionClient"); if (mActivityRecognitionClient == null) { mActivityRecognitionClient = new ActivityRecognitionClient(mContext, this, this); } return mActivityRecognitionClient; } /** * Get the current activity recognition client and disconnect from Location Services */ private void requestDisconnection() { getActivityRecognitionClient().disconnect(); } /* * Called by Location Services once the activity recognition client is connected. * * Continue by requesting activity updates. */ @Override public void onConnected(Bundle arg0) { // If debugging, log the connection // Log.d(ActivityUtils.APPTAG, mContext.getString(R.string.connected)); // Continue the process of requesting activity recognition updates switch (TrackingService.mRequestType) { case START: continueRequestActivityUpdates(); break; case STOP: getActivityRecognitionClient().removeActivityUpdates(mActivityRecognitionPendingIntent); break; default: Debug.log(TAG, "Unknown request type in onConnected"); break; } } /* * Called by Location Services once the activity recognition client is disconnected. */ @Override public void onDisconnected() { // In debug mode, log the disconnection // Log.d(ActivityUtils.APPTAG, mContext.getString(R.string.disconnected)); // Destroy the current activity recognition client mActivityRecognitionClient = null; } /** * Get a PendingIntent to send with the request to get activity recognition updates. Location * Services issues the Intent inside this PendingIntent whenever a activity recognition update * occurs. * * @return A PendingIntent for the IntentService that handles activity recognition updates. */ private PendingIntent createRequestPendingIntent() { // If the PendingIntent already exists if (getRequestPendingIntent() != null) { // Return the existing intent Debug.log(TAG, "createRequestPendingIntent: Returning an existing one"); return mActivityRecognitionPendingIntent; // If no PendingIntent exists } else { Debug.log(TAG, "createRequestPendingIntent: Creating a new pointer."); // Create an Intent pointing to the IntentService Intent intent = new Intent(mContext, ActivityRecognitionIntentService.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. */ mActivityRecognitionPendingIntent = PendingIntent.getService(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); setRequestPendingIntent(mActivityRecognitionPendingIntent); return mActivityRecognitionPendingIntent; } } /* * 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) { /* * 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 { connectionResult.startResolutionForResult((Activity) mContext, ActivityUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST); /* * Thrown if Google Play services canceled the original * PendingIntent */ } catch (SendIntentException e) { // display an error or log it here. e.printStackTrace(); } /* * If no resolution is available, display Google * Play service error dialog. This may direct the * user to Google Play Store if Google Play services * is out of date. */ } else { Dialog dialog = GooglePlayServicesUtil.getErrorDialog(connectionResult.getErrorCode(), (Activity) mContext, ActivityUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST); if (dialog != null) { dialog.show(); } } } }