mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-02 09:33:06 +02:00
Also sync "Shared with me" KML files.
This commit is contained in:
@@ -1732,8 +1732,9 @@ limitations under the License.
|
||||
account.
|
||||
|
||||
%1$s account name. E.g., 'foo@foo.com'.">
|
||||
This will remove any mappings between tracks and %1$s Google Drive. After removal, when sending
|
||||
to Google Drive or syncing with Google Drive, all tracks will be treated as new.
|
||||
This will remove mappings between tracks and %1$s Google Drive. No tracks and no Google Drive
|
||||
files will get removed. After switching account, when sending to Google Drive or syncing with
|
||||
Google Drive, all tracks will be treated as new.
|
||||
</string>
|
||||
<string name="settings_google_account_title"
|
||||
translation_description="In the 'Google' settings, the option to switch Google account.
|
||||
@@ -1747,9 +1748,8 @@ limitations under the License.
|
||||
|
||||
%1$s account name. E.g., 'foo@foo.com'.
|
||||
%2$s folder name. E.g., 'My Tracks'.">
|
||||
Check the files in %1$s Google Drive ‘%2$s’ folder. Files not mapped to existing
|
||||
tracks will be synced as new tracks. If not desired, move those files to a different folder
|
||||
beforehand.
|
||||
All files in the %1$s Google Drive ‘%2$s’ folder will be treated as new. If not
|
||||
desired, move the files to a different folder beforehand.
|
||||
</string>
|
||||
<string name="settings_google_drive_sync_summary_on"
|
||||
translation_description="In the 'Google' settings, the summary for the 'Sync Google Drive'
|
||||
|
||||
@@ -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
|
||||
|
||||
+19
-12
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -138,7 +138,7 @@ public class SyncTestUtils {
|
||||
}
|
||||
String folderId = folder.getId();
|
||||
return drive.files().list()
|
||||
.setQ(String.format(Locale.US, SyncUtils.GET_KML_FILES_QUERY, folderId)).execute()
|
||||
.setQ(String.format(Locale.US, SyncUtils.MY_TRACKS_FOLDER_FILES_QUERY, folderId)).execute()
|
||||
.getItems();
|
||||
}
|
||||
|
||||
@@ -330,7 +330,7 @@ public class SyncTestUtils {
|
||||
try {
|
||||
String folderName = context.getString(R.string.my_tracks_app_name);
|
||||
com.google.api.services.drive.Drive.Files.List list = drive.files().list()
|
||||
.setQ(String.format(Locale.US, SyncUtils.GET_MY_TRACKS_FOLDER_QUERY, folderName));
|
||||
.setQ(String.format(Locale.US, SyncUtils.MY_TRACKS_FOLDER_QUERY, folderName));
|
||||
FileList result = list.execute();
|
||||
for (File file : result.getItems()) {
|
||||
if (file.getTitle().equals(folderName)) {
|
||||
|
||||
Reference in New Issue
Block a user