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.anthonykeane.speedzone; import android.app.IntentService; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.provider.Settings; import android.support.v4.app.NotificationCompat; import android.util.Log; import com.google.android.gms.location.ActivityRecognitionResult; import com.google.android.gms.location.DetectedActivity; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; /** * Service that receives ActivityRecognition updates. It receives updates * in the background, even if the main Activity is not visible. */ public class ActivityRecognitionIntentService extends IntentService { // Formats the timestamp in the log private static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd HH:mm:ss.SSSZ"; // Delimits the timestamp from the log info private static final String LOG_DELIMITER = ";;"; // A date formatter private SimpleDateFormat mDateFormat; // Store the app's shared preferences repository private SharedPreferences mPrefs; public ActivityRecognitionIntentService() { // Set the label for the service's background thread super("ActivityRecognitionIntentService"); } /** * Called when a new activity detection update is available. */ @Override protected void onHandleIntent(Intent intent) { // Get a handle to the repository mPrefs = getApplicationContext().getSharedPreferences(ActivityUtils.SHARED_PREFERENCES, Context.MODE_PRIVATE); // Get a date formatter, and catch errors in the returned timestamp try { mDateFormat = (SimpleDateFormat) DateFormat.getDateTimeInstance(); } catch (Exception e) { Log.e(ActivityUtils.APPTAG, getString(R.string.date_format_error)); } // Format the timestamp according to the pattern, then localize the pattern mDateFormat.applyPattern(DATE_FORMAT_PATTERN); mDateFormat.applyLocalizedPattern(mDateFormat.toLocalizedPattern()); // If the intent contains an update if (ActivityRecognitionResult.hasResult(intent)) { // Get the update ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent); // Log the update logActivityRecognitionResult(result); // Get the most probable activity from the list of activities in the update DetectedActivity mostProbableActivity = result.getMostProbableActivity(); // Get the confidence percentage for the most probable activity int confidence = mostProbableActivity.getConfidence(); // Get the type of activity int activityType = mostProbableActivity.getType(); // Check to see if the repository contains a previous activity if (!mPrefs.contains(ActivityUtils.KEY_PREVIOUS_ACTIVITY_TYPE)) { // This is the first type an activity has been detected. Store the type SharedPreferences.Editor editor = mPrefs.edit(); editor.putInt(ActivityUtils.KEY_PREVIOUS_ACTIVITY_TYPE, activityType); editor.commit(); // If the repository contains a type } else if (activityChanged(activityType) // The activity has changed from the previous activity && (confidence >= 80)) // The confidence level for the current activity is > 50% { switch (activityType) { case DetectedActivity.IN_VEHICLE: Intent callIntent = new Intent(Intent.ACTION_CALL); callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); callIntent.setClass(getApplicationContext(), MainActivity.class); // todo callIntent.putExtra("bZoneError",bZoneError); startActivity(callIntent); break; //case DetectedActivity.STILL: //case DetectedActivity.ON_BICYCLE: case DetectedActivity.ON_FOOT: //sendNotification(); break; } } } } /** * Post a notification to the user. The notification prompts the user to click it to * open the device's GPS settings */ private void sendNotification() { // Create a notification builder that's compatible with platforms >= version 4 NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext()); // Set the title, text, and icon builder.setContentTitle(getString(R.string.app_name)); builder.setContentText(getString(R.string.NotificationText)); builder.setSmallIcon(R.drawable.ic_launcher); //builder.setContentIntent(WhatToDoWhenNotificationIsClicked()); // Get an instance of the Notification Manager NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // Build the notification and post it notifyManager.notify(0, builder.build()); } /** * Get a content Intent for the notification * * @return A PendingIntent that starts the device's Location Settings panel. */ private PendingIntent WhatToDoWhenNotificationIsClicked() { // Set the Intent action to open Location Settings Intent gpsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); // Create a PendingIntent to start an Activity return PendingIntent.getActivity(getApplicationContext(), 0, gpsIntent, PendingIntent.FLAG_UPDATE_CURRENT); } /** * Tests to see if the activity has changed * * @param currentType The current activity type * @return true if the user's current activity is different from the previous most probable * activity; otherwise, false. */ private boolean activityChanged(int currentType) { // Get the previous type, otherwise return the "unknown" type int previousType = mPrefs.getInt(ActivityUtils.KEY_PREVIOUS_ACTIVITY_TYPE, DetectedActivity.UNKNOWN); // If the previous type isn't the same as the current type, the activity has changed return previousType != currentType; } /** * Determine if an activity means that the user is moving. * * @param type The type of activity the user is doing (see DetectedActivity constants) * @return true if the user seems to be moving from one location to another, otherwise false */ private boolean isMoving(int type) { switch (type) { // These types mean that the user is probably not moving case DetectedActivity.STILL: case DetectedActivity.TILTING: case DetectedActivity.UNKNOWN: return false; default: return true; } } /** * Write the activity recognition update to the log file * * @param result The result extracted from the incoming Intent */ private void logActivityRecognitionResult(ActivityRecognitionResult result) { // Get all the probably activities from the updated result for (DetectedActivity detectedActivity : result.getProbableActivities()) { // Get the activity type, confidence level, and human-readable name int activityType = detectedActivity.getType(); int confidence = detectedActivity.getConfidence(); String activityName = getNameFromType(activityType); // Make a timestamp String timeStamp = mDateFormat.format(new Date()); // Get the current log file or create a new one, then log the activity LogFile.getInstance(getApplicationContext()).log(timeStamp + LOG_DELIMITER + getString(R.string.log_message, activityType, activityName, confidence)); } } /** * Map detected activity types to strings * * @param activityType The detected activity type * @return A user-readable name for the type */ private String getNameFromType(int activityType) { switch (activityType) { case DetectedActivity.IN_VEHICLE: return "in_vehicle"; case DetectedActivity.ON_BICYCLE: return "on_bicycle"; case DetectedActivity.ON_FOOT: return "on_foot"; case DetectedActivity.STILL: return "still"; case DetectedActivity.UNKNOWN: return "unknown"; case DetectedActivity.TILTING: return "tilting"; } return "unknown"; } }