/* * Copyright 2012 Google Inc. * * 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.google.android.apps.mytracks.io.sendtogoogle; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.util.LocationUtils; import com.google.android.gms.auth.GoogleAuthException; import com.google.android.maps.mytracks.R; import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential; import com.google.api.services.drive.DriveScopes; import com.google.api.services.fusiontables.FusiontablesScopes; import com.google.common.annotations.VisibleForTesting; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.location.Location; import android.support.v4.app.NotificationCompat; import android.util.Log; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * Commons utilities for sending a track to Google. * * @author Jimmy Shih */ public class SendToGoogleUtils { private static final String TAG = SendToGoogleUtils.class.getSimpleName(); public static final String DRIVE_SCOPE = DriveScopes.DRIVE; public static final int DRIVE_NOTIFICATION_ID = 1; public static final String FUSION_TABLES_SCOPE = FusiontablesScopes.FUSIONTABLES; public static final int FUSION_TABLES_NOTIFICATION_ID = 2; public static final String SPREADSHEETS_SCOPE = "https://spreadsheets.google.com/feeds"; public static final int SPREADSHEETS_NOTIFICATION_ID = 3; private SendToGoogleUtils() {} /** * Prepares a list of locations to send to Google Maps or Google Fusion * Tables. Splits the locations into segments if necessary. * * @param track the track * @param locations the list of locations * @return an array of split segments. */ public static ArrayList<Track> prepareLocations(Track track, List<Location> locations) { ArrayList<Track> splitTracks = new ArrayList<Track>(); // Create a new segment Track segment = createNewSegment( track, locations.size() > 0 ? locations.get(0).getTime() : -1L); for (Location location : locations) { /* * Latitude is greater than 90 if the location is a pause/resume * separator. */ if (location.getLatitude() > 90) { endSegment(segment, location.getTime(), splitTracks); segment = createNewSegment(track, location.getTime()); } else { segment.addLocation(location); } } endSegment(segment, locations.size() > 0 ? locations.get(locations.size() - 1).getTime() : -1L, splitTracks); return splitTracks; } /** * Creates a new segment for a track. * * @param track the track * @param startTime the segment start time */ private static Track createNewSegment(Track track, long startTime) { Track segment = new Track(); segment.setId(track.getId()); segment.setName(track.getName()); segment.setDescription(""); segment.setCategory(track.getCategory()); TripStatistics segmentTripStatistics = segment.getTripStatistics(); segmentTripStatistics.setStartTime(startTime); return segment; } /** * Ends a segment. Adds to the array of track segments if the segment is * valid. * * @param segment the segment * @param stopTime the stop time * @param splitTracks the array of track segments */ @VisibleForTesting static boolean endSegment(Track segment, long stopTime, ArrayList<Track> splitTracks) { // Make sure the segment has at least 2 points if (segment.getLocations().size() < 2) { Log.d(TAG, "segment has less than 2 points"); return false; } // Set its stop time segment.getTripStatistics().setStopTime(stopTime); /* * Decimate to 2 meter precision. Google Maps and Google Fusion Tables do * not like the locations to be too precise. */ LocationUtils.decimate(segment, 2.0); splitTracks.add(segment); return true; } /** * Gets the google account credential. * * @param context the context * @param accountName the account name * @param scope the scope */ public static GoogleAccountCredential getGoogleAccountCredential( Context context, String accountName, String scope) throws IOException, GoogleAuthException { GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(context, scope); credential.setSelectedAccountName(accountName); credential.getToken(); return credential; } /** * Gets the OAuth2 token. * * @param context the context * @param accountName the account name * @param scope the scope */ public static String getToken(Context context, String accountName, String scope) throws IOException, GoogleAuthException { GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(context, scope); credential.setSelectedAccountName(accountName); return credential.getToken(); } /** * Sends a notification to request permission. * * @param context the context * @param accountName the account name * @param intent the intent * @param notificaitonId the notification id */ public static void sendNotification( Context context, String accountName, Intent intent, int notificaitonId) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).addFlags(Intent.FLAG_FROM_BACKGROUND); PendingIntent pendingIntent = PendingIntent.getActivity( context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder = new NotificationCompat.Builder(context).setAutoCancel(true) .setContentIntent(pendingIntent) .setContentText(context.getString(R.string.permission_request_message, accountName)) .setContentTitle(context.getString(R.string.permission_request_title)) .setSmallIcon(android.R.drawable.ic_dialog_alert) .setTicker(context.getString(R.string.permission_request_title)); NotificationManager notificationManager = (NotificationManager) context.getSystemService( Context.NOTIFICATION_SERVICE); notificationManager.notify(notificaitonId, builder.build()); } /** * Cancels any notification to request a permission. * * @param context the context * @param notificationId the notification id */ public static void cancelNotification(Context context, int notificationId) { NotificationManager notificationManager = (NotificationManager) context.getSystemService( Context.NOTIFICATION_SERVICE); notificationManager.cancel(notificationId); } }