Also sync "Shared with me" KML files.

This commit is contained in:
Jimmy Shih
2013-02-02 13:16:04 -08:00
parent 0fac9767fe
commit f26a8799fa
7 changed files with 144 additions and 78 deletions
@@ -208,7 +208,7 @@ public class MyTracksProvider extends ContentProvider {
getContext(), R.string.drive_sync_key, PreferencesUtils.DRIVE_SYNC_DEFAULT);
if (driveSync) {
driveIds = where != null ? getDriveIds(null, where, selectionArgs)
: getDriveIds(new String[] { TracksColumns.DRIVEID }, SyncUtils.DRIVE_IDS_QUERY, null);
: getDriveIds(new String[] { TracksColumns.DRIVEID }, SyncUtils.DRIVE_ID_TRACKS_BY_ME_QUERY, null);
}
}
@@ -84,11 +84,10 @@ public class SendDriveAsyncTask extends AbstractSendAsyncTask {
String driveId = track.getDriveId();
if (driveId != null && !driveId.equals("")) {
File driveFile = drive.files().get(driveId).execute();
if (SyncUtils.isDriveFileValid(driveFile, folderId)) {
if (SyncUtils.updateDriveFile(context, myTracksProviderUtils, drive, driveFile, track)) {
addPermission(drive, driveId);
return true;
}
if (SyncUtils.isValid(driveFile, folderId)
&& SyncUtils.updateDriveFile(context, myTracksProviderUtils, drive, driveFile, track)) {
addPermission(drive, driveId);
return true;
}
track.setDriveId("");
track.setModifiedTime(-1L);
@@ -134,27 +134,17 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
About about = drive.about().get().setFields(ABOUT_GET_FIELDS).execute();
long largestChangeId = about.getLargestChangeId();
// Get all drive files
Files.List request = drive.files()
.list().setQ(String.format(Locale.US, SyncUtils.GET_KML_FILES_QUERY, folderId));
Map<String, File> idToFileMap = new HashMap<String, File>();
do {
try {
FileList files = request.execute();
for (File file : files.getItems()) {
idToFileMap.put(file.getId(), file);
}
request.setPageToken(files.getNextPageToken());
} catch (IOException e) {
Log.e(TAG, "IOException", e);
request.setPageToken(null);
}
} while (request.getPageToken() != null && request.getPageToken().length() > 0);
// Handle new drive files
// Get all the KML files in the "My Drive:/My Tracks" folder
Files.List request = drive.files().list()
.setQ(String.format(Locale.US, SyncUtils.MY_TRACKS_FOLDER_FILES_QUERY, folderId));
Map<String, File> idToFileMap = getFiles(request);
insertNewDriveFiles(idToFileMap.values());
// Get all the KML files in the "Shared with me:/" folder
request = drive.files().list().setQ(SyncUtils.SHARED_WITH_ME_FILES_QUERY);
idToFileMap = getFiles(request);
insertNewDriveFiles(idToFileMap.values());
PreferencesUtils.setLong(context, R.string.drive_largest_change_id_key, largestChangeId);
}
@@ -172,8 +162,13 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
String deletedIds[] = TextUtils.split(driveDeletedList, ";");
for (String id : deletedIds) {
File driveFile = drive.files().get(id).execute();
if (SyncUtils.isDriveFileValid(driveFile, folderId)) {
drive.files().trash(id).execute();
if (SyncUtils.isInFolder(driveFile, folderId)) {
if (!driveFile.getLabels().getTrashed()) {
drive.files().trash(id).execute();
}
// if trashed, ignore
} else if (SyncUtils.isSharedWithMe(driveFile)) {
drive.files().delete(id).execute();
}
}
PreferencesUtils.setString(
@@ -185,7 +180,7 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
Cursor cursor = null;
try {
// Get all the local tracks with drive file id
cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.DRIVE_IDS_QUERY, null, null);
cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.DRIVE_ID_TRACKS_QUERY, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
Track track = myTracksProviderUtils.createTrack(cursor);
@@ -203,19 +198,22 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
}
changes.remove(driveId);
} else {
if (!track.isSharedWithMe()) {
// Handle the case the track has changed
File driveFile = drive.files().get(driveId).execute();
if (SyncUtils.isDriveFileValid(driveFile, folderId)) {
mergeFiles(track, driveFile);
} else {
/*
* Track has a drive id, but the drive id is no longer valid.
* E.g., the file is moved to another folder. Clear the drive id.
*/
track.setDriveId("");
track.setModifiedTime(-1L);
myTracksProviderUtils.updateTrack(track);
// Handle the case the track has changed
File driveFile = drive.files().get(driveId).execute();
if (SyncUtils.isValid(driveFile, folderId)) {
mergeFiles(track, driveFile);
} else {
/*
* Track has a drive id, but the drive id is no longer valid.
* E.g., the file is moved to another folder. Clear the drive
* id.
*/
track.setDriveId("");
track.setModifiedTime(-1L);
myTracksProviderUtils.updateTrack(track);
}
}
}
} while (cursor.moveToNext());
@@ -243,9 +241,9 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
private void insertNewTracks(String folderId) throws IOException {
Cursor cursor = null;
try {
cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.NO_DRIVE_ID_QUERY, null, null);
cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.NO_DRIVE_ID_TRACKS_QUERY, null, null);
long recordingTrackId = PreferencesUtils.getLong(context, R.string.recording_track_id_key);
if (cursor != null && cursor.moveToFirst()) {
do {
Track track = myTracksProviderUtils.createTrack(cursor);
@@ -280,6 +278,7 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
Track track = myTracksProviderUtils.getTrack(tracksIds[0]);
track.setDriveId(driveFile.getId());
track.setModifiedTime(driveFile.getModifiedDate().getValue());
track.setSharedWithMe(driveFile.getSharedWithMeDate() != null);
myTracksProviderUtils.updateTrack(track);
Log.d(TAG, "Add from Google Drive " + track.getName());
}
@@ -289,6 +288,30 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
}
}
/**
* Gets all the files from a request.
*
* @param request the request
* @return a map of file id to file
*/
private Map<String, File> getFiles(Files.List request) {
Map<String, File> idToFileMap = new HashMap<String, File>();
do {
try {
FileList files = request.execute();
for (File file : files.getItems()) {
idToFileMap.put(file.getId(), file);
}
request.setPageToken(files.getNextPageToken());
} catch (IOException e) {
Log.e(TAG, "IOException", e);
request.setPageToken(null);
}
} while (request.getPageToken() != null && request.getPageToken().length() > 0);
return idToFileMap;
}
/**
* Gets the Drive changes in the My Tracks folder. Includes deleted files.
*
@@ -310,7 +333,13 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
} else {
File file = change.getFile();
if (SyncUtils.isInFolder(file, folderId)) {
changes.put(change.getFileId(), file.getLabels().getTrashed() ? null : file);
if (file.getLabels().getTrashed()) {
changes.put(change.getFileId(), null);
} else {
changes.put(change.getFileId(), file);
}
} else if (SyncUtils.isSharedWithMe(file)) {
changes.put(change.getFileId(), file);
}
}
}
@@ -359,6 +388,7 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
Track newTrack = myTracksProviderUtils.getTrack(tracksIds[0]);
newTrack.setDriveId(driveFile.getId());
newTrack.setModifiedTime(driveModifiedTime);
newTrack.setSharedWithMe(driveFile.getSharedWithMeDate() != null);
myTracksProviderUtils.updateTrack(newTrack);
} else {
@@ -65,20 +65,38 @@ import java.util.Locale;
*/
public class SyncUtils {
// Request code to obtain Drive permission
public static final int DRIVE_PERMISSION_REQUEST_CODE = 1;
public static final String DRIVE_IDS_QUERY = TracksColumns.DRIVEID + " IS NOT NULL AND "
// Get tracks with drive id
public static final String DRIVE_ID_TRACKS_QUERY = TracksColumns.DRIVEID + " IS NOT NULL AND "
+ TracksColumns.DRIVEID + "!=''";
public static final String NO_DRIVE_ID_QUERY = TracksColumns.DRIVEID + " IS NULL OR "
// Get tracks with drive id that are owned by me, not tracks ashared with me.
public static final String DRIVE_ID_TRACKS_BY_ME_QUERY = DRIVE_ID_TRACKS_QUERY + " AND "
+ TracksColumns.SHAREDWITHME + "!=1";
// Get tracks without drive id
public static final String NO_DRIVE_ID_TRACKS_QUERY = TracksColumns.DRIVEID + " IS NULL OR "
+ TracksColumns.DRIVEID + "=''";
// KML mime type
public static final String KML_MIME_TYPE = "application/vnd.google-earth.kml+xml";
public static final String GET_KML_FILES_QUERY = "'%s' in parents and mimeType = '"
// Get My Tracks folder KML files
public static final String MY_TRACKS_FOLDER_FILES_QUERY = "'%s' in parents and mimeType = '"
+ KML_MIME_TYPE + "' and trashed = false";
// Get shared with me KML files
public static final String SHARED_WITH_ME_FILES_QUERY = "sharedWithMe and mimeType = '"
+ KML_MIME_TYPE + "'";
// Folder mime type
private static final String FOLDER_MIME_TYPE = "application/vnd.google-apps.folder";
// Get My Tracks folder
@VisibleForTesting
public static final String GET_MY_TRACKS_FOLDER_QUERY =
public static final String MY_TRACKS_FOLDER_QUERY =
"'root' in parents and title = '%s' and mimeType = '" + FOLDER_MIME_TYPE
+ "' and trashed = false";
@@ -164,7 +182,7 @@ public class SyncUtils {
}
return null;
}
/**
* Cancels any notification to request drive permission.
*
@@ -236,7 +254,7 @@ public class SyncUtils {
try {
String folderName = context.getString(R.string.my_tracks_app_name);
List list = drive.files()
.list().setQ(String.format(Locale.US, GET_MY_TRACKS_FOLDER_QUERY, folderName));
.list().setQ(String.format(Locale.US, MY_TRACKS_FOLDER_QUERY, folderName));
FileList result = list.execute();
for (File file : result.getItems()) {
if (file.getTitle().equals(folderName)) {
@@ -254,21 +272,33 @@ public class SyncUtils {
}
/**
* Returns true if the drive file is a kml file in the My Tracks folder and
* not trashed.
* Returns true if the drive file is a Shared with me KML file.
*
* @param driveFile the drive file
*/
public static boolean isSharedWithMe(File driveFile) {
if (driveFile == null) {
return false;
}
if (!SyncUtils.KML_MIME_TYPE.equals(driveFile.getMimeType())) {
return false;
}
return driveFile.getSharedWithMeDate() != null;
}
/**
* Returns true if the drive file is a valid KML file in the My Tracks folder
* and not trashed.
*
* @param driveFile the drive file
* @param folderId the My Tracks folder id
*/
public static boolean isDriveFileValid(File driveFile, String folderId) {
if (isInFolder(driveFile, folderId)) {
return !driveFile.getLabels().getTrashed();
}
return false;
public static boolean isValid(File driveFile, String folderId) {
return isInFolder(driveFile, folderId) && !driveFile.getLabels().getTrashed();
}
/**
* Returns true if the drive file is a kml file in the My Tracks folder.
* Returns true if the drive file is a KML file in the My Tracks folder.
*
* @param driveFile the drive file
* @param folderId the My Tracks folder id
@@ -121,6 +121,7 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity {
showDialog(DIALOG_CONFIRM_DRIVE_SYNC_ON);
} else {
handleSync(false);
clearSyncState();
}
return false;
}
@@ -198,8 +199,8 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity {
@Override
public void onClick(DialogInterface d, int button) {
googleAccountPreference.setValue(newValue);
clearSyncState();
handleSync(false);
clearSyncState();
updateUiByAccountName(newValue);
}
});
@@ -215,25 +216,25 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity {
}
/**
* Clears the sync state.
* Clears the sync state. Assumes sync is turned off. Do not want clearing the
* state to cause sync activities.
*/
private void clearSyncState() {
PreferencesUtils.setLong(this, R.string.drive_largest_change_id_key,
PreferencesUtils.DRIVE_LARGEST_CHANGE_ID_DEFAULT);
PreferencesUtils.setString(
this, R.string.drive_deleted_list_key, PreferencesUtils.DRIVE_DELETED_LIST_DEFAULT);
MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
Cursor cursor = null;
try {
cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.DRIVE_IDS_QUERY, null, null);
cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.DRIVE_ID_TRACKS_QUERY, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
Track track = myTracksProviderUtils.createTrack(cursor);
track.setDriveId("");
track.setModifiedTime(-1L);
track.setSharedWithMe(false);
myTracksProviderUtils.updateTrack(track);
if (track.isSharedWithMe()) {
myTracksProviderUtils.deleteTrack(track.getId());
} else {
track.setDriveId("");
track.setModifiedTime(-1L);
track.setSharedWithMe(false);
myTracksProviderUtils.updateTrack(track);
}
} while (cursor.moveToNext());
}
} finally {
@@ -241,6 +242,12 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity {
cursor.close();
}
}
PreferencesUtils.setLong(this, R.string.drive_largest_change_id_key,
PreferencesUtils.DRIVE_LARGEST_CHANGE_ID_DEFAULT);
// Clear the driveDeletedList last
PreferencesUtils.setString(
this, R.string.drive_deleted_list_key, PreferencesUtils.DRIVE_DELETED_LIST_DEFAULT);
}
/**