Files
OpenTracks/MyTracks/src/com/google/android/apps/mytracks/AbstractSendToGoogleActivity.java
T

413 lines
15 KiB
Java

/*
* 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;
import com.google.android.apps.mytracks.fragments.CheckPermissionFragment;
import com.google.android.apps.mytracks.fragments.CheckPermissionFragment.CheckPermissionCaller;
import com.google.android.apps.mytracks.fragments.ChooseAccountDialogFragment;
import com.google.android.apps.mytracks.fragments.ChooseAccountDialogFragment.ChooseAccountCaller;
import com.google.android.apps.mytracks.fragments.ConfirmDeleteDialogFragment;
import com.google.android.apps.mytracks.fragments.ConfirmDeleteDialogFragment.ConfirmDeleteCaller;
import com.google.android.apps.mytracks.fragments.ConfirmSyncDialogFragment;
import com.google.android.apps.mytracks.fragments.ConfirmSyncDialogFragment.ConfirmSyncCaller;
import com.google.android.apps.mytracks.fragments.InstallEarthDialogFragment;
import com.google.android.apps.mytracks.fragments.ShareTrackDialogFragment;
import com.google.android.apps.mytracks.fragments.ShareTrackDialogFragment.ShareTrackCaller;
import com.google.android.apps.mytracks.io.drive.SendDriveActivity;
import com.google.android.apps.mytracks.io.file.TrackFileFormat;
import com.google.android.apps.mytracks.io.file.exporter.SaveActivity;
import com.google.android.apps.mytracks.io.fusiontables.SendFusionTablesActivity;
import com.google.android.apps.mytracks.io.gdata.maps.MapsConstants;
import com.google.android.apps.mytracks.io.maps.SendMapsActivity;
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils;
import com.google.android.apps.mytracks.io.sendtogoogle.UploadResultActivity;
import com.google.android.apps.mytracks.io.spreadsheets.SendSpreadsheetsActivity;
import com.google.android.apps.mytracks.io.sync.SyncUtils;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.AnalyticsUtils;
import com.google.android.apps.mytracks.util.GoogleEarthUtils;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
import com.google.android.maps.mytracks.R;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.widget.Toast;
import java.io.IOException;
/**
* An abstract class for sending a track to Google services.
*
* @author Jimmy Shih
*/
public abstract class AbstractSendToGoogleActivity extends AbstractMyTracksActivity implements
ChooseAccountCaller, ConfirmSyncCaller, CheckPermissionCaller, ShareTrackCaller,
ConfirmDeleteCaller {
private static final String TAG = AbstractMyTracksActivity.class.getSimpleName();
private static final String SEND_REQUEST_KEY = "send_request_key";
private static final int DRIVE_REQUEST_CODE = 0;
private static final int FUSION_TABLES_REQUEST_CODE = 1;
private static final int SPREADSHEETS_REQUEST_CODE = 2;
private static final int DELETE_REQUEST_CODE = 3;
protected static final int GOOGLE_PLAY_SERVICES_REQUEST_CODE = 4;
protected static final int CAMERA_REQUEST_CODE = 5;
private SendRequest sendRequest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
sendRequest = savedInstanceState.getParcelable(SEND_REQUEST_KEY);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(SEND_REQUEST_KEY, sendRequest);
}
/**
* Share a track.
*
* @param trackId the track id
*/
protected void shareTrack(long trackId) {
AnalyticsUtils.sendPageViews(this, AnalyticsUtils.ACTION_SHARE_DRIVE);
SendRequest newRequest;
newRequest = new SendRequest(trackId);
newRequest.setSendDrive(true);
newRequest.setDriveShare(true);
sendToGoogle(newRequest);
}
/**
* Sends a request to Google.
*
* @param request the request
*/
protected void sendToGoogle(SendRequest request) {
sendRequest = request;
new ChooseAccountDialogFragment().show(
getSupportFragmentManager(), ChooseAccountDialogFragment.CHOOSE_ACCOUNT_DIALOG_TAG);
}
@Override
public void onChooseAccountDone() {
String googleAccount = PreferencesUtils.getString(
this, R.string.google_account_key, PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT);
if (googleAccount == null || googleAccount.equals(PreferencesUtils.GOOGLE_ACCOUNT_DEFAULT)) {
return;
}
sendRequest.setAccount(new Account(googleAccount, Constants.ACCOUNT_TYPE));
if (sendRequest.isSendDrive() && sendRequest.isDriveSync() && sendRequest.isDriveSyncConfirm()) {
new ConfirmSyncDialogFragment().show(
getSupportFragmentManager(), ConfirmSyncDialogFragment.CONFIRM_SYNC_DIALOG_TAG);
} else {
onConfirmSyncDone(true);
}
}
@Override
public void onConfirmSyncDone(boolean enable) {
if (enable) {
// Check Drive permission
boolean needDrivePermission = sendRequest.isSendDrive();
if (!needDrivePermission && sendRequest.isSendFusionTables()) {
needDrivePermission = PreferencesUtils.getBoolean(this,
R.string.export_google_fusion_tables_public_key,
PreferencesUtils.EXPORT_GOOGLE_FUSION_TABLES_PUBLIC_DEFAULT);
}
if (!needDrivePermission) {
needDrivePermission = sendRequest.isSendSpreadsheets();
}
if (needDrivePermission) {
Fragment fragment = CheckPermissionFragment.newInstance(
sendRequest.getAccount().name, SendToGoogleUtils.DRIVE_SCOPE);
getSupportFragmentManager().beginTransaction()
.add(fragment, CheckPermissionFragment.CHECK_PERMISSION_TAG).commit();
} else {
onDrivePermissionSuccess();
}
}
}
@Override
public void onCheckPermissionDone(String scope, boolean success, Intent intent) {
if (success) {
if (scope.equals(SendToGoogleUtils.DRIVE_SCOPE)) {
onDrivePermissionSuccess();
} else if (scope.equals(SendToGoogleUtils.FUSION_TABLES_SCOPE)) {
onFusionTablesSuccess();
} else {
onSpreadsheetsPermissionSuccess();
}
} else {
if (intent != null) {
int requestCode;
if (scope.equals(SendToGoogleUtils.DRIVE_SCOPE)) {
requestCode = DRIVE_REQUEST_CODE;
} else if (scope.equals(SendToGoogleUtils.FUSION_TABLES_SCOPE)) {
requestCode = FUSION_TABLES_REQUEST_CODE;
} else {
requestCode = SPREADSHEETS_REQUEST_CODE;
}
startActivityForResult(intent, requestCode);
} else {
onPermissionFailure();
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case DRIVE_REQUEST_CODE:
SendToGoogleUtils.cancelNotification(this, SendToGoogleUtils.DRIVE_NOTIFICATION_ID);
if (resultCode == Activity.RESULT_OK) {
onDrivePermissionSuccess();
} else {
onPermissionFailure();
}
break;
case FUSION_TABLES_REQUEST_CODE:
SendToGoogleUtils.cancelNotification(this, SendToGoogleUtils.FUSION_TABLES_NOTIFICATION_ID);
if (resultCode == Activity.RESULT_OK) {
onFusionTablesSuccess();
} else {
onPermissionFailure();
}
break;
case SPREADSHEETS_REQUEST_CODE:
SendToGoogleUtils.cancelNotification(this, SendToGoogleUtils.SPREADSHEETS_NOTIFICATION_ID);
if (resultCode == Activity.RESULT_OK) {
onSpreadsheetsPermissionSuccess();
} else {
onPermissionFailure();
}
break;
case DELETE_REQUEST_CODE:
onDeleted();
break;
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
private void onDrivePermissionSuccess() {
// Check Maps permission
if (sendRequest.isSendMaps()) {
AccountManager.get(this).getAuthToken(
sendRequest.getAccount(), MapsConstants.SERVICE_NAME, null, this,
new AccountManagerCallback<Bundle>() {
@Override
public void run(AccountManagerFuture<Bundle> future) {
try {
if (future.getResult().getString(AccountManager.KEY_AUTHTOKEN) != null) {
runOnUiThread(new Runnable() {
@Override
public void run() {
onMapsPermissionSuccess();
}
});
return;
} else {
Log.d(TAG, "auth token is null");
}
} catch (OperationCanceledException e) {
Log.d(TAG, "Unable to get auth token", e);
} catch (AuthenticatorException e) {
Log.d(TAG, "Unable to get auth token", e);
} catch (IOException e) {
Log.d(TAG, "Unable to get auth token", e);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
onPermissionFailure();
}
});
}
}, null);
} else {
onMapsPermissionSuccess();
}
}
private void onMapsPermissionSuccess() {
// Check Fusion Tables permission
if (sendRequest.isSendFusionTables()) {
Fragment fragment = CheckPermissionFragment.newInstance(
sendRequest.getAccount().name, SendToGoogleUtils.FUSION_TABLES_SCOPE);
getSupportFragmentManager()
.beginTransaction().add(fragment, CheckPermissionFragment.CHECK_PERMISSION_TAG).commit();
} else {
onFusionTablesSuccess();
}
}
private void onFusionTablesSuccess() {
// Check Spreadsheets permission
if (sendRequest.isSendSpreadsheets()) {
Fragment fragment = CheckPermissionFragment.newInstance(
sendRequest.getAccount().name, SendToGoogleUtils.SPREADSHEETS_SCOPE);
getSupportFragmentManager()
.beginTransaction().add(fragment, CheckPermissionFragment.CHECK_PERMISSION_TAG).commit();
} else {
onSpreadsheetsPermissionSuccess();
}
}
/**
* On spreadsheets permission success. If
* <p>
* isSendDrive and isDriveEnableSync -> enable sync
* <p>
* isSendDrive and isDriveShare -> show {@link ShareTrackDialogFragment}
* <p>
* isSendDrive -> start {@link SendDriveActivity}
* <p>
* isSendMaps -> start {@link SendMapsActivity}
* <p>
* isSendFusionTables -> start {@link SendFusionTablesActivity}
* <p>
* isSendSpreadsheets -> start {@link SendSpreadsheetsActivity}
* <p>
* else -> start {@link UploadResultActivity}
*/
private void onSpreadsheetsPermissionSuccess() {
Class<?> next;
if (sendRequest.isSendDrive()) {
if (sendRequest.isDriveSync()) {
PreferencesUtils.setBoolean(this, R.string.drive_sync_key, true);
// Turn off everything
SyncUtils.disableSync(this);
// Turn on sync
ContentResolver.setMasterSyncAutomatically(true);
// Enable sync for account
SyncUtils.enableSync(sendRequest.getAccount());
return;
} else if (sendRequest.isDriveShare()) {
ShareTrackDialogFragment.newInstance(sendRequest.getTrackId())
.show(getSupportFragmentManager(), ShareTrackDialogFragment.SHARE_TRACK_DIALOG_TAG);
return;
} else {
next = SendDriveActivity.class;
}
} else if (sendRequest.isSendMaps()) {
next = SendMapsActivity.class;
} else if (sendRequest.isSendFusionTables()) {
next = SendFusionTablesActivity.class;
} else if (sendRequest.isSendSpreadsheets()) {
next = SendSpreadsheetsActivity.class;
} else {
next = UploadResultActivity.class;
}
Intent intent = IntentUtils.newIntent(this, next)
.putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
startActivity(intent);
}
/**
* Call when not able to get permission for a google service.
*/
private void onPermissionFailure() {
Toast.makeText(this, R.string.send_google_no_account_permission, Toast.LENGTH_LONG).show();
}
@Override
public void onShareTrackDone(String emails, boolean makePublic) {
sendRequest.setDriveShareEmails(emails);
sendRequest.setDriveSharePublic(makePublic);
Intent intent = IntentUtils.newIntent(this, SendDriveActivity.class)
.putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
startActivity(intent);
}
/**
* Play track in Google Earth.
*
* @param trackIds the track ids
*/
protected void playTrack(long[] trackIds) {
AnalyticsUtils.sendPageViews(this, AnalyticsUtils.ACTION_PLAY);
if (GoogleEarthUtils.isEarthInstalled(this)) {
Intent intent = IntentUtils.newIntent(this, SaveActivity.class)
.putExtra(SaveActivity.EXTRA_TRACK_IDS, trackIds)
.putExtra(SaveActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) TrackFileFormat.KML)
.putExtra(SaveActivity.EXTRA_PLAY_TRACK, true);
startActivity(intent);
} else {
new InstallEarthDialogFragment().show(
getSupportFragmentManager(), InstallEarthDialogFragment.INSTALL_EARTH_DIALOG_TAG);
}
}
protected void deleteTrack(long[] trackIds) {
ConfirmDeleteDialogFragment.newInstance(trackIds)
.show(getSupportFragmentManager(), ConfirmDeleteDialogFragment.CONFIRM_DELETE_DIALOG_TAG);
}
abstract protected TrackRecordingServiceConnection getTrackRecordingServiceConnection();
abstract protected void onDeleted();
@Override
public void onConfirmDeleteDone(long[] trackIds) {
boolean stopRecording = false;
if (trackIds.length == 1 && trackIds[0] == -1L) {
stopRecording = true;
} else {
long recordingTrackId = PreferencesUtils.getLong(this, R.string.recording_track_id_key);
for (long trackId : trackIds) {
if (trackId == recordingTrackId) {
stopRecording = true;
break;
}
}
}
if (stopRecording) {
TrackRecordingServiceConnectionUtils.stopRecording(
this, getTrackRecordingServiceConnection(), false);
}
Intent intent = IntentUtils.newIntent(this, DeleteActivity.class);
intent.putExtra(DeleteActivity.EXTRA_TRACK_IDS, trackIds);
startActivityForResult(intent, DELETE_REQUEST_CODE);
}
}