forked from upstream-mirrors/OpenTracks
Add columns driveid, modifiedtime, and sharedwithme
Add tombstone when a track is deleted
This commit is contained in:
@@ -37,6 +37,8 @@ import android.os.Process;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A {@link ContentProvider} that handles access to track points, tracks, and
|
||||
* waypoints tables.
|
||||
@@ -46,32 +48,35 @@ import android.util.Log;
|
||||
public class MyTracksProvider extends ContentProvider {
|
||||
|
||||
private static final String TAG = MyTracksProvider.class.getSimpleName();
|
||||
private static final int DATABASE_VERSION = 21;
|
||||
private static final String DRIVE_IDS_QUERY = TracksColumns.DRIVEID + " IS NOT NULL AND "
|
||||
+ TracksColumns.DRIVEID + "!=''";
|
||||
|
||||
@VisibleForTesting
|
||||
static final String DATABASE_NAME = "mytracks.db";
|
||||
private static final int DATABASE_VERSION = 20;
|
||||
|
||||
/**
|
||||
* Database helper for creating and upgrading the database.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static class DatabaseHelper extends SQLiteOpenHelper {
|
||||
|
||||
|
||||
public DatabaseHelper(Context context) {
|
||||
this(context, DATABASE_NAME);
|
||||
}
|
||||
|
||||
|
||||
@VisibleForTesting
|
||||
public DatabaseHelper(Context context, String databaseName) {
|
||||
super(context, databaseName, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(TrackPointsColumns.CREATE_TABLE);
|
||||
db.execSQL(TracksColumns.CREATE_TABLE);
|
||||
db.execSQL(WaypointsColumns.CREATE_TABLE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion);
|
||||
@@ -83,25 +88,40 @@ public class MyTracksProvider extends ContentProvider {
|
||||
onCreate(db);
|
||||
} else {
|
||||
// Incremental upgrades. One if statement per DB version.
|
||||
|
||||
|
||||
// Add track points SENSOR column
|
||||
if (oldVersion <= 17) {
|
||||
Log.w(TAG, "Upgrade DB: Adding sensor column.");
|
||||
db.execSQL("ALTER TABLE " + TrackPointsColumns.TABLE_NAME + " ADD "
|
||||
+ TrackPointsColumns.SENSOR + " BLOB");
|
||||
}
|
||||
|
||||
// Add tracks TABLEID column
|
||||
if (oldVersion <= 18) {
|
||||
Log.w(TAG, "Upgrade DB: Adding tableid column.");
|
||||
db.execSQL("ALTER TABLE " + TracksColumns.TABLE_NAME + " ADD " + TracksColumns.TABLEID
|
||||
+ " STRING");
|
||||
}
|
||||
|
||||
// Add tracks ICON column
|
||||
if (oldVersion <= 19) {
|
||||
Log.w(TAG, "Upgrade DB: Adding icon column.");
|
||||
db.execSQL(
|
||||
"ALTER TABLE " + TracksColumns.TABLE_NAME + " ADD " + TracksColumns.ICON + " STRING");
|
||||
}
|
||||
|
||||
// Add track DRIVEID, MODIFIEDTIME, and SHAREDWITHME columns
|
||||
if (oldVersion <= 20) {
|
||||
Log.w(TAG, "Upgrade DB: Adding driveid column.");
|
||||
db.execSQL("ALTER TABLE " + TracksColumns.TABLE_NAME + " ADD " + TracksColumns.DRIVEID
|
||||
+ " STRING");
|
||||
Log.w(TAG, "Upgrade DB: Adding modifiedtime column.");
|
||||
db.execSQL("ALTER TABLE " + TracksColumns.TABLE_NAME + " ADD "
|
||||
+ TracksColumns.MODIFIEDTIME + " INTEGER");
|
||||
Log.w(TAG, "Upgrade DB: Adding sharedwithme column.");
|
||||
db.execSQL("ALTER TABLE " + TracksColumns.TABLE_NAME + " ADD "
|
||||
+ TracksColumns.SHAREDWITHME + " INTEGER");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,9 +159,10 @@ public class MyTracksProvider extends ContentProvider {
|
||||
public boolean onCreate() {
|
||||
return onCreate(getContext());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to make onCreate is testable.
|
||||
*
|
||||
* @param context context to creates database
|
||||
* @return true means run successfully
|
||||
*/
|
||||
@@ -180,7 +201,18 @@ public class MyTracksProvider extends ContentProvider {
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
|
||||
|
||||
boolean driveSync = false;
|
||||
String driveIds = "";
|
||||
if (table.equals(TracksColumns.TABLE_NAME)) {
|
||||
driveSync = PreferencesUtils.getBoolean(
|
||||
getContext(), R.string.drive_sync_key, PreferencesUtils.DRIVE_SYNC_DEFAULT);
|
||||
if (driveSync) {
|
||||
driveIds = where != null ? getDriveIds(null, where, selectionArgs)
|
||||
: getDriveIds(new String[] { TracksColumns.DRIVEID }, DRIVE_IDS_QUERY, null);
|
||||
}
|
||||
}
|
||||
|
||||
Log.w(MyTracksProvider.TAG, "Deleting table " + table);
|
||||
int count;
|
||||
try {
|
||||
@@ -190,8 +222,20 @@ public class MyTracksProvider extends ContentProvider {
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
if (driveSync && table.equals(TracksColumns.TABLE_NAME)) {
|
||||
String driveDeletedList = PreferencesUtils.getString(getContext(),
|
||||
R.string.drive_deleted_list_key, PreferencesUtils.DRIVE_DELETED_LIST_DEFAULT);
|
||||
if (driveDeletedList.equals(PreferencesUtils.DRIVE_DELETED_LIST_DEFAULT)) {
|
||||
driveDeletedList = driveIds;
|
||||
} else {
|
||||
driveDeletedList += ";" + driveIds;
|
||||
}
|
||||
PreferencesUtils.setString(getContext(), R.string.drive_deleted_list_key, driveDeletedList);
|
||||
}
|
||||
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
|
||||
|
||||
if (shouldVacuum) {
|
||||
// If a potentially large amount of data was deleted, reclaim its space.
|
||||
Log.i(TAG, "Vacuuming the database.");
|
||||
@@ -251,7 +295,7 @@ public class MyTracksProvider extends ContentProvider {
|
||||
try {
|
||||
// Use a transaction in order to make the insertions run as a single batch
|
||||
db.beginTransaction();
|
||||
|
||||
|
||||
UrlType urlType = getUrlType(url);
|
||||
for (numInserted = 0; numInserted < valuesBulk.length; numInserted++) {
|
||||
ContentValues contentValues = valuesBulk[numInserted];
|
||||
@@ -464,4 +508,29 @@ public class MyTracksProvider extends ContentProvider {
|
||||
}
|
||||
throw new SQLException("Failed to insert a waypoint " + url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of dirve ids.
|
||||
*
|
||||
* @param projection the projection
|
||||
* @param where where
|
||||
* @param selectionArgs selection args
|
||||
*/
|
||||
private String getDriveIds(String[] projection, String where, String[] selectionArgs) {
|
||||
ArrayList<String> driveIds = new ArrayList<String>();
|
||||
Cursor cursor = query(TracksColumns.CONTENT_URI, projection, where, selectionArgs, null);
|
||||
if (cursor != null) {
|
||||
int index = cursor.getColumnIndex(TracksColumns.DRIVEID);
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
String driveId = cursor.getString(index);
|
||||
if (driveId != null && !driveId.equals("")) {
|
||||
driveIds.add(driveId);
|
||||
}
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
return TextUtils.join(";", driveIds);
|
||||
}
|
||||
}
|
||||
+15
@@ -85,6 +85,9 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
int mapIdIndex = cursor.getColumnIndexOrThrow(TracksColumns.MAPID);
|
||||
int tableIdIndex = cursor.getColumnIndexOrThrow(TracksColumns.TABLEID);
|
||||
int iconIndex = cursor.getColumnIndexOrThrow(TracksColumns.ICON);
|
||||
int driveIdIndex = cursor.getColumnIndexOrThrow(TracksColumns.DRIVEID);
|
||||
int modifiedTimeIndex = cursor.getColumnIndexOrThrow(TracksColumns.MODIFIEDTIME);
|
||||
int sharedWithMeIndex = cursor.getColumnIndexOrThrow(TracksColumns.SHAREDWITHME);
|
||||
|
||||
Track track = new Track();
|
||||
TripStatistics tripStatistics = track.getTripStatistics();
|
||||
@@ -159,6 +162,15 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
if (!cursor.isNull(iconIndex)) {
|
||||
track.setIcon(cursor.getString(iconIndex));
|
||||
}
|
||||
if (!cursor.isNull(driveIdIndex)) {
|
||||
track.setDriveId(cursor.getString(driveIdIndex));
|
||||
}
|
||||
if (!cursor.isNull(modifiedTimeIndex)) {
|
||||
track.setModifiedTime(cursor.getLong(modifiedTimeIndex));
|
||||
}
|
||||
if (!cursor.isNull(sharedWithMeIndex)) {
|
||||
track.setSharedWithMe(cursor.getInt(sharedWithMeIndex) == 1);
|
||||
}
|
||||
return track;
|
||||
}
|
||||
|
||||
@@ -302,6 +314,9 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
values.put(TracksColumns.MAPID, track.getMapId());
|
||||
values.put(TracksColumns.TABLEID, track.getTableId());
|
||||
values.put(TracksColumns.ICON, track.getIcon());
|
||||
values.put(TracksColumns.DRIVEID, track.getDriveId());
|
||||
values.put(TracksColumns.MODIFIEDTIME, track.getModifiedTime());
|
||||
values.put(TracksColumns.SHAREDWITHME, track.isSharedWithMe());
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,19 +32,24 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public class Track implements Parcelable {
|
||||
|
||||
private long id = -1;
|
||||
private long id = -1L;
|
||||
private String name = "";
|
||||
private String description = "";
|
||||
private String category = "";
|
||||
private long startId = -1;
|
||||
private long stopId = -1;
|
||||
private long startId = -1L;
|
||||
private long stopId = -1L;
|
||||
|
||||
// The number of location points (present even if the points themselves are
|
||||
// not loaded)
|
||||
/*
|
||||
* The number of location points (present even if the points themselves are
|
||||
* not loaded)
|
||||
*/
|
||||
private int numberOfPoints = 0;
|
||||
private String mapId = "";
|
||||
private String tableId = "";
|
||||
private String icon = "";
|
||||
private String driveId = "";
|
||||
private long modifiedTime = -1L;
|
||||
private boolean sharedWithMe = false;
|
||||
|
||||
private TripStatistics tripStatistics = new TripStatistics();
|
||||
|
||||
@@ -64,13 +69,16 @@ public class Track implements Parcelable {
|
||||
mapId = in.readString();
|
||||
tableId = in.readString();
|
||||
icon = in.readString();
|
||||
driveId = in.readString();
|
||||
modifiedTime = in.readLong();
|
||||
sharedWithMe = in.readByte() == 1;
|
||||
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
tripStatistics = in.readParcelable(classLoader);
|
||||
|
||||
for (int i = 0; i < numberOfPoints; ++i) {
|
||||
Location loc = in.readParcelable(classLoader);
|
||||
locations.add(loc);
|
||||
Location location = in.readParcelable(classLoader);
|
||||
locations.add(location);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +99,10 @@ public class Track implements Parcelable {
|
||||
dest.writeString(mapId);
|
||||
dest.writeString(tableId);
|
||||
dest.writeString(icon);
|
||||
dest.writeString(driveId);
|
||||
dest.writeLong(modifiedTime);
|
||||
dest.writeByte((byte) (sharedWithMe ? 1 : 0));
|
||||
|
||||
dest.writeParcelable(tripStatistics, 0);
|
||||
for (int i = 0; i < numberOfPoints; ++i) {
|
||||
dest.writeParcelable(locations.get(i), 0);
|
||||
@@ -189,6 +201,30 @@ public class Track implements Parcelable {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public String getDriveId() {
|
||||
return driveId;
|
||||
}
|
||||
|
||||
public void setDriveId(String driveId) {
|
||||
this.driveId = driveId;
|
||||
}
|
||||
|
||||
public long getModifiedTime() {
|
||||
return modifiedTime;
|
||||
}
|
||||
|
||||
public void setModifiedTime(long modifiedTime) {
|
||||
this.modifiedTime = modifiedTime;
|
||||
}
|
||||
|
||||
public boolean isSharedWithMe() {
|
||||
return sharedWithMe;
|
||||
}
|
||||
|
||||
public void setSharedWithMe(boolean sharedWithMe) {
|
||||
this.sharedWithMe = sharedWithMe;
|
||||
}
|
||||
|
||||
public TripStatistics getTripStatistics() {
|
||||
return tripStatistics;
|
||||
}
|
||||
@@ -197,8 +233,8 @@ public class Track implements Parcelable {
|
||||
this.tripStatistics = tripStatistics;
|
||||
}
|
||||
|
||||
public void addLocation(Location l) {
|
||||
locations.add(l);
|
||||
public void addLocation(Location location) {
|
||||
locations.add(location);
|
||||
}
|
||||
|
||||
public ArrayList<Location> getLocations() {
|
||||
|
||||
@@ -66,7 +66,9 @@ public interface TracksColumns extends BaseColumns {
|
||||
public static final String MINLON = "minlon"; // minimum longitude
|
||||
public static final String MAXLON = "maxlon"; // maximum longitude
|
||||
public static final String AVGSPEED = "avgspeed"; // average speed
|
||||
public static final String AVGMOVINGSPEED = "avgmovingspeed"; // average moving speed
|
||||
|
||||
// average moving speed
|
||||
public static final String AVGMOVINGSPEED = "avgmovingspeed";
|
||||
public static final String MAXSPEED = "maxspeed"; // maximum speed
|
||||
public static final String MINELEVATION = "minelevation"; // minimum elevation
|
||||
public static final String MAXELEVATION = "maxelevation"; // maximum elevation
|
||||
@@ -76,69 +78,78 @@ public interface TracksColumns extends BaseColumns {
|
||||
public static final String MAPID = "mapid"; // Google Maps id
|
||||
public static final String TABLEID = "tableid"; // Google Fusion Tables id
|
||||
public static final String ICON = "icon"; // track activity type icon
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " ("
|
||||
+ _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ NAME + " STRING, "
|
||||
+ DESCRIPTION + " STRING, "
|
||||
+ CATEGORY + " STRING, "
|
||||
+ STARTID + " INTEGER, "
|
||||
+ STOPID + " INTEGER, "
|
||||
+ STARTTIME + " INTEGER, "
|
||||
+ STOPTIME + " INTEGER, "
|
||||
+ NUMPOINTS + " INTEGER, "
|
||||
+ TOTALDISTANCE + " FLOAT, "
|
||||
+ TOTALTIME + " INTEGER, "
|
||||
+ MOVINGTIME + " INTEGER, "
|
||||
+ MINLAT + " INTEGER, "
|
||||
+ MAXLAT + " INTEGER, "
|
||||
+ MINLON + " INTEGER, "
|
||||
+ MAXLON + " INTEGER, "
|
||||
+ AVGSPEED + " FLOAT, "
|
||||
+ AVGMOVINGSPEED + " FLOAT, "
|
||||
+ MAXSPEED + " FLOAT, "
|
||||
+ MINELEVATION + " FLOAT, "
|
||||
+ MAXELEVATION + " FLOAT, "
|
||||
+ ELEVATIONGAIN + " FLOAT, "
|
||||
+ MINGRADE + " FLOAT, "
|
||||
+ MAXGRADE + " FLOAT, "
|
||||
+ MAPID + " STRING, "
|
||||
+ TABLEID + " STRING, "
|
||||
+ ICON + " STRING"
|
||||
+ ");";
|
||||
public static final String DRIVEID = "driveid"; // Google Drive file id
|
||||
|
||||
public static final String[] COLUMNS = {
|
||||
_ID,
|
||||
NAME,
|
||||
DESCRIPTION,
|
||||
CATEGORY,
|
||||
STARTID,
|
||||
STOPID,
|
||||
STARTTIME,
|
||||
STOPTIME,
|
||||
NUMPOINTS,
|
||||
TOTALDISTANCE,
|
||||
TOTALTIME,
|
||||
MOVINGTIME,
|
||||
MINLAT,
|
||||
MAXLAT,
|
||||
MINLON,
|
||||
MAXLON,
|
||||
AVGSPEED,
|
||||
AVGMOVINGSPEED,
|
||||
MAXSPEED,
|
||||
MINELEVATION,
|
||||
MAXELEVATION,
|
||||
ELEVATIONGAIN,
|
||||
MINGRADE,
|
||||
MAXGRADE,
|
||||
MAPID,
|
||||
TABLEID,
|
||||
ICON
|
||||
};
|
||||
// Google drive file modified time
|
||||
public static final String MODIFIEDTIME = "modifiedtime";
|
||||
|
||||
public static final byte[] COLUMN_TYPES = {
|
||||
ContentTypeIds.LONG_TYPE_ID, // id
|
||||
// 1 if the Google Drive file is from the "Shared with me" directory
|
||||
public static final String SHAREDWITHME = "sharedwithme";
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" // table
|
||||
+ _ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " // id
|
||||
+ NAME + " STRING, " // name
|
||||
+ DESCRIPTION + " STRING, " // description
|
||||
+ CATEGORY + " STRING, " // category
|
||||
+ STARTID + " INTEGER, " // start id
|
||||
+ STOPID + " INTEGER, " // stop id
|
||||
+ STARTTIME + " INTEGER, " // start time
|
||||
+ STOPTIME + " INTEGER, " // stop time
|
||||
+ NUMPOINTS + " INTEGER, " // num points
|
||||
+ TOTALDISTANCE + " FLOAT, " // total distance
|
||||
+ TOTALTIME + " INTEGER, " // total time
|
||||
+ MOVINGTIME + " INTEGER, " // moving time
|
||||
+ MINLAT + " INTEGER, " // min latitude
|
||||
+ MAXLAT + " INTEGER, " // max latitude
|
||||
+ MINLON + " INTEGER, " // min longitude
|
||||
+ MAXLON + " INTEGER, " // max longitude
|
||||
+ AVGSPEED + " FLOAT, " // average speed
|
||||
+ AVGMOVINGSPEED + " FLOAT, " // average moving speed
|
||||
+ MAXSPEED + " FLOAT, " // max speed
|
||||
+ MINELEVATION + " FLOAT, " // min elevation
|
||||
+ MAXELEVATION + " FLOAT, " // max elevation
|
||||
+ ELEVATIONGAIN + " FLOAT, " // elevation gain
|
||||
+ MINGRADE + " FLOAT, " // min grade
|
||||
+ MAXGRADE + " FLOAT, " // max grade
|
||||
+ MAPID + " STRING, " // map id
|
||||
+ TABLEID + " STRING, " // table id
|
||||
+ ICON + " STRING, " // icon
|
||||
+ DRIVEID + " STRING, " // drive id
|
||||
+ MODIFIEDTIME + " INTEGER, " // modified time
|
||||
+ SHAREDWITHME + " INTEGER" + ");"; // shared with me
|
||||
|
||||
public static final String[] COLUMNS = { _ID, // id
|
||||
NAME, // name
|
||||
DESCRIPTION, // description
|
||||
CATEGORY, // category
|
||||
STARTID, // start id
|
||||
STOPID, // stop id
|
||||
STARTTIME, // start time
|
||||
STOPTIME, // stop time
|
||||
NUMPOINTS, // num points
|
||||
TOTALDISTANCE, // total distance
|
||||
TOTALTIME, // total time
|
||||
MOVINGTIME, // moving time
|
||||
MINLAT, // min latitude
|
||||
MAXLAT, // max latitude
|
||||
MINLON, // min longitude
|
||||
MAXLON, // max longitude
|
||||
AVGSPEED, // average speed
|
||||
AVGMOVINGSPEED, // average moving speed
|
||||
MAXSPEED, // max speed
|
||||
MINELEVATION, // min elevation
|
||||
MAXELEVATION, // max elevation
|
||||
ELEVATIONGAIN, // elevation gain
|
||||
MINGRADE, // min grade
|
||||
MAXGRADE, // max grade
|
||||
MAPID, // map id
|
||||
TABLEID, // table id
|
||||
ICON, // icon
|
||||
DRIVEID, // drive id
|
||||
MODIFIEDTIME, // modified time
|
||||
SHAREDWITHME }; // shared with me
|
||||
|
||||
public static final byte[] COLUMN_TYPES = { ContentTypeIds.LONG_TYPE_ID, // id
|
||||
ContentTypeIds.STRING_TYPE_ID, // name
|
||||
ContentTypeIds.STRING_TYPE_ID, // description
|
||||
ContentTypeIds.STRING_TYPE_ID, // category
|
||||
@@ -164,6 +175,9 @@ public interface TracksColumns extends BaseColumns {
|
||||
ContentTypeIds.FLOAT_TYPE_ID, // max grade
|
||||
ContentTypeIds.STRING_TYPE_ID, // map id
|
||||
ContentTypeIds.STRING_TYPE_ID, // table id
|
||||
ContentTypeIds.STRING_TYPE_ID // icon
|
||||
};
|
||||
ContentTypeIds.STRING_TYPE_ID, // icon
|
||||
ContentTypeIds.STRING_TYPE_ID, // drive id
|
||||
ContentTypeIds.LONG_TYPE_ID, // modified time
|
||||
ContentTypeIds.BOOLEAN_TYPE_ID // shared with me
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user