forked from upstream-mirrors/OpenTracks
Add retry when sending a track to Google Drive.
This commit is contained in:
@@ -20,14 +20,16 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
|||||||
import com.google.android.apps.mytracks.content.Track;
|
import com.google.android.apps.mytracks.content.Track;
|
||||||
import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendAsyncTask;
|
import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendAsyncTask;
|
||||||
import com.google.android.apps.mytracks.io.sync.SyncUtils;
|
import com.google.android.apps.mytracks.io.sync.SyncUtils;
|
||||||
|
import com.google.android.gms.auth.GoogleAuthException;
|
||||||
|
import com.google.android.gms.auth.UserRecoverableAuthException;
|
||||||
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
|
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
|
||||||
|
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
|
||||||
import com.google.api.services.drive.Drive;
|
import com.google.api.services.drive.Drive;
|
||||||
import com.google.api.services.drive.model.File;
|
import com.google.api.services.drive.model.File;
|
||||||
import com.google.api.services.drive.model.Permission;
|
import com.google.api.services.drive.model.Permission;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@@ -38,12 +40,10 @@ import java.io.IOException;
|
|||||||
*/
|
*/
|
||||||
public class SendDriveAsyncTask extends AbstractSendAsyncTask {
|
public class SendDriveAsyncTask extends AbstractSendAsyncTask {
|
||||||
|
|
||||||
private static final String TAG = SendDriveAsyncTask.class.getSimpleName();
|
|
||||||
|
|
||||||
private final long trackId;
|
private final long trackId;
|
||||||
private final Account account;
|
private final Account account;
|
||||||
private final Context context;
|
|
||||||
private final String[] acl;
|
private final String[] acl;
|
||||||
|
private final Context context;
|
||||||
private final MyTracksProviderUtils myTracksProviderUtils;
|
private final MyTracksProviderUtils myTracksProviderUtils;
|
||||||
|
|
||||||
public SendDriveAsyncTask(SendDriveActivity activity, long trackId, Account account, String acl) {
|
public SendDriveAsyncTask(SendDriveActivity activity, long trackId, Account account, String acl) {
|
||||||
@@ -68,18 +68,18 @@ public class SendDriveAsyncTask extends AbstractSendAsyncTask {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean performTask() {
|
protected boolean performTask() {
|
||||||
GoogleAccountCredential credential = SyncUtils.getCredential(context, account.name);
|
|
||||||
if (credential == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Drive drive = SyncUtils.getDriveService(credential);
|
|
||||||
String folderId = SyncUtils.getMyTracksFolder(context, drive);
|
|
||||||
if (folderId == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
GoogleAccountCredential credential = SyncUtils.getGoogleAccountCredential(
|
||||||
|
context, account.name);
|
||||||
|
if (credential == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Drive drive = SyncUtils.getDriveService(credential);
|
||||||
|
String folderId = SyncUtils.getMyTracksFolder(context, drive);
|
||||||
|
if (folderId == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Track track = myTracksProviderUtils.getTrack(trackId);
|
Track track = myTracksProviderUtils.getTrack(trackId);
|
||||||
String driveId = track.getDriveId();
|
String driveId = track.getDriveId();
|
||||||
if (driveId != null && !driveId.equals("")) {
|
if (driveId != null && !driveId.equals("")) {
|
||||||
@@ -91,6 +91,7 @@ public class SendDriveAsyncTask extends AbstractSendAsyncTask {
|
|||||||
}
|
}
|
||||||
track.setDriveId("");
|
track.setDriveId("");
|
||||||
track.setModifiedTime(-1L);
|
track.setModifiedTime(-1L);
|
||||||
|
track.setSharedWithMe(false);
|
||||||
myTracksProviderUtils.updateTrack(track);
|
myTracksProviderUtils.updateTrack(track);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,9 +101,16 @@ public class SendDriveAsyncTask extends AbstractSendAsyncTask {
|
|||||||
}
|
}
|
||||||
addPermission(drive, id);
|
addPermission(drive, id);
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException e) {
|
} catch (UserRecoverableAuthIOException e) {
|
||||||
Log.e(TAG, "IOException", e);
|
SyncUtils.sendNotification(context, account.name, e.getIntent());
|
||||||
return false;
|
return false;
|
||||||
|
} catch (IOException e) {
|
||||||
|
return retryTask();
|
||||||
|
} catch (UserRecoverableAuthException e) {
|
||||||
|
SyncUtils.sendNotification(context, account.name, e.getIntent());
|
||||||
|
return false;
|
||||||
|
} catch (GoogleAuthException e) {
|
||||||
|
return retryTask();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,7 +118,7 @@ public class SendDriveAsyncTask extends AbstractSendAsyncTask {
|
|||||||
protected void invalidateToken() {}
|
protected void invalidateToken() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds permision.
|
* Adds permission.
|
||||||
*
|
*
|
||||||
* @param drive the drive
|
* @param drive the drive
|
||||||
* @param driveId the drive id
|
* @param driveId the drive id
|
||||||
|
|||||||
@@ -104,12 +104,11 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
|
|||||||
driveAccountName = account.name;
|
driveAccountName = account.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
String folderId = SyncUtils.getMyTracksFolder(context, drive);
|
|
||||||
if (folderId == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
String folderId = SyncUtils.getMyTracksFolder(context, drive);
|
||||||
|
if (folderId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
long largestChangeId = PreferencesUtils.getLong(
|
long largestChangeId = PreferencesUtils.getLong(
|
||||||
context, R.string.drive_largest_change_id_key);
|
context, R.string.drive_largest_change_id_key);
|
||||||
if (largestChangeId == PreferencesUtils.DRIVE_LARGEST_CHANGE_ID_DEFAULT) {
|
if (largestChangeId == PreferencesUtils.DRIVE_LARGEST_CHANGE_ID_DEFAULT) {
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import com.google.android.gms.auth.UserRecoverableAuthException;
|
|||||||
import com.google.android.maps.mytracks.R;
|
import com.google.android.maps.mytracks.R;
|
||||||
import com.google.api.client.extensions.android.http.AndroidHttp;
|
import com.google.api.client.extensions.android.http.AndroidHttp;
|
||||||
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
|
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
|
||||||
|
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
|
||||||
import com.google.api.client.http.FileContent;
|
import com.google.api.client.http.FileContent;
|
||||||
import com.google.api.client.json.gson.GsonFactory;
|
import com.google.api.client.json.gson.GsonFactory;
|
||||||
import com.google.api.services.drive.Drive;
|
import com.google.api.services.drive.Drive;
|
||||||
@@ -98,7 +99,7 @@ public class SyncUtils {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public static final String MY_TRACKS_FOLDER_QUERY =
|
public static final String MY_TRACKS_FOLDER_QUERY =
|
||||||
"'root' in parents and title = '%s' and mimeType = '" + FOLDER_MIME_TYPE
|
"'root' in parents and title = '%s' and mimeType = '" + FOLDER_MIME_TYPE
|
||||||
+ "' and trashed = false and not sharedWithMe";
|
+ "' and trashed = false";
|
||||||
|
|
||||||
private static final String TAG = SyncUtils.class.getSimpleName();
|
private static final String TAG = SyncUtils.class.getSimpleName();
|
||||||
private static final String SYNC_AUTHORITY = "com.google.android.maps.mytracks";
|
private static final String SYNC_AUTHORITY = "com.google.android.maps.mytracks";
|
||||||
@@ -129,16 +130,18 @@ public class SyncUtils {
|
|||||||
});
|
});
|
||||||
} catch (UserRecoverableAuthException e) {
|
} catch (UserRecoverableAuthException e) {
|
||||||
activity.startActivityForResult(e.getIntent(), DRIVE_PERMISSION_REQUEST_CODE);
|
activity.startActivityForResult(e.getIntent(), DRIVE_PERMISSION_REQUEST_CODE);
|
||||||
} catch (IOException e) {
|
} catch (GoogleAuthException e) {
|
||||||
Log.e(TAG, "IOException", e);
|
Log.e(TAG, "GoogleAuthException", e);
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
permissionCallback.onFailure();
|
permissionCallback.onFailure();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (GoogleAuthException e) {
|
} catch (UserRecoverableAuthIOException e) {
|
||||||
Log.e(TAG, "GoogleAuthException", e);
|
activity.startActivityForResult(e.getIntent(), DRIVE_PERMISSION_REQUEST_CODE);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "IOException", e);
|
||||||
activity.runOnUiThread(new Runnable() {
|
activity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -161,25 +164,14 @@ public class SyncUtils {
|
|||||||
try {
|
try {
|
||||||
return getGoogleAccountCredential(context, accountName);
|
return getGoogleAccountCredential(context, accountName);
|
||||||
} catch (UserRecoverableAuthException e) {
|
} catch (UserRecoverableAuthException e) {
|
||||||
Intent intent = e.getIntent();
|
sendNotification(context, accountName, e.getIntent());
|
||||||
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(NOTIFICATION_ID, builder.build());
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "IOException", e);
|
|
||||||
} catch (GoogleAuthException e) {
|
} catch (GoogleAuthException e) {
|
||||||
Log.e(TAG, "GoogleAuthException", e);
|
Log.e(TAG, "GoogleAuthException", e);
|
||||||
}
|
} catch (UserRecoverableAuthIOException e) {
|
||||||
|
sendNotification(context, accountName, e.getIntent());
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "IOException", e);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,25 +242,20 @@ public class SyncUtils {
|
|||||||
* @param context the context
|
* @param context the context
|
||||||
* @param drive the drive
|
* @param drive the drive
|
||||||
*/
|
*/
|
||||||
public static String getMyTracksFolder(Context context, Drive drive) {
|
public static String getMyTracksFolder(Context context, Drive drive) throws IOException {
|
||||||
try {
|
String folderName = context.getString(R.string.my_tracks_app_name);
|
||||||
String folderName = context.getString(R.string.my_tracks_app_name);
|
List list = drive.files()
|
||||||
List list = drive.files()
|
.list().setQ(String.format(Locale.US, MY_TRACKS_FOLDER_QUERY, folderName));
|
||||||
.list().setQ(String.format(Locale.US, MY_TRACKS_FOLDER_QUERY, folderName));
|
FileList result = list.execute();
|
||||||
FileList result = list.execute();
|
for (File file : result.getItems()) {
|
||||||
for (File file : result.getItems()) {
|
if (file.getTitle().equals(folderName)) {
|
||||||
if (file.getTitle().equals(folderName)) {
|
return file.getId();
|
||||||
return file.getId();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
File file = new File();
|
|
||||||
file.setTitle(folderName);
|
|
||||||
file.setMimeType(FOLDER_MIME_TYPE);
|
|
||||||
return drive.files().insert(file).execute().getId();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "IOException", e);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
File file = new File();
|
||||||
|
file.setTitle(folderName);
|
||||||
|
file.setMimeType(FOLDER_MIME_TYPE);
|
||||||
|
return drive.files().insert(file).execute().getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -364,6 +351,7 @@ public class SyncUtils {
|
|||||||
String id = uploadedFile.getId();
|
String id = uploadedFile.getId();
|
||||||
track.setDriveId(id);
|
track.setDriveId(id);
|
||||||
track.setModifiedTime(uploadedFile.getModifiedDate().getValue());
|
track.setModifiedTime(uploadedFile.getModifiedDate().getValue());
|
||||||
|
track.setSharedWithMe(false);
|
||||||
myTracksProviderUtils.updateTrack(track);
|
myTracksProviderUtils.updateTrack(track);
|
||||||
return id;
|
return id;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -417,7 +405,7 @@ public class SyncUtils {
|
|||||||
* @param context the context
|
* @param context the context
|
||||||
* @param accountName the account name
|
* @param accountName the account name
|
||||||
*/
|
*/
|
||||||
private static GoogleAccountCredential getGoogleAccountCredential(
|
public static GoogleAccountCredential getGoogleAccountCredential(
|
||||||
Context context, String accountName) throws IOException, GoogleAuthException {
|
Context context, String accountName) throws IOException, GoogleAuthException {
|
||||||
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(
|
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(
|
||||||
context, DriveScopes.DRIVE);
|
context, DriveScopes.DRIVE);
|
||||||
@@ -426,6 +414,29 @@ public class SyncUtils {
|
|||||||
return credential;
|
return credential;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a notification to request permission.
|
||||||
|
*
|
||||||
|
* @param context the context
|
||||||
|
* @param accountName the account name
|
||||||
|
* @param intent the intent
|
||||||
|
*/
|
||||||
|
public static void sendNotification(Context context, String accountName, Intent intent) {
|
||||||
|
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(NOTIFICATION_ID, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a file from a track.
|
* Gets a file from a track.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user