com.spire.activity_recognition.DetectionRequester.java Source code

Java tutorial

Introduction

Here is the source code for com.spire.activity_recognition.DetectionRequester.java

Source

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