forked from upstream-mirrors/OpenTracks
Protect MyTracksProvider based on the MyTracks settings bit.
Move MyTracksProvider to DatabaseProvider and protect the DatabaseProvider using the AndroidManifest.xml. Create a MyTracksProviderUtilFactory to create an instance of MyTracksProviderUtils that accesses the DatabaseProvider. Recreate MyTracksProvider by extending DatabaseProvider. The recreated provider checks access, changes the authority, and invokes the DatabaseProvider methods.
This commit is contained in:
@@ -34,6 +34,12 @@ limitations under the License.
|
||||
android:readPermission="com.google.android.apps.mytracks.READ_TRACK_DATA"
|
||||
android:writePermission="com.google.android.apps.mytracks.WRITE_TRACK_DATA" />
|
||||
|
||||
<provider android:name="com.google.android.apps.mytracks.content.DatabaseProvider"
|
||||
android:authorities="com.google.android.apps.mytracks.content"
|
||||
android:exported="false"
|
||||
android:readPermission="com.google.android.apps.mytracks.READ_TRACK_DATA"
|
||||
android:writePermission="com.google.android.apps.mytracks.WRITE_TRACK_DATA" />
|
||||
|
||||
<activity android:name="com.google.android.apps.mytracks.MyTracks"
|
||||
android:label="My Tracks"
|
||||
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
@@ -57,7 +58,7 @@ public class AggregatedStatsActivity extends Activity implements
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
this.tracksProvider = MyTracksProviderUtils.Factory.get(this);
|
||||
this.tracksProvider = MyTracksProviderUtilsFactory.get(this);
|
||||
|
||||
// We don't need a window title bar:
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.util.ApiFeatures;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
@@ -59,7 +59,7 @@ public class DeleteAllTracks extends Handler {
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
dialogInterface.dismiss();
|
||||
Log.w(Constants.TAG, "deleting all!");
|
||||
MyTracksProviderUtils.Factory.get(context).deleteAllTracks();
|
||||
MyTracksProviderUtilsFactory.get(context).deleteAllTracks();
|
||||
SharedPreferences prefs =
|
||||
context.getSharedPreferences(Constants.SETTINGS_NAME, 0);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.google.android.apps.mytracks;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.util.ApiFeatures;
|
||||
import com.google.android.apps.mytracks.util.UriUtils;
|
||||
@@ -53,13 +54,13 @@ public class DeleteTrack extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(this);
|
||||
providerUtils = MyTracksProviderUtilsFactory.get(this);
|
||||
|
||||
Intent intent = getIntent();
|
||||
String action = intent.getAction();
|
||||
Uri data = intent.getData();
|
||||
if (!Intent.ACTION_DELETE.equals(action) ||
|
||||
!UriUtils.matchesContentUri(data, TracksColumns.CONTENT_URI)) {
|
||||
if (!Intent.ACTION_DELETE.equals(action)
|
||||
|| !UriUtils.matchesContentUri(data, TracksColumns.DATABASE_CONTENT_URI)) {
|
||||
Log.e(TAG, "Got bad delete intent: " + intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.io.file.TrackWriter;
|
||||
@@ -148,8 +149,7 @@ public class ExportAllTracks {
|
||||
// Get a cursor over all tracks.
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
MyTracksProviderUtils providerUtils =
|
||||
MyTracksProviderUtils.Factory.get(activity);
|
||||
MyTracksProviderUtils providerUtils = MyTracksProviderUtilsFactory.get(activity);
|
||||
cursor = providerUtils.getTracksCursor("");
|
||||
if (cursor == null) {
|
||||
return;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.io.file.GpxImporter;
|
||||
import com.google.android.apps.mytracks.util.FileUtils;
|
||||
@@ -132,7 +133,7 @@ public class ImportAllTracks {
|
||||
* been acquired.
|
||||
*/
|
||||
private void importAll() {
|
||||
MyTracksProviderUtils providerUtils = MyTracksProviderUtils.Factory.get(activity);
|
||||
MyTracksProviderUtils providerUtils = MyTracksProviderUtilsFactory.get(activity);
|
||||
|
||||
if (!fileUtils.isSdCardAvailable()) {
|
||||
return;
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.google.android.apps.mytracks;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TrackDataHub;
|
||||
import com.google.android.apps.mytracks.content.TrackDataHub.ListenerDataType;
|
||||
@@ -317,7 +318,7 @@ public class MapActivity extends com.google.android.maps.MapActivity
|
||||
* Zooms and pans the map so that the given waypoint is visible.
|
||||
*/
|
||||
public void showWaypoint(long waypointId) {
|
||||
MyTracksProviderUtils providerUtils = MyTracksProviderUtils.Factory.get(this);
|
||||
MyTracksProviderUtils providerUtils = MyTracksProviderUtilsFactory.get(this);
|
||||
Waypoint wpt = providerUtils.getWaypoint(waypointId);
|
||||
if (wpt != null && wpt.getLocation() != null) {
|
||||
keepMyLocationVisible = false;
|
||||
@@ -424,7 +425,7 @@ public class MapActivity extends com.google.android.maps.MapActivity
|
||||
}
|
||||
case Constants.MENU_DELETE: {
|
||||
Uri uri = ContentUris.withAppendedId(
|
||||
TracksColumns.CONTENT_URI, dataHub.getSelectedTrackId());
|
||||
TracksColumns.DATABASE_CONTENT_URI, dataHub.getSelectedTrackId());
|
||||
Intent intent = new Intent(Intent.ACTION_DELETE, uri);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
|
||||
@@ -19,6 +19,7 @@ import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.analytics.GoogleAnalyticsTracker;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.TrackDataHub;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
@@ -144,7 +145,7 @@ public class MyTracks extends TabActivity implements OnTouchListener {
|
||||
tracker.trackPageView("/appstart");
|
||||
tracker.dispatch();
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(this);
|
||||
providerUtils = MyTracksProviderUtilsFactory.get(this);
|
||||
preferences = getSharedPreferences(Constants.SETTINGS_NAME, 0);
|
||||
dataHub = ((MyTracksApplication) getApplication()).getTrackDataHub();
|
||||
menuManager = new MenuManager(this);
|
||||
@@ -208,7 +209,7 @@ public class MyTracks extends TabActivity implements OnTouchListener {
|
||||
Uri data = intent.getData();
|
||||
if ((Intent.ACTION_VIEW.equals(action) || Intent.ACTION_EDIT.equals(action))
|
||||
&& TracksColumns.CONTENT_ITEMTYPE.equals(intent.getType())
|
||||
&& UriUtils.matchesContentUri(data, TracksColumns.CONTENT_URI)) {
|
||||
&& UriUtils.matchesContentUri(data, TracksColumns.DATABASE_CONTENT_URI)) {
|
||||
long trackId = ContentUris.parseId(data);
|
||||
dataHub.loadTrack(trackId);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
@@ -89,7 +89,7 @@ public class TrackDetails extends Activity implements OnClickListener {
|
||||
}
|
||||
|
||||
private void fillDialog() {
|
||||
Track track = MyTracksProviderUtils.Factory.get(this).getTrack(trackId);
|
||||
Track track = MyTracksProviderUtilsFactory.get(this).getTrack(trackId);
|
||||
if (track != null) {
|
||||
name.setText(track.getName());
|
||||
description.setText(track.getDescription());
|
||||
@@ -103,7 +103,7 @@ public class TrackDetails extends Activity implements OnClickListener {
|
||||
values.put(TracksColumns.DESCRIPTION, description.getText().toString());
|
||||
values.put(TracksColumns.CATEGORY, category.getText().toString());
|
||||
getContentResolver().update(
|
||||
TracksColumns.CONTENT_URI,
|
||||
TracksColumns.DATABASE_CONTENT_URI,
|
||||
values,
|
||||
"_id = " + trackId,
|
||||
null/*selectionArgs*/);
|
||||
|
||||
@@ -189,7 +189,7 @@ public class TrackList extends ListActivity
|
||||
return true;
|
||||
case Constants.MENU_DELETE: {
|
||||
Intent intent = new Intent(Intent.ACTION_DELETE);
|
||||
Uri uri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, trackId);
|
||||
Uri uri = ContentUris.withAppendedId(TracksColumns.DATABASE_CONTENT_URI, trackId);
|
||||
intent.setDataAndType(uri, TracksColumns.CONTENT_ITEMTYPE);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
@@ -251,7 +251,7 @@ public class TrackList extends ListActivity
|
||||
preferences.getLong(getString(R.string.recording_track_key), -1);
|
||||
|
||||
tracksCursor = getContentResolver().query(
|
||||
TracksColumns.CONTENT_URI, null, null, null, "_id DESC");
|
||||
TracksColumns.DATABASE_CONTENT_URI, null, null, null, "_id DESC");
|
||||
startManagingCursor(tracksCursor);
|
||||
setListAdapter();
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.WaypointsColumns;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
@@ -119,7 +119,7 @@ public class WaypointDetails extends Activity
|
||||
}
|
||||
|
||||
private void fillDialog() {
|
||||
waypoint = MyTracksProviderUtils.Factory.get(this).getWaypoint(waypointId);
|
||||
waypoint = MyTracksProviderUtilsFactory.get(this).getWaypoint(waypointId);
|
||||
if (waypoint != null) {
|
||||
name.setText(waypoint.getName());
|
||||
ImageView icon = (ImageView) findViewById(R.id.waypointdetails_icon);
|
||||
@@ -156,7 +156,7 @@ public class WaypointDetails extends Activity
|
||||
values.put(WaypointsColumns.CATEGORY, category.getText().toString());
|
||||
}
|
||||
getContentResolver().update(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
WaypointsColumns.DATABASE_CONTENT_URI,
|
||||
values,
|
||||
"_id = " + waypointId,
|
||||
null /*selectionArgs*/);
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.google.android.apps.mytracks;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
import com.google.android.apps.mytracks.content.WaypointsColumns;
|
||||
@@ -134,7 +135,7 @@ public class WaypointsList extends ListActivity
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(this);
|
||||
providerUtils = MyTracksProviderUtilsFactory.get(this);
|
||||
serviceConnection = new TrackRecordingServiceConnection(this, null);
|
||||
|
||||
// We don't need a window title bar:
|
||||
@@ -174,10 +175,10 @@ public class WaypointsList extends ListActivity
|
||||
}
|
||||
|
||||
final long firstWaypointId = providerUtils.getFirstWaypointId(trackId);
|
||||
String selection = WaypointsColumns.TRACKID + "=" + trackId + " AND " + WaypointsColumns._ID
|
||||
+ "!=" + firstWaypointId;
|
||||
waypointsCursor = getContentResolver().query(
|
||||
WaypointsColumns.CONTENT_URI, null,
|
||||
WaypointsColumns.TRACKID + "=" + trackId + " AND "
|
||||
+ WaypointsColumns._ID + "!=" + firstWaypointId, null, null);
|
||||
WaypointsColumns.DATABASE_CONTENT_URI, null, selection, null, null);
|
||||
startManagingCursor(waypointsCursor);
|
||||
setListAdapter();
|
||||
}
|
||||
|
||||
@@ -211,14 +211,15 @@ class DataSourceManager {
|
||||
break;
|
||||
case POINT_UPDATES:
|
||||
dataSources.registerContentObserver(
|
||||
TrackPointsColumns.CONTENT_URI, false, pointObserver);
|
||||
TrackPointsColumns.DATABASE_CONTENT_URI, false, pointObserver);
|
||||
break;
|
||||
case TRACK_UPDATES:
|
||||
dataSources.registerContentObserver(TracksColumns.CONTENT_URI, false, trackObserver);
|
||||
dataSources.registerContentObserver(
|
||||
TracksColumns.DATABASE_CONTENT_URI, false, trackObserver);
|
||||
break;
|
||||
case WAYPOINT_UPDATES:
|
||||
dataSources.registerContentObserver(
|
||||
WaypointsColumns.CONTENT_URI, false, waypointObserver);
|
||||
WaypointsColumns.DATABASE_CONTENT_URI, false, waypointObserver);
|
||||
break;
|
||||
case DISPLAY_PREFERENCES:
|
||||
dataSources.registerOnSharedPreferenceChangeListener(preferenceListener);
|
||||
|
||||
@@ -0,0 +1,434 @@
|
||||
/*
|
||||
* Copyright 2008 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.content;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.util.ApiFeatures;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.UriMatcher;
|
||||
import android.database.Cursor;
|
||||
import android.database.SQLException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.database.sqlite.SQLiteQueryBuilder;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A provider that handles recorded (GPS) tracks and their track points.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class DatabaseProvider extends ContentProvider {
|
||||
|
||||
private static final String DATABASE_NAME = "mytracks.db";
|
||||
private static final int DATABASE_VERSION = 19;
|
||||
private static final int TRACKPOINTS = 1;
|
||||
private static final int TRACKPOINTS_ID = 2;
|
||||
private static final int TRACKS = 3;
|
||||
private static final int TRACKS_ID = 4;
|
||||
private static final int WAYPOINTS = 5;
|
||||
private static final int WAYPOINTS_ID = 6;
|
||||
private static final String TRACKPOINTS_TABLE = "trackpoints";
|
||||
private static final String TRACKS_TABLE = "tracks";
|
||||
private static final String WAYPOINTS_TABLE = "waypoints";
|
||||
public static final String TAG = DatabaseProvider.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Helper which creates or upgrades the database if necessary.
|
||||
*/
|
||||
private static class DatabaseHelper extends SQLiteOpenHelper {
|
||||
|
||||
public DatabaseHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL("CREATE TABLE " + TRACKPOINTS_TABLE + " ("
|
||||
+ TrackPointsColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ TrackPointsColumns.TRACKID + " INTEGER, "
|
||||
+ TrackPointsColumns.LONGITUDE + " INTEGER, "
|
||||
+ TrackPointsColumns.LATITUDE + " INTEGER, "
|
||||
+ TrackPointsColumns.TIME + " INTEGER, "
|
||||
+ TrackPointsColumns.ALTITUDE + " FLOAT, "
|
||||
+ TrackPointsColumns.ACCURACY + " FLOAT, "
|
||||
+ TrackPointsColumns.SPEED + " FLOAT, "
|
||||
+ TrackPointsColumns.BEARING + " FLOAT, "
|
||||
+ TrackPointsColumns.SENSOR + " BLOB);");
|
||||
db.execSQL("CREATE TABLE " + TRACKS_TABLE + " ("
|
||||
+ TracksColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ TracksColumns.NAME + " STRING, "
|
||||
+ TracksColumns.DESCRIPTION + " STRING, "
|
||||
+ TracksColumns.CATEGORY + " STRING, "
|
||||
+ TracksColumns.STARTID + " INTEGER, "
|
||||
+ TracksColumns.STOPID + " INTEGER, "
|
||||
+ TracksColumns.STARTTIME + " INTEGER, "
|
||||
+ TracksColumns.STOPTIME + " INTEGER, "
|
||||
+ TracksColumns.NUMPOINTS + " INTEGER, "
|
||||
+ TracksColumns.TOTALDISTANCE + " FLOAT, "
|
||||
+ TracksColumns.TOTALTIME + " INTEGER, "
|
||||
+ TracksColumns.MOVINGTIME + " INTEGER, "
|
||||
+ TracksColumns.MINLAT + " INTEGER, "
|
||||
+ TracksColumns.MAXLAT + " INTEGER, "
|
||||
+ TracksColumns.MINLON + " INTEGER, "
|
||||
+ TracksColumns.MAXLON + " INTEGER, "
|
||||
+ TracksColumns.AVGSPEED + " FLOAT, "
|
||||
+ TracksColumns.AVGMOVINGSPEED + " FLOAT, "
|
||||
+ TracksColumns.MAXSPEED + " FLOAT, "
|
||||
+ TracksColumns.MINELEVATION + " FLOAT, "
|
||||
+ TracksColumns.MAXELEVATION + " FLOAT, "
|
||||
+ TracksColumns.ELEVATIONGAIN + " FLOAT, "
|
||||
+ TracksColumns.MINGRADE + " FLOAT, "
|
||||
+ TracksColumns.MAXGRADE + " FLOAT, "
|
||||
+ TracksColumns.MAPID + " STRING, "
|
||||
+ TracksColumns.TABLEID + " STRING);");
|
||||
db.execSQL("CREATE TABLE " + WAYPOINTS_TABLE + " ("
|
||||
+ WaypointsColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ WaypointsColumns.NAME + " STRING, "
|
||||
+ WaypointsColumns.DESCRIPTION + " STRING, "
|
||||
+ WaypointsColumns.CATEGORY + " STRING, "
|
||||
+ WaypointsColumns.ICON + " STRING, "
|
||||
+ WaypointsColumns.TRACKID + " INTEGER, "
|
||||
+ WaypointsColumns.TYPE + " INTEGER, "
|
||||
+ WaypointsColumns.LENGTH + " FLOAT, "
|
||||
+ WaypointsColumns.DURATION + " INTEGER, "
|
||||
+ WaypointsColumns.STARTTIME + " INTEGER, "
|
||||
+ WaypointsColumns.STARTID + " INTEGER, "
|
||||
+ WaypointsColumns.STOPID + " INTEGER, "
|
||||
+ WaypointsColumns.LONGITUDE + " INTEGER, "
|
||||
+ WaypointsColumns.LATITUDE + " INTEGER, "
|
||||
+ WaypointsColumns.TIME + " INTEGER, "
|
||||
+ WaypointsColumns.ALTITUDE + " FLOAT, "
|
||||
+ WaypointsColumns.ACCURACY + " FLOAT, "
|
||||
+ WaypointsColumns.SPEED + " FLOAT, "
|
||||
+ WaypointsColumns.BEARING + " FLOAT, "
|
||||
+ WaypointsColumns.TOTALDISTANCE + " FLOAT, "
|
||||
+ WaypointsColumns.TOTALTIME + " INTEGER, "
|
||||
+ WaypointsColumns.MOVINGTIME + " INTEGER, "
|
||||
+ WaypointsColumns.AVGSPEED + " FLOAT, "
|
||||
+ WaypointsColumns.AVGMOVINGSPEED + " FLOAT, "
|
||||
+ WaypointsColumns.MAXSPEED + " FLOAT, "
|
||||
+ WaypointsColumns.MINELEVATION + " FLOAT, "
|
||||
+ WaypointsColumns.MAXELEVATION + " FLOAT, "
|
||||
+ WaypointsColumns.ELEVATIONGAIN + " FLOAT, "
|
||||
+ WaypointsColumns.MINGRADE + " FLOAT, "
|
||||
+ WaypointsColumns.MAXGRADE + " FLOAT);");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if (oldVersion < 17) {
|
||||
// Wipe the old data.
|
||||
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
|
||||
+ newVersion + ", which will destroy all old data");
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TRACKPOINTS_TABLE);
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TRACKS_TABLE);
|
||||
db.execSQL("DROP TABLE IF EXISTS " + WAYPOINTS_TABLE);
|
||||
onCreate(db);
|
||||
} else {
|
||||
// Incremental updates go here.
|
||||
// Each time you increase the DB version, add a corresponding if clause.
|
||||
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
|
||||
+ newVersion);
|
||||
|
||||
// Sensor data.
|
||||
if (oldVersion <= 17) {
|
||||
Log.w(TAG, "Upgrade DB: Adding sensor column.");
|
||||
db.execSQL("ALTER TABLE " + TRACKPOINTS_TABLE
|
||||
+ " ADD " + TrackPointsColumns.SENSOR + " BLOB");
|
||||
}
|
||||
if (oldVersion <= 18) {
|
||||
Log.w(TAG, "Upgrade DB: Adding tableid column.");
|
||||
db.execSQL("ALTER TABLE " + TRACKS_TABLE
|
||||
+ " ADD " + TracksColumns.TABLEID + " STRING");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final UriMatcher urlMatcher;
|
||||
|
||||
private SQLiteDatabase db;
|
||||
|
||||
public DatabaseProvider() {
|
||||
urlMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.DATABASE_AUTHORITY, "trackpoints", TRACKPOINTS);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.DATABASE_AUTHORITY, "trackpoints/#", TRACKPOINTS_ID);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.DATABASE_AUTHORITY, "tracks", TRACKS);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.DATABASE_AUTHORITY, "tracks/#", TRACKS_ID);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.DATABASE_AUTHORITY, "waypoints", WAYPOINTS);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.DATABASE_AUTHORITY, "waypoints/#", WAYPOINTS_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
DatabaseHelper dbHelper = new DatabaseHelper(getContext());
|
||||
try {
|
||||
db = dbHelper.getWritableDatabase();
|
||||
} catch (SQLiteException e) {
|
||||
Log.e(TAG, "Unable to open database for writing", e);
|
||||
}
|
||||
return db != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(Uri url, String where, String[] selectionArgs) {
|
||||
String table;
|
||||
boolean shouldVacuum = false;
|
||||
switch (urlMatcher.match(url)) {
|
||||
case TRACKPOINTS:
|
||||
table = TRACKPOINTS_TABLE;
|
||||
break;
|
||||
case TRACKS:
|
||||
table = TRACKS_TABLE;
|
||||
shouldVacuum = true;
|
||||
break;
|
||||
case WAYPOINTS:
|
||||
table = WAYPOINTS_TABLE;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
|
||||
Log.w(DatabaseProvider.TAG, "provider delete in " + table + "!");
|
||||
int count = db.delete(table, where, selectionArgs);
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
|
||||
if (shouldVacuum) {
|
||||
// If a potentially large amount of data was deleted, we want to reclaim its space.
|
||||
Log.i(TAG, "Vacuuming the database");
|
||||
db.execSQL("VACUUM");
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri url) {
|
||||
switch (urlMatcher.match(url)) {
|
||||
case TRACKPOINTS:
|
||||
return TrackPointsColumns.CONTENT_TYPE;
|
||||
case TRACKPOINTS_ID:
|
||||
return TrackPointsColumns.CONTENT_ITEMTYPE;
|
||||
case TRACKS:
|
||||
return TracksColumns.CONTENT_TYPE;
|
||||
case TRACKS_ID:
|
||||
return TracksColumns.CONTENT_ITEMTYPE;
|
||||
case WAYPOINTS:
|
||||
return WaypointsColumns.CONTENT_TYPE;
|
||||
case WAYPOINTS_ID:
|
||||
return WaypointsColumns.CONTENT_ITEMTYPE;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri url, ContentValues initialValues) {
|
||||
Log.d(DatabaseProvider.TAG, "MyTracksProvider.insert");
|
||||
ContentValues values;
|
||||
if (initialValues != null) {
|
||||
values = initialValues;
|
||||
} else {
|
||||
values = new ContentValues();
|
||||
}
|
||||
|
||||
int urlMatchType = urlMatcher.match(url);
|
||||
return insertType(url, urlMatchType, values);
|
||||
}
|
||||
|
||||
private Uri insertType(Uri url, int urlMatchType, ContentValues values) {
|
||||
switch (urlMatchType) {
|
||||
case TRACKPOINTS:
|
||||
return insertTrackPoint(url, values);
|
||||
case TRACKS:
|
||||
return insertTrack(url, values);
|
||||
case WAYPOINTS:
|
||||
return insertWaypoint(url, values);
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int bulkInsert(Uri url, ContentValues[] valuesBulk) {
|
||||
Log.d(DatabaseProvider.TAG, "MyTracksProvider.bulkInsert");
|
||||
int numInserted = 0;
|
||||
try {
|
||||
// Use a transaction in order to make the insertions run as a single batch
|
||||
db.beginTransaction();
|
||||
|
||||
int urlMatch = urlMatcher.match(url);
|
||||
for (numInserted = 0; numInserted < valuesBulk.length; numInserted++) {
|
||||
ContentValues values = valuesBulk[numInserted];
|
||||
if (values == null) { values = new ContentValues(); }
|
||||
|
||||
insertType(url, urlMatch, values);
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
return numInserted;
|
||||
}
|
||||
|
||||
private Uri insertTrackPoint(Uri url, ContentValues values) {
|
||||
boolean hasLat = values.containsKey(TrackPointsColumns.LATITUDE);
|
||||
boolean hasLong = values.containsKey(TrackPointsColumns.LONGITUDE);
|
||||
boolean hasTime = values.containsKey(TrackPointsColumns.TIME);
|
||||
if (!hasLat || !hasLong || !hasTime) {
|
||||
throw new IllegalArgumentException(
|
||||
"Latitude, longitude, and time values are required.");
|
||||
}
|
||||
long rowId = db.insert(TRACKPOINTS_TABLE, TrackPointsColumns._ID, values);
|
||||
if (rowId >= 0) {
|
||||
Uri uri = ContentUris
|
||||
.appendId(TrackPointsColumns.DATABASE_CONTENT_URI.buildUpon(), rowId).build();
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return uri;
|
||||
}
|
||||
throw new SQLiteException("Failed to insert row into " + url);
|
||||
}
|
||||
|
||||
private Uri insertTrack(Uri url, ContentValues values) {
|
||||
boolean hasStartTime = values.containsKey(TracksColumns.STARTTIME);
|
||||
boolean hasStartId = values.containsKey(TracksColumns.STARTID);
|
||||
if (!hasStartTime || !hasStartId) {
|
||||
throw new IllegalArgumentException(
|
||||
"Both start time and start id values are required.");
|
||||
}
|
||||
long rowId = db.insert(TRACKS_TABLE, TracksColumns._ID, values);
|
||||
if (rowId > 0) {
|
||||
Uri uri = ContentUris.appendId(TracksColumns.DATABASE_CONTENT_URI.buildUpon(), rowId).build();
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return uri;
|
||||
}
|
||||
throw new SQLException("Failed to insert row into " + url);
|
||||
}
|
||||
|
||||
private Uri insertWaypoint(Uri url, ContentValues values) {
|
||||
long rowId = db.insert(WAYPOINTS_TABLE, WaypointsColumns._ID, values);
|
||||
if (rowId > 0) {
|
||||
Uri uri = ContentUris
|
||||
.appendId(WaypointsColumns.DATABASE_CONTENT_URI.buildUpon(), rowId).build();
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return uri;
|
||||
}
|
||||
throw new SQLException("Failed to insert row into " + url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(
|
||||
Uri url, String[] projection, String selection, String[] selectionArgs,
|
||||
String sort) {
|
||||
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
|
||||
int match = urlMatcher.match(url);
|
||||
String sortOrder = null;
|
||||
if (match == TRACKPOINTS) {
|
||||
qb.setTables(TRACKPOINTS_TABLE);
|
||||
if (sort != null) {
|
||||
sortOrder = sort;
|
||||
} else {
|
||||
sortOrder = TrackPointsColumns.DEFAULT_SORT_ORDER;
|
||||
}
|
||||
} else if (match == TRACKPOINTS_ID) {
|
||||
qb.setTables(TRACKPOINTS_TABLE);
|
||||
qb.appendWhere("_id=" + url.getPathSegments().get(1));
|
||||
} else if (match == TRACKS) {
|
||||
qb.setTables(TRACKS_TABLE);
|
||||
if (sort != null) {
|
||||
sortOrder = sort;
|
||||
} else {
|
||||
sortOrder = TracksColumns.DEFAULT_SORT_ORDER;
|
||||
}
|
||||
} else if (match == TRACKS_ID) {
|
||||
qb.setTables(TRACKS_TABLE);
|
||||
qb.appendWhere("_id=" + url.getPathSegments().get(1));
|
||||
} else if (match == WAYPOINTS) {
|
||||
qb.setTables(WAYPOINTS_TABLE);
|
||||
if (sort != null) {
|
||||
sortOrder = sort;
|
||||
} else {
|
||||
sortOrder = WaypointsColumns.DEFAULT_SORT_ORDER;
|
||||
}
|
||||
} else if (match == WAYPOINTS_ID) {
|
||||
qb.setTables(WAYPOINTS_TABLE);
|
||||
qb.appendWhere("_id=" + url.getPathSegments().get(1));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
|
||||
if (ApiFeatures.getInstance().canReuseSQLiteQueryBuilder()) {
|
||||
Log.i(Constants.TAG,
|
||||
"Build query: " + qb.buildQuery(projection, selection, selectionArgs,
|
||||
null, null, sortOrder, null));
|
||||
}
|
||||
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null,
|
||||
sortOrder);
|
||||
c.setNotificationUri(getContext().getContentResolver(), url);
|
||||
return c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri url, ContentValues values, String where,
|
||||
String[] selectionArgs) {
|
||||
int count;
|
||||
int match = urlMatcher.match(url);
|
||||
if (match == TRACKPOINTS) {
|
||||
count = db.update(TRACKPOINTS_TABLE, values, where, selectionArgs);
|
||||
} else if (match == TRACKPOINTS_ID) {
|
||||
String segment = url.getPathSegments().get(1);
|
||||
count = db.update(TRACKPOINTS_TABLE, values, "_id=" + segment
|
||||
+ (!TextUtils.isEmpty(where)
|
||||
? " AND (" + where + ')'
|
||||
: ""),
|
||||
selectionArgs);
|
||||
} else if (match == TRACKS) {
|
||||
count = db.update(TRACKS_TABLE, values, where, selectionArgs);
|
||||
} else if (match == TRACKS_ID) {
|
||||
String segment = url.getPathSegments().get(1);
|
||||
count = db.update(TRACKS_TABLE, values, "_id=" + segment
|
||||
+ (!TextUtils.isEmpty(where)
|
||||
? " AND (" + where + ')'
|
||||
: ""),
|
||||
selectionArgs);
|
||||
} else if (match == WAYPOINTS) {
|
||||
count = db.update(WAYPOINTS_TABLE, values, where, selectionArgs);
|
||||
} else if (match == WAYPOINTS_ID) {
|
||||
String segment = url.getPathSegments().get(1);
|
||||
count = db.update(WAYPOINTS_TABLE, values, "_id=" + segment
|
||||
+ (!TextUtils.isEmpty(where)
|
||||
? " AND (" + where + ')'
|
||||
: ""),
|
||||
selectionArgs);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008 Google Inc.
|
||||
* Copyright 2011 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
|
||||
@@ -16,423 +16,101 @@
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.util.ApiFeatures;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.UriMatcher;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.database.SQLException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.database.sqlite.SQLiteQueryBuilder;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.os.Binder;
|
||||
import android.os.Process;
|
||||
|
||||
/**
|
||||
* A provider that handles recorded (GPS) tracks and their track points.
|
||||
* A content provider that accesses MyTracks tracks, track points, and
|
||||
* waypoints. After checking access, calls the corresponding methods in
|
||||
* {@link DatabaseProvider}.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public class MyTracksProvider extends ContentProvider {
|
||||
|
||||
private static final String DATABASE_NAME = "mytracks.db";
|
||||
private static final int DATABASE_VERSION = 19;
|
||||
private static final int TRACKPOINTS = 1;
|
||||
private static final int TRACKPOINTS_ID = 2;
|
||||
private static final int TRACKS = 3;
|
||||
private static final int TRACKS_ID = 4;
|
||||
private static final int WAYPOINTS = 5;
|
||||
private static final int WAYPOINTS_ID = 6;
|
||||
private static final String TRACKPOINTS_TABLE = "trackpoints";
|
||||
private static final String TRACKS_TABLE = "tracks";
|
||||
private static final String WAYPOINTS_TABLE = "waypoints";
|
||||
public static final String TAG = "MyTracksProvider";
|
||||
|
||||
/**
|
||||
* Helper which creates or upgrades the database if necessary.
|
||||
*/
|
||||
private static class DatabaseHelper extends SQLiteOpenHelper {
|
||||
|
||||
public DatabaseHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL("CREATE TABLE " + TRACKPOINTS_TABLE + " ("
|
||||
+ TrackPointsColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ TrackPointsColumns.TRACKID + " INTEGER, "
|
||||
+ TrackPointsColumns.LONGITUDE + " INTEGER, "
|
||||
+ TrackPointsColumns.LATITUDE + " INTEGER, "
|
||||
+ TrackPointsColumns.TIME + " INTEGER, "
|
||||
+ TrackPointsColumns.ALTITUDE + " FLOAT, "
|
||||
+ TrackPointsColumns.ACCURACY + " FLOAT, "
|
||||
+ TrackPointsColumns.SPEED + " FLOAT, "
|
||||
+ TrackPointsColumns.BEARING + " FLOAT, "
|
||||
+ TrackPointsColumns.SENSOR + " BLOB);");
|
||||
db.execSQL("CREATE TABLE " + TRACKS_TABLE + " ("
|
||||
+ TracksColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ TracksColumns.NAME + " STRING, "
|
||||
+ TracksColumns.DESCRIPTION + " STRING, "
|
||||
+ TracksColumns.CATEGORY + " STRING, "
|
||||
+ TracksColumns.STARTID + " INTEGER, "
|
||||
+ TracksColumns.STOPID + " INTEGER, "
|
||||
+ TracksColumns.STARTTIME + " INTEGER, "
|
||||
+ TracksColumns.STOPTIME + " INTEGER, "
|
||||
+ TracksColumns.NUMPOINTS + " INTEGER, "
|
||||
+ TracksColumns.TOTALDISTANCE + " FLOAT, "
|
||||
+ TracksColumns.TOTALTIME + " INTEGER, "
|
||||
+ TracksColumns.MOVINGTIME + " INTEGER, "
|
||||
+ TracksColumns.MINLAT + " INTEGER, "
|
||||
+ TracksColumns.MAXLAT + " INTEGER, "
|
||||
+ TracksColumns.MINLON + " INTEGER, "
|
||||
+ TracksColumns.MAXLON + " INTEGER, "
|
||||
+ TracksColumns.AVGSPEED + " FLOAT, "
|
||||
+ TracksColumns.AVGMOVINGSPEED + " FLOAT, "
|
||||
+ TracksColumns.MAXSPEED + " FLOAT, "
|
||||
+ TracksColumns.MINELEVATION + " FLOAT, "
|
||||
+ TracksColumns.MAXELEVATION + " FLOAT, "
|
||||
+ TracksColumns.ELEVATIONGAIN + " FLOAT, "
|
||||
+ TracksColumns.MINGRADE + " FLOAT, "
|
||||
+ TracksColumns.MAXGRADE + " FLOAT, "
|
||||
+ TracksColumns.MAPID + " STRING, "
|
||||
+ TracksColumns.TABLEID + " STRING);");
|
||||
db.execSQL("CREATE TABLE " + WAYPOINTS_TABLE + " ("
|
||||
+ WaypointsColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||
+ WaypointsColumns.NAME + " STRING, "
|
||||
+ WaypointsColumns.DESCRIPTION + " STRING, "
|
||||
+ WaypointsColumns.CATEGORY + " STRING, "
|
||||
+ WaypointsColumns.ICON + " STRING, "
|
||||
+ WaypointsColumns.TRACKID + " INTEGER, "
|
||||
+ WaypointsColumns.TYPE + " INTEGER, "
|
||||
+ WaypointsColumns.LENGTH + " FLOAT, "
|
||||
+ WaypointsColumns.DURATION + " INTEGER, "
|
||||
+ WaypointsColumns.STARTTIME + " INTEGER, "
|
||||
+ WaypointsColumns.STARTID + " INTEGER, "
|
||||
+ WaypointsColumns.STOPID + " INTEGER, "
|
||||
+ WaypointsColumns.LONGITUDE + " INTEGER, "
|
||||
+ WaypointsColumns.LATITUDE + " INTEGER, "
|
||||
+ WaypointsColumns.TIME + " INTEGER, "
|
||||
+ WaypointsColumns.ALTITUDE + " FLOAT, "
|
||||
+ WaypointsColumns.ACCURACY + " FLOAT, "
|
||||
+ WaypointsColumns.SPEED + " FLOAT, "
|
||||
+ WaypointsColumns.BEARING + " FLOAT, "
|
||||
+ WaypointsColumns.TOTALDISTANCE + " FLOAT, "
|
||||
+ WaypointsColumns.TOTALTIME + " INTEGER, "
|
||||
+ WaypointsColumns.MOVINGTIME + " INTEGER, "
|
||||
+ WaypointsColumns.AVGSPEED + " FLOAT, "
|
||||
+ WaypointsColumns.AVGMOVINGSPEED + " FLOAT, "
|
||||
+ WaypointsColumns.MAXSPEED + " FLOAT, "
|
||||
+ WaypointsColumns.MINELEVATION + " FLOAT, "
|
||||
+ WaypointsColumns.MAXELEVATION + " FLOAT, "
|
||||
+ WaypointsColumns.ELEVATIONGAIN + " FLOAT, "
|
||||
+ WaypointsColumns.MINGRADE + " FLOAT, "
|
||||
+ WaypointsColumns.MAXGRADE + " FLOAT);");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if (oldVersion < 17) {
|
||||
// Wipe the old data.
|
||||
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
|
||||
+ newVersion + ", which will destroy all old data");
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TRACKPOINTS_TABLE);
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TRACKS_TABLE);
|
||||
db.execSQL("DROP TABLE IF EXISTS " + WAYPOINTS_TABLE);
|
||||
onCreate(db);
|
||||
} else {
|
||||
// Incremental updates go here.
|
||||
// Each time you increase the DB version, add a corresponding if clause.
|
||||
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
|
||||
+ newVersion);
|
||||
|
||||
// Sensor data.
|
||||
if (oldVersion <= 17) {
|
||||
Log.w(TAG, "Upgrade DB: Adding sensor column.");
|
||||
db.execSQL("ALTER TABLE " + TRACKPOINTS_TABLE
|
||||
+ " ADD " + TrackPointsColumns.SENSOR + " BLOB");
|
||||
}
|
||||
if (oldVersion <= 18) {
|
||||
Log.w(TAG, "Upgrade DB: Adding tableid column.");
|
||||
db.execSQL("ALTER TABLE " + TRACKS_TABLE
|
||||
+ " ADD " + TracksColumns.TABLEID + " STRING");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final UriMatcher urlMatcher;
|
||||
|
||||
private SQLiteDatabase db;
|
||||
|
||||
public MyTracksProvider() {
|
||||
urlMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.AUTHORITY,
|
||||
"trackpoints", TRACKPOINTS);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.AUTHORITY,
|
||||
"trackpoints/#", TRACKPOINTS_ID);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.AUTHORITY, "tracks", TRACKS);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.AUTHORITY, "tracks/#", TRACKS_ID);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.AUTHORITY, "waypoints", WAYPOINTS);
|
||||
urlMatcher.addURI(MyTracksProviderUtils.AUTHORITY,
|
||||
"waypoints/#", WAYPOINTS_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
DatabaseHelper dbHelper = new DatabaseHelper(getContext());
|
||||
try {
|
||||
db = dbHelper.getWritableDatabase();
|
||||
} catch (SQLiteException e) {
|
||||
Log.e(TAG, "Unable to open database for writing", e);
|
||||
}
|
||||
return db != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(Uri url, String where, String[] selectionArgs) {
|
||||
String table;
|
||||
boolean shouldVacuum = false;
|
||||
switch (urlMatcher.match(url)) {
|
||||
case TRACKPOINTS:
|
||||
table = TRACKPOINTS_TABLE;
|
||||
break;
|
||||
case TRACKS:
|
||||
table = TRACKS_TABLE;
|
||||
shouldVacuum = true;
|
||||
break;
|
||||
case WAYPOINTS:
|
||||
table = WAYPOINTS_TABLE;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
|
||||
Log.w(MyTracksProvider.TAG, "provider delete in " + table + "!");
|
||||
int count = db.delete(table, where, selectionArgs);
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
|
||||
if (shouldVacuum) {
|
||||
// If a potentially large amount of data was deleted, we want to reclaim its space.
|
||||
Log.i(TAG, "Vacuuming the database");
|
||||
db.execSQL("VACUUM");
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri url) {
|
||||
switch (urlMatcher.match(url)) {
|
||||
case TRACKPOINTS:
|
||||
return TrackPointsColumns.CONTENT_TYPE;
|
||||
case TRACKPOINTS_ID:
|
||||
return TrackPointsColumns.CONTENT_ITEMTYPE;
|
||||
case TRACKS:
|
||||
return TracksColumns.CONTENT_TYPE;
|
||||
case TRACKS_ID:
|
||||
return TracksColumns.CONTENT_ITEMTYPE;
|
||||
case WAYPOINTS:
|
||||
return WaypointsColumns.CONTENT_TYPE;
|
||||
case WAYPOINTS_ID:
|
||||
return WaypointsColumns.CONTENT_ITEMTYPE;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri url, ContentValues initialValues) {
|
||||
Log.d(MyTracksProvider.TAG, "MyTracksProvider.insert");
|
||||
ContentValues values;
|
||||
if (initialValues != null) {
|
||||
values = initialValues;
|
||||
public class MyTracksProvider extends DatabaseProvider {
|
||||
|
||||
private boolean canAccess() {
|
||||
if (Binder.getCallingPid() == Process.myPid()) {
|
||||
return true;
|
||||
} else {
|
||||
values = new ContentValues();
|
||||
}
|
||||
|
||||
int urlMatchType = urlMatcher.match(url);
|
||||
return insertType(url, urlMatchType, values);
|
||||
}
|
||||
|
||||
private Uri insertType(Uri url, int urlMatchType, ContentValues values) {
|
||||
switch (urlMatchType) {
|
||||
case TRACKPOINTS:
|
||||
return insertTrackPoint(url, values);
|
||||
case TRACKS:
|
||||
return insertTrack(url, values);
|
||||
case WAYPOINTS:
|
||||
return insertWaypoint(url, values);
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
Context context = getContext();
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(
|
||||
Constants.SETTINGS_NAME, 0);
|
||||
return sharedPreferences.getBoolean(context.getString(R.string.share_data_key), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a URI based on the input URI, but replaces the
|
||||
* {@link MyTracksProvider} authority with the {@link DatabaseProvider}
|
||||
* authority. Returns null if the input URI doesn't contain the
|
||||
* {@link MyTracksProvider} authority.
|
||||
*/
|
||||
private Uri getDatabaseProviderUri(Uri uri) {
|
||||
String authority = uri.getAuthority();
|
||||
if (authority != null && authority.equals(MyTracksProviderUtils.AUTHORITY)) {
|
||||
String databaseUri = "content://" + MyTracksProviderUtils.DATABASE_AUTHORITY;
|
||||
String path = uri.getPath();
|
||||
if (path != null && !path.isEmpty()) {
|
||||
databaseUri += path;
|
||||
}
|
||||
return Uri.parse(databaseUri);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bulkInsert(Uri url, ContentValues[] valuesBulk) {
|
||||
Log.d(MyTracksProvider.TAG, "MyTracksProvider.bulkInsert");
|
||||
int numInserted = 0;
|
||||
try {
|
||||
// Use a transaction in order to make the insertions run as a single batch
|
||||
db.beginTransaction();
|
||||
|
||||
int urlMatch = urlMatcher.match(url);
|
||||
for (numInserted = 0; numInserted < valuesBulk.length; numInserted++) {
|
||||
ContentValues values = valuesBulk[numInserted];
|
||||
if (values == null) { values = new ContentValues(); }
|
||||
|
||||
insertType(url, urlMatch, values);
|
||||
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
||||
if (!canAccess()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
return numInserted;
|
||||
return super.delete(getDatabaseProviderUri(uri), selection, selectionArgs);
|
||||
}
|
||||
|
||||
private Uri insertTrackPoint(Uri url, ContentValues values) {
|
||||
boolean hasLat = values.containsKey(TrackPointsColumns.LATITUDE);
|
||||
boolean hasLong = values.containsKey(TrackPointsColumns.LONGITUDE);
|
||||
boolean hasTime = values.containsKey(TrackPointsColumns.TIME);
|
||||
if (!hasLat || !hasLong || !hasTime) {
|
||||
throw new IllegalArgumentException(
|
||||
"Latitude, longitude, and time values are required.");
|
||||
@Override
|
||||
public String getType(Uri uri) {
|
||||
if (!canAccess()) {
|
||||
return null;
|
||||
}
|
||||
long rowId = db.insert(TRACKPOINTS_TABLE, TrackPointsColumns._ID, values);
|
||||
if (rowId >= 0) {
|
||||
Uri uri = ContentUris.appendId(
|
||||
TrackPointsColumns.CONTENT_URI.buildUpon(), rowId).build();
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return uri;
|
||||
}
|
||||
throw new SQLiteException("Failed to insert row into " + url);
|
||||
return super.getType(getDatabaseProviderUri(uri));
|
||||
}
|
||||
|
||||
private Uri insertTrack(Uri url, ContentValues values) {
|
||||
boolean hasStartTime = values.containsKey(TracksColumns.STARTTIME);
|
||||
boolean hasStartId = values.containsKey(TracksColumns.STARTID);
|
||||
if (!hasStartTime || !hasStartId) {
|
||||
throw new IllegalArgumentException(
|
||||
"Both start time and start id values are required.");
|
||||
@Override
|
||||
public Uri insert(Uri uri, ContentValues values) {
|
||||
if (!canAccess()) {
|
||||
return null;
|
||||
}
|
||||
long rowId = db.insert(TRACKS_TABLE, TracksColumns._ID, values);
|
||||
if (rowId > 0) {
|
||||
Uri uri = ContentUris.appendId(
|
||||
TracksColumns.CONTENT_URI.buildUpon(), rowId).build();
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return uri;
|
||||
}
|
||||
throw new SQLException("Failed to insert row into " + url);
|
||||
return super.insert(getDatabaseProviderUri(uri), values);
|
||||
}
|
||||
|
||||
private Uri insertWaypoint(Uri url, ContentValues values) {
|
||||
long rowId = db.insert(WAYPOINTS_TABLE, WaypointsColumns._ID, values);
|
||||
if (rowId > 0) {
|
||||
Uri uri = ContentUris.appendId(
|
||||
WaypointsColumns.CONTENT_URI.buildUpon(), rowId).build();
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return uri;
|
||||
|
||||
@Override
|
||||
public int bulkInsert(Uri uri, ContentValues[] values) {
|
||||
if (!canAccess()) {
|
||||
return 0;
|
||||
}
|
||||
throw new SQLException("Failed to insert row into " + url);
|
||||
return super.bulkInsert(getDatabaseProviderUri(uri), values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(
|
||||
Uri url, String[] projection, String selection, String[] selectionArgs,
|
||||
String sort) {
|
||||
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
|
||||
int match = urlMatcher.match(url);
|
||||
String sortOrder = null;
|
||||
if (match == TRACKPOINTS) {
|
||||
qb.setTables(TRACKPOINTS_TABLE);
|
||||
if (sort != null) {
|
||||
sortOrder = sort;
|
||||
} else {
|
||||
sortOrder = TrackPointsColumns.DEFAULT_SORT_ORDER;
|
||||
}
|
||||
} else if (match == TRACKPOINTS_ID) {
|
||||
qb.setTables(TRACKPOINTS_TABLE);
|
||||
qb.appendWhere("_id=" + url.getPathSegments().get(1));
|
||||
} else if (match == TRACKS) {
|
||||
qb.setTables(TRACKS_TABLE);
|
||||
if (sort != null) {
|
||||
sortOrder = sort;
|
||||
} else {
|
||||
sortOrder = TracksColumns.DEFAULT_SORT_ORDER;
|
||||
}
|
||||
} else if (match == TRACKS_ID) {
|
||||
qb.setTables(TRACKS_TABLE);
|
||||
qb.appendWhere("_id=" + url.getPathSegments().get(1));
|
||||
} else if (match == WAYPOINTS) {
|
||||
qb.setTables(WAYPOINTS_TABLE);
|
||||
if (sort != null) {
|
||||
sortOrder = sort;
|
||||
} else {
|
||||
sortOrder = WaypointsColumns.DEFAULT_SORT_ORDER;
|
||||
}
|
||||
} else if (match == WAYPOINTS_ID) {
|
||||
qb.setTables(WAYPOINTS_TABLE);
|
||||
qb.appendWhere("_id=" + url.getPathSegments().get(1));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
|
||||
if (!canAccess()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (ApiFeatures.getInstance().canReuseSQLiteQueryBuilder()) {
|
||||
Log.i(Constants.TAG,
|
||||
"Build query: " + qb.buildQuery(projection, selection, selectionArgs,
|
||||
null, null, sortOrder, null));
|
||||
}
|
||||
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null,
|
||||
sortOrder);
|
||||
c.setNotificationUri(getContext().getContentResolver(), url);
|
||||
return c;
|
||||
return super.query(getDatabaseProviderUri(uri), projection, selection, selectionArgs, sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri url, ContentValues values, String where,
|
||||
String[] selectionArgs) {
|
||||
int count;
|
||||
int match = urlMatcher.match(url);
|
||||
if (match == TRACKPOINTS) {
|
||||
count = db.update(TRACKPOINTS_TABLE, values, where, selectionArgs);
|
||||
} else if (match == TRACKPOINTS_ID) {
|
||||
String segment = url.getPathSegments().get(1);
|
||||
count = db.update(TRACKPOINTS_TABLE, values, "_id=" + segment
|
||||
+ (!TextUtils.isEmpty(where)
|
||||
? " AND (" + where + ')'
|
||||
: ""),
|
||||
selectionArgs);
|
||||
} else if (match == TRACKS) {
|
||||
count = db.update(TRACKS_TABLE, values, where, selectionArgs);
|
||||
} else if (match == TRACKS_ID) {
|
||||
String segment = url.getPathSegments().get(1);
|
||||
count = db.update(TRACKS_TABLE, values, "_id=" + segment
|
||||
+ (!TextUtils.isEmpty(where)
|
||||
? " AND (" + where + ')'
|
||||
: ""),
|
||||
selectionArgs);
|
||||
} else if (match == WAYPOINTS) {
|
||||
count = db.update(WAYPOINTS_TABLE, values, where, selectionArgs);
|
||||
} else if (match == WAYPOINTS_ID) {
|
||||
String segment = url.getPathSegments().get(1);
|
||||
count = db.update(WAYPOINTS_TABLE, values, "_id=" + segment
|
||||
+ (!TextUtils.isEmpty(where)
|
||||
? " AND (" + where + ')'
|
||||
: ""),
|
||||
selectionArgs);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown URL " + url);
|
||||
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
||||
if (!canAccess()) {
|
||||
return 0;
|
||||
}
|
||||
getContext().getContentResolver().notifyChange(url, null, true);
|
||||
return count;
|
||||
return super.update(getDatabaseProviderUri(uri), values, selection, selectionArgs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2011 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.content;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* A factory to return a new {@link MyTracksProviderUtils} that can access the
|
||||
* Database content provider, {@link DatabaseProvider}.
|
||||
*
|
||||
* @author jshih@google.com (Jimmy Shih)
|
||||
*/
|
||||
public class MyTracksProviderUtilsFactory {
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link MyTracksProviderUtils} that uses the given
|
||||
* context to access the Database content provider, {@link DatabaseProvider}.
|
||||
*/
|
||||
public static MyTracksProviderUtils get(Context context) {
|
||||
return new MyTracksProviderUtilsImpl(
|
||||
context.getContentResolver(), MyTracksProviderUtils.DATABASE_AUTHORITY);
|
||||
}
|
||||
}
|
||||
@@ -202,7 +202,7 @@ public class TrackDataHub {
|
||||
*/
|
||||
public synchronized static TrackDataHub newInstance(Context context) {
|
||||
SharedPreferences preferences = context.getSharedPreferences(Constants.SETTINGS_NAME, 0);
|
||||
MyTracksProviderUtils providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
MyTracksProviderUtils providerUtils = MyTracksProviderUtilsFactory.get(context);
|
||||
return new TrackDataHub(context,
|
||||
new TrackDataListeners(),
|
||||
preferences, providerUtils,
|
||||
|
||||
@@ -17,7 +17,7 @@ package com.google.android.apps.mytracks.io;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.ProgressIndicator;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.io.docs.DocsHelper;
|
||||
import com.google.android.apps.mytracks.io.gdata.GDataClientFactory;
|
||||
@@ -102,8 +102,7 @@ public class SendToDocs {
|
||||
}
|
||||
|
||||
// Get the track from the provider:
|
||||
Track track =
|
||||
MyTracksProviderUtils.Factory.get(activity).getTrack(trackId);
|
||||
Track track = MyTracksProviderUtilsFactory.get(activity).getTrack(trackId);
|
||||
if (track == null) {
|
||||
Log.w(Constants.TAG, "Cannot get track.");
|
||||
return;
|
||||
|
||||
@@ -20,6 +20,7 @@ import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.ProgressIndicator;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.io.gdata.GDataWrapper;
|
||||
@@ -138,7 +139,7 @@ public class SendToFusionTables implements Runnable {
|
||||
this.progressIndicator = progressIndicator;
|
||||
this.onCompletion = onCompletion;
|
||||
this.stringUtils = new StringUtils(context);
|
||||
this.providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
this.providerUtils = MyTracksProviderUtilsFactory.get(context);
|
||||
|
||||
HttpTransport transport = ApiFeatures.getInstance().useNetHttpTransport()
|
||||
? new NetHttpTransport() : new ApacheHttpTransport();
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
package com.google.android.apps.mytracks.io;
|
||||
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.ProgressIndicator;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.io.mymaps.MapsFacade;
|
||||
@@ -87,7 +89,7 @@ public class SendToMyMaps implements Runnable {
|
||||
this.progressIndicator = progressIndicator;
|
||||
this.onCompletion = onCompletion;
|
||||
this.stringUtils = new StringUtils(context);
|
||||
this.providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
this.providerUtils = MyTracksProviderUtilsFactory.get(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -177,7 +177,7 @@ class ExternalFileBackup {
|
||||
// Dump the entire contents of each table
|
||||
ContentResolver contentResolver = context.getContentResolver();
|
||||
Cursor tracksCursor = contentResolver.query(
|
||||
TracksColumns.CONTENT_URI, null, null, null, null);
|
||||
TracksColumns.DATABASE_CONTENT_URI, null, null, null, null);
|
||||
try {
|
||||
trackDumper.writeAllRows(tracksCursor, outWriter);
|
||||
} finally {
|
||||
@@ -185,7 +185,7 @@ class ExternalFileBackup {
|
||||
}
|
||||
|
||||
Cursor waypointsCursor = contentResolver.query(
|
||||
WaypointsColumns.CONTENT_URI, null, null, null, null);
|
||||
WaypointsColumns.DATABASE_CONTENT_URI, null, null, null, null);
|
||||
try {
|
||||
waypointDumper.writeAllRows(waypointsCursor, outWriter);
|
||||
} finally {
|
||||
@@ -193,7 +193,7 @@ class ExternalFileBackup {
|
||||
}
|
||||
|
||||
Cursor pointsCursor = contentResolver.query(
|
||||
TrackPointsColumns.CONTENT_URI, null, null, null, null);
|
||||
TrackPointsColumns.DATABASE_CONTENT_URI, null, null, null, null);
|
||||
try {
|
||||
pointDumper.writeAllRows(pointsCursor, outWriter);
|
||||
} finally {
|
||||
@@ -227,12 +227,12 @@ class ExternalFileBackup {
|
||||
|
||||
PreferenceBackupHelper preferencesHelper = new PreferenceBackupHelper();
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
DatabaseImporter trackImporter =
|
||||
new DatabaseImporter(TracksColumns.CONTENT_URI, resolver, false);
|
||||
DatabaseImporter waypointImporter =
|
||||
new DatabaseImporter(WaypointsColumns.CONTENT_URI, resolver, false);
|
||||
DatabaseImporter pointImporter =
|
||||
new DatabaseImporter(TrackPointsColumns.CONTENT_URI, resolver, false);
|
||||
DatabaseImporter trackImporter = new DatabaseImporter(
|
||||
TracksColumns.DATABASE_CONTENT_URI, resolver, false);
|
||||
DatabaseImporter waypointImporter = new DatabaseImporter(
|
||||
WaypointsColumns.DATABASE_CONTENT_URI, resolver, false);
|
||||
DatabaseImporter pointImporter = new DatabaseImporter(
|
||||
TrackPointsColumns.DATABASE_CONTENT_URI, resolver, false);
|
||||
|
||||
ZipFile zipFile = new ZipFile(inputFile, ZipFile.OPEN_READ);
|
||||
ZipEntry zipEntry = zipFile.getEntry(ZIP_ENTRY_NAME);
|
||||
@@ -245,9 +245,9 @@ class ExternalFileBackup {
|
||||
|
||||
try {
|
||||
// Delete all previous contents of the tables and preferences.
|
||||
resolver.delete(TracksColumns.CONTENT_URI, null, null);
|
||||
resolver.delete(TrackPointsColumns.CONTENT_URI, null, null);
|
||||
resolver.delete(WaypointsColumns.CONTENT_URI, null, null);
|
||||
resolver.delete(TracksColumns.DATABASE_CONTENT_URI, null, null);
|
||||
resolver.delete(TrackPointsColumns.DATABASE_CONTENT_URI, null, null);
|
||||
resolver.delete(WaypointsColumns.DATABASE_CONTENT_URI, null, null);
|
||||
|
||||
// Import the new contents of each table
|
||||
trackImporter.importAllRows(reader);
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.google.android.apps.mytracks.io.file;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.util.UriUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
@@ -64,7 +65,7 @@ public class ImportActivity extends Activity {
|
||||
public void onCreate(Bundle savedState) {
|
||||
super.onCreate(savedState);
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(this);
|
||||
providerUtils = MyTracksProviderUtilsFactory.get(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,7 +148,7 @@ public class ImportActivity extends Activity {
|
||||
|
||||
protected void showImportedTrack() {
|
||||
long lastTrackId = importedTrackIds[importedTrackIds.length - 1];
|
||||
Uri trackUri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, lastTrackId);
|
||||
Uri trackUri = ContentUris.withAppendedId(TracksColumns.DATABASE_CONTENT_URI, lastTrackId);
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(trackUri, TracksColumns.CONTENT_ITEMTYPE);
|
||||
|
||||
@@ -19,6 +19,7 @@ import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
|
||||
import com.google.android.apps.mytracks.util.FileUtils;
|
||||
@@ -63,7 +64,7 @@ public class SaveActivity extends Activity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(this);
|
||||
providerUtils = MyTracksProviderUtilsFactory.get(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,9 +75,9 @@ public class SaveActivity extends Activity {
|
||||
String action = intent.getAction();
|
||||
String type = intent.getType();
|
||||
Uri data = intent.getData();
|
||||
if (!getString(R.string.save_intent_action).equals(action) ||
|
||||
!TracksColumns.CONTENT_ITEMTYPE.equals(type) ||
|
||||
!UriUtils.matchesContentUri(data, TracksColumns.CONTENT_URI)) {
|
||||
if (!getString(R.string.save_intent_action).equals(action)
|
||||
|| !TracksColumns.CONTENT_ITEMTYPE.equals(type)
|
||||
|| !UriUtils.matchesContentUri(data, TracksColumns.DATABASE_CONTENT_URI)) {
|
||||
Log.e(TAG, "Got bad save intent: " + intent);
|
||||
finish();
|
||||
return;
|
||||
@@ -224,7 +225,7 @@ public class SaveActivity extends Activity {
|
||||
shareFile = true;
|
||||
}
|
||||
|
||||
Uri uri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, trackId);
|
||||
Uri uri = ContentUris.withAppendedId(TracksColumns.DATABASE_CONTENT_URI, trackId);
|
||||
|
||||
Intent intent = new Intent(ctx, SaveActivity.class);
|
||||
intent.setAction(ctx.getString(R.string.save_intent_action));
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyMapsList;
|
||||
import com.google.android.apps.mytracks.ProgressIndicator;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.io.AuthManager;
|
||||
@@ -158,7 +159,7 @@ public class SendActivity extends Activity implements ProgressIndicator {
|
||||
Log.d(TAG, "SendActivity.onCreate");
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(this);
|
||||
providerUtils = MyTracksProviderUtilsFactory.get(this);
|
||||
sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, 0);
|
||||
|
||||
tracker = GoogleAnalyticsTracker.getInstance();
|
||||
@@ -197,9 +198,8 @@ public class SendActivity extends Activity implements ProgressIndicator {
|
||||
String action = intent.getAction();
|
||||
String type = intent.getType();
|
||||
Uri data = intent.getData();
|
||||
if (!Intent.ACTION_SEND.equals(action) ||
|
||||
!TracksColumns.CONTENT_ITEMTYPE.equals(type) ||
|
||||
!UriUtils.matchesContentUri(data, TracksColumns.CONTENT_URI)) {
|
||||
if (!Intent.ACTION_SEND.equals(action) || !TracksColumns.CONTENT_ITEMTYPE.equals(type)
|
||||
|| !UriUtils.matchesContentUri(data, TracksColumns.DATABASE_CONTENT_URI)) {
|
||||
Log.e(TAG, "Got bad send intent: " + intent);
|
||||
return false;
|
||||
}
|
||||
@@ -911,7 +911,7 @@ public class SendActivity extends Activity implements ProgressIndicator {
|
||||
}
|
||||
|
||||
public static void sendToGoogle(Context ctx, long trackId, boolean shareLink) {
|
||||
Uri uri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, trackId);
|
||||
Uri uri = ContentUris.withAppendedId(TracksColumns.DATABASE_CONTENT_URI, trackId);
|
||||
|
||||
Intent intent = new Intent(ctx, SendActivity.class);
|
||||
intent.setAction(Intent.ACTION_SEND);
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ package com.google.android.apps.mytracks.maps;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
@@ -104,7 +104,7 @@ public class DynamicSpeedTrackPathDescriptor
|
||||
// Could not find track.
|
||||
return false;
|
||||
}
|
||||
Track track = MyTracksProviderUtils.Factory.get(context).getTrack(currentTrackId);
|
||||
Track track = MyTracksProviderUtilsFactory.get(context).getTrack(currentTrackId);
|
||||
TripStatistics stats = track.getStatistics();
|
||||
double newaverageSpeed = (int) Math.floor(stats.getAverageMovingSpeed() * 3.6);
|
||||
|
||||
|
||||
@@ -235,6 +235,11 @@ public class TrackRecordingService extends Service {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Log.d(TAG, "TrackRecordingService.onCreate");
|
||||
|
||||
/*
|
||||
* Use the MyTracksProviderUtils that access the MyTracksProvider because
|
||||
* this service can be called by MyTracks or another app.
|
||||
*/
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(this);
|
||||
notificationManager =
|
||||
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracks;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.services.ControlRecordingService;
|
||||
@@ -91,7 +92,7 @@ public class TrackWidgetProvider
|
||||
}
|
||||
this.context = context;
|
||||
trackObserver = new TrackObserver();
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
providerUtils = MyTracksProviderUtilsFactory.get(context);
|
||||
unknown = context.getString(R.string.unknown);
|
||||
|
||||
sharedPreferences = context.getSharedPreferences(SETTINGS_NAME, 0);
|
||||
@@ -99,7 +100,7 @@ public class TrackWidgetProvider
|
||||
onSharedPreferenceChanged(sharedPreferences, null);
|
||||
|
||||
context.getContentResolver().registerContentObserver(
|
||||
TracksColumns.CONTENT_URI, true, trackObserver);
|
||||
TracksColumns.DATABASE_CONTENT_URI, true, trackObserver);
|
||||
TRACK_STARTED_ACTION = context.getString(R.string.track_started_broadcast_action);
|
||||
TRACK_STOPPED_ACTION = context.getString(R.string.track_stopped_broadcast_action);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,13 @@ public interface MyTracksProviderUtils {
|
||||
*/
|
||||
public static final String AUTHORITY = "com.google.android.maps.mytracks";
|
||||
|
||||
/**
|
||||
* Authority for the Database content provider. The Database content provider
|
||||
* is configured, through the MyTracks AndroidManifest.xml, to only allow the
|
||||
* MyTracks app access.
|
||||
*/
|
||||
public static final String DATABASE_AUTHORITY = "com.google.android.apps.mytracks.content";
|
||||
|
||||
/**
|
||||
* Deletes all tracks (including track points) from the provider.
|
||||
*/
|
||||
@@ -437,7 +444,7 @@ public interface MyTracksProviderUtils {
|
||||
* Creates an instance of {@link MyTracksProviderUtils}.
|
||||
*/
|
||||
protected MyTracksProviderUtils newForContext(Context context) {
|
||||
return new MyTracksProviderUtilsImpl(context.getContentResolver());
|
||||
return new MyTracksProviderUtilsImpl(context.getContentResolver(), AUTHORITY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+57
-45
@@ -16,7 +16,7 @@
|
||||
package com.google.android.apps.mytracks.content;
|
||||
|
||||
import static com.google.android.apps.mytracks.lib.MyTracksLibConstants.TAG;
|
||||
import com.google.android.apps.mytracks.content.Sensor;
|
||||
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
|
||||
@@ -40,13 +40,39 @@ import java.util.NoSuchElementException;
|
||||
public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
|
||||
private final ContentResolver contentResolver;
|
||||
private final String authority; // authority of the content provider
|
||||
|
||||
private int defaultCursorBatchSize = 2000;
|
||||
|
||||
public MyTracksProviderUtilsImpl(ContentResolver contentResolver) {
|
||||
public MyTracksProviderUtilsImpl(ContentResolver contentResolver, String authority) {
|
||||
this.contentResolver = contentResolver;
|
||||
this.authority = authority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tracks table URI.
|
||||
*/
|
||||
private Uri getTracksUri() {
|
||||
return authority.equals(DATABASE_AUTHORITY) ? TracksColumns.DATABASE_CONTENT_URI
|
||||
: TracksColumns.CONTENT_URI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the track points table URI.
|
||||
*/
|
||||
private Uri getTrackPointsUri() {
|
||||
return authority.equals(DATABASE_AUTHORITY) ? TrackPointsColumns.DATABASE_CONTENT_URI
|
||||
: TrackPointsColumns.CONTENT_URI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the waypoints table URI.
|
||||
*/
|
||||
private Uri getWaypointsUri() {
|
||||
return authority.equals(DATABASE_AUTHORITY) ? WaypointsColumns.DATABASE_CONTENT_URI
|
||||
: WaypointsColumns.CONTENT_URI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the ContentValues for a given location object.
|
||||
*
|
||||
@@ -518,24 +544,20 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
|
||||
@Override
|
||||
public void deleteAllTracks() {
|
||||
contentResolver.delete(TracksColumns.CONTENT_URI, null, null);
|
||||
contentResolver.delete(TrackPointsColumns.CONTENT_URI,
|
||||
null, null);
|
||||
contentResolver.delete(WaypointsColumns.CONTENT_URI, null, null);
|
||||
contentResolver.delete(getTracksUri(), null, null);
|
||||
contentResolver.delete(getTrackPointsUri(), null, null);
|
||||
contentResolver.delete(getWaypointsUri(), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteTrack(long trackId) {
|
||||
Track track = getTrack(trackId);
|
||||
if (track != null) {
|
||||
contentResolver.delete(TrackPointsColumns.CONTENT_URI,
|
||||
"_id>=" + track.getStartId() + " AND _id<=" + track.getStopId(),
|
||||
null);
|
||||
contentResolver.delete(getTrackPointsUri(),
|
||||
"_id>=" + track.getStartId() + " AND _id<=" + track.getStopId(), null);
|
||||
}
|
||||
contentResolver.delete(WaypointsColumns.CONTENT_URI,
|
||||
WaypointsColumns.TRACKID + "=" + trackId, null);
|
||||
contentResolver.delete(
|
||||
TracksColumns.CONTENT_URI, "_id=" + trackId, null);
|
||||
contentResolver.delete(getWaypointsUri(), WaypointsColumns.TRACKID + "=" + trackId, null);
|
||||
contentResolver.delete(getTracksUri(), "_id=" + trackId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -559,8 +581,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
Log.d(TAG, "No statistics marker after the deleted one was found.");
|
||||
}
|
||||
}
|
||||
contentResolver.delete(
|
||||
WaypointsColumns.CONTENT_URI, "_id=" + waypointId, null);
|
||||
contentResolver.delete(getWaypointsUri(), "_id=" + waypointId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -572,7 +593,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = contentResolver.query(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
getWaypointsUri(),
|
||||
null /*projection*/,
|
||||
selection,
|
||||
null /*selectionArgs*/,
|
||||
@@ -594,7 +615,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
public boolean updateWaypoint(Waypoint waypoint) {
|
||||
try {
|
||||
final int rows = contentResolver.update(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
getWaypointsUri(),
|
||||
createContentValues(waypoint),
|
||||
"_id=" + waypoint.getId(),
|
||||
null /*selectionArgs*/);
|
||||
@@ -614,8 +635,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
private Location findLocationBy(String select) {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = contentResolver.query(
|
||||
TrackPointsColumns.CONTENT_URI, null, select, null, null);
|
||||
cursor = contentResolver.query(getTrackPointsUri(), null, select, null, null);
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
return createLocation(cursor);
|
||||
}
|
||||
@@ -638,8 +658,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
private Track findTrackBy(String select) {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = contentResolver.query(
|
||||
TracksColumns.CONTENT_URI, null, select, null, null);
|
||||
cursor = contentResolver.query(getTracksUri(), null, select, null, null);
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
return createTrack(cursor);
|
||||
}
|
||||
@@ -665,7 +684,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
}
|
||||
|
||||
Cursor cursor = contentResolver.query(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
getWaypointsUri(),
|
||||
null /*projection*/,
|
||||
"trackid=" + trackId,
|
||||
null /*selectionArgs*/,
|
||||
@@ -691,7 +710,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
}
|
||||
|
||||
Cursor cursor = contentResolver.query(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
getWaypointsUri(),
|
||||
null /*projection*/,
|
||||
"_id=" + waypointId,
|
||||
null /*selectionArgs*/,
|
||||
@@ -718,7 +737,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
|
||||
final String[] projection = {"_id"};
|
||||
Cursor cursor = contentResolver.query(
|
||||
TrackPointsColumns.CONTENT_URI,
|
||||
getTrackPointsUri(),
|
||||
projection,
|
||||
"_id=(select max(_id) from trackpoints WHERE trackid=" + trackId + ")",
|
||||
null /*selectionArgs*/,
|
||||
@@ -746,7 +765,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
|
||||
final String[] projection = {"_id"};
|
||||
Cursor cursor = contentResolver.query(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
getWaypointsUri(),
|
||||
projection,
|
||||
"trackid=" + trackId,
|
||||
null /*selectionArgs*/,
|
||||
@@ -774,7 +793,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
|
||||
final String[] projection = {"_id"};
|
||||
Cursor cursor = contentResolver.query(
|
||||
WaypointsColumns.CONTENT_URI,
|
||||
getWaypointsUri(),
|
||||
projection,
|
||||
WaypointsColumns.TRACKID + "=" + trackId,
|
||||
null /*selectionArgs*/,
|
||||
@@ -799,8 +818,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = contentResolver.query(
|
||||
TracksColumns.CONTENT_URI, null, "_id=(select max(_id) from tracks)",
|
||||
null, null);
|
||||
getTracksUri(), null, "_id=(select max(_id) from tracks)", null, null);
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
return createTrack(cursor);
|
||||
}
|
||||
@@ -818,8 +836,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
public long getLastTrackId() {
|
||||
String[] proj = { TracksColumns._ID };
|
||||
Cursor cursor = contentResolver.query(
|
||||
TracksColumns.CONTENT_URI, proj, "_id=(select max(_id) from tracks)",
|
||||
null, null);
|
||||
getTracksUri(), proj, "_id=(select max(_id) from tracks)", null, null);
|
||||
if (cursor != null) {
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
@@ -864,7 +881,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
sortOrder += " LIMIT " + maxLocations;
|
||||
}
|
||||
|
||||
return contentResolver.query(TrackPointsColumns.CONTENT_URI, null, selection, null, sortOrder);
|
||||
return contentResolver.query(getTrackPointsUri(), null, selection, null, sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -889,8 +906,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
sortOrder += " LIMIT " + maxWaypoints;
|
||||
}
|
||||
|
||||
return contentResolver.query(
|
||||
WaypointsColumns.CONTENT_URI, null, selection, null, sortOrder);
|
||||
return contentResolver.query(getWaypointsUri(), null, selection, null, sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -924,23 +940,20 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
|
||||
@Override
|
||||
public Cursor getTracksCursor(String selection) {
|
||||
Cursor cursor = contentResolver.query(
|
||||
TracksColumns.CONTENT_URI, null, selection, null, "_id");
|
||||
Cursor cursor = contentResolver.query(getTracksUri(), null, selection, null, "_id");
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insertTrack(Track track) {
|
||||
Log.d(TAG, "MyTracksProviderUtilsImpl.insertTrack");
|
||||
return contentResolver.insert(TracksColumns.CONTENT_URI,
|
||||
createContentValues(track));
|
||||
return contentResolver.insert(getTracksUri(), createContentValues(track));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insertTrackPoint(Location location, long trackId) {
|
||||
Log.d(TAG, "MyTracksProviderUtilsImpl.insertTrackPoint");
|
||||
return contentResolver.insert(TrackPointsColumns.CONTENT_URI,
|
||||
createContentValues(location, trackId));
|
||||
return contentResolver.insert(getTrackPointsUri(), createContentValues(location, trackId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -952,15 +965,14 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
values[i] = createContentValues(locations[i], trackId);
|
||||
}
|
||||
|
||||
return contentResolver.bulkInsert(TrackPointsColumns.CONTENT_URI, values);
|
||||
return contentResolver.bulkInsert(getTrackPointsUri(), values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insertWaypoint(Waypoint waypoint) {
|
||||
Log.d(TAG, "MyTracksProviderUtilsImpl.insertWaypoint");
|
||||
waypoint.setId(-1);
|
||||
return contentResolver.insert(WaypointsColumns.CONTENT_URI,
|
||||
createContentValues(waypoint));
|
||||
return contentResolver.insert(getWaypointsUri(), createContentValues(waypoint));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -973,7 +985,7 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
try {
|
||||
final String[] projection = { TracksColumns._ID };
|
||||
cursor = contentResolver.query(
|
||||
TracksColumns.CONTENT_URI,
|
||||
getTracksUri(),
|
||||
projection,
|
||||
TracksColumns._ID + "=" + id/*selection*/,
|
||||
null/*selectionArgs*/,
|
||||
@@ -992,8 +1004,8 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
||||
@Override
|
||||
public void updateTrack(Track track) {
|
||||
Log.d(TAG, "MyTracksProviderUtilsImpl.updateTrack");
|
||||
contentResolver.update(TracksColumns.CONTENT_URI,
|
||||
createContentValues(track), "_id=" + track.getId(), null);
|
||||
contentResolver.update(
|
||||
getTracksUri(), createContentValues(track), "_id=" + track.getId(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,8 +25,14 @@ import android.provider.BaseColumns;
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public interface TrackPointsColumns extends BaseColumns {
|
||||
public static final Uri CONTENT_URI =
|
||||
Uri.parse("content://com.google.android.maps.mytracks/trackpoints");
|
||||
|
||||
// MyTracks content provider URI for the track points table.
|
||||
public static final Uri CONTENT_URI = Uri.parse(
|
||||
"content://" + MyTracksProviderUtils.AUTHORITY + "/trackpoints");
|
||||
|
||||
// Database content provider URI for the track points table.
|
||||
public static final Uri DATABASE_CONTENT_URI = Uri.parse(
|
||||
"content://" + MyTracksProviderUtils.DATABASE_AUTHORITY + "/trackpoints");
|
||||
public static final String CONTENT_TYPE =
|
||||
"vnd.android.cursor.dir/vnd.google.trackpoint";
|
||||
public static final String CONTENT_ITEMTYPE =
|
||||
|
||||
@@ -26,8 +26,13 @@ import android.provider.BaseColumns;
|
||||
*/
|
||||
public interface TracksColumns extends BaseColumns {
|
||||
|
||||
public static final Uri CONTENT_URI =
|
||||
Uri.parse("content://com.google.android.maps.mytracks/tracks");
|
||||
// MyTracks content provider URI for the tracks table.
|
||||
public static final Uri CONTENT_URI = Uri.parse(
|
||||
"content://" + MyTracksProviderUtils.AUTHORITY + "/tracks");
|
||||
|
||||
// Database content provider URI for the tracks table.
|
||||
public static final Uri DATABASE_CONTENT_URI = Uri.parse(
|
||||
"content://" + MyTracksProviderUtils.DATABASE_AUTHORITY + "/tracks");
|
||||
public static final String CONTENT_TYPE =
|
||||
"vnd.android.cursor.dir/vnd.google.track";
|
||||
public static final String CONTENT_ITEMTYPE =
|
||||
|
||||
@@ -26,8 +26,13 @@ import android.provider.BaseColumns;
|
||||
*/
|
||||
public interface WaypointsColumns extends BaseColumns {
|
||||
|
||||
public static final Uri CONTENT_URI =
|
||||
Uri.parse("content://com.google.android.maps.mytracks/waypoints");
|
||||
// MyTracks content provider URI for the waypoints table.
|
||||
public static final Uri CONTENT_URI = Uri.parse(
|
||||
"content://" + MyTracksProviderUtils.AUTHORITY + "/waypoints");
|
||||
|
||||
// Database content provider URI for the waypoints table.
|
||||
public static final Uri DATABASE_CONTENT_URI = Uri.parse(
|
||||
"content://" + MyTracksProviderUtils.DATABASE_AUTHORITY + "/waypoints");
|
||||
public static final String CONTENT_TYPE =
|
||||
"vnd.android.cursor.dir/vnd.google.waypoint";
|
||||
public static final String CONTENT_ITEMTYPE =
|
||||
|
||||
@@ -63,7 +63,6 @@ public class MapOverlayTest extends AndroidTestCase {
|
||||
assertEquals(2, myTracksOverlay.getNumLocations());
|
||||
assertEquals(0, myTracksOverlay.getNumWaypoints());
|
||||
assertNotNull(myTracksOverlay.getLastPath());
|
||||
assertEquals(2, ((MockPath)myTracksOverlay.getLastPath()).totalPoints);
|
||||
|
||||
myTracksOverlay.draw(canvas, mockView, true);
|
||||
assertEquals(2, myTracksOverlay.getNumLocations());
|
||||
@@ -152,11 +151,8 @@ public class MapOverlayTest extends AndroidTestCase {
|
||||
// No shadow.
|
||||
myTracksOverlay.draw(canvas, mockView, false);
|
||||
assertNotNull(myTracksOverlay.getLastPath());
|
||||
assertTrue(myTracksOverlay.getLastPath() instanceof MockPath);
|
||||
MockPath path = (MockPath) myTracksOverlay.getLastPath();
|
||||
assertEquals(40, myTracksOverlay.getNumWaypoints());
|
||||
assertEquals(100, myTracksOverlay.getNumLocations());
|
||||
assertEquals(100, path.totalPoints);
|
||||
// TODO: Check the points from the path (and the segments).
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -46,12 +46,12 @@ public class MyTracksProviderUtilsImplTest extends AndroidTestCase {
|
||||
RenamingDelegatingContext targetContext = new RenamingDelegatingContext(
|
||||
getContext(), getContext(), "test.");
|
||||
context = new MockContext(mockContentResolver, targetContext);
|
||||
MyTracksProvider provider = new MyTracksProvider();
|
||||
DatabaseProvider provider = new DatabaseProvider();
|
||||
provider.attachInfo(context, null);
|
||||
mockContentResolver.addProvider(MyTracksProviderUtils.AUTHORITY, provider);
|
||||
mockContentResolver.addProvider(MyTracksProviderUtils.DATABASE_AUTHORITY, provider);
|
||||
setContext(context);
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
providerUtils = MyTracksProviderUtilsFactory.get(context);
|
||||
}
|
||||
|
||||
public void testLocationIterator_noPoints() {
|
||||
|
||||
@@ -142,7 +142,7 @@ public class TrackDataHubTest extends AndroidTestCase {
|
||||
expect(providerUtils.getTrack(TRACK_ID)).andStubReturn(track);
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(TracksColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
eq(TracksColumns.DATABASE_CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
// Expect the initial loading.
|
||||
// Both listeners (registered before and after start) should get the same data.
|
||||
@@ -322,7 +322,7 @@ public class TrackDataHubTest extends AndroidTestCase {
|
||||
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(WaypointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
eq(WaypointsColumns.DATABASE_CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
// Expect the initial loading.
|
||||
// Both listeners (registered before and after start) should get the same data.
|
||||
@@ -415,7 +415,7 @@ public class TrackDataHubTest extends AndroidTestCase {
|
||||
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
eq(TrackPointsColumns.DATABASE_CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 10, 5);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
@@ -502,7 +502,7 @@ public class TrackDataHubTest extends AndroidTestCase {
|
||||
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
eq(TrackPointsColumns.DATABASE_CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 10, 5);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
@@ -533,7 +533,7 @@ public class TrackDataHubTest extends AndroidTestCase {
|
||||
|
||||
// Register again, except only points since unregistered.
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
eq(TrackPointsColumns.DATABASE_CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
locationIterator = new FixedSizeLocationIterator(11, 10);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
@@ -574,7 +574,7 @@ public class TrackDataHubTest extends AndroidTestCase {
|
||||
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
eq(TrackPointsColumns.DATABASE_CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 10, 5);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
@@ -605,7 +605,7 @@ public class TrackDataHubTest extends AndroidTestCase {
|
||||
|
||||
// Register again after track changed, expect all points.
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
eq(TrackPointsColumns.DATABASE_CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
locationIterator = new FixedSizeLocationIterator(1, 10);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
@@ -632,7 +632,7 @@ public class TrackDataHubTest extends AndroidTestCase {
|
||||
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
eq(TrackPointsColumns.DATABASE_CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 200, 4, 25, 71, 120);
|
||||
expect(providerUtils.getLocationIterator(
|
||||
@@ -665,7 +665,7 @@ public class TrackDataHubTest extends AndroidTestCase {
|
||||
|
||||
expectStart();
|
||||
dataSources.registerContentObserver(
|
||||
eq(TrackPointsColumns.CONTENT_URI), eq(false), capture(observerCapture));
|
||||
eq(TrackPointsColumns.DATABASE_CONTENT_URI), eq(false), capture(observerCapture));
|
||||
|
||||
// Deliver 30 points (no sampling happens)
|
||||
FixedSizeLocationIterator locationIterator = new FixedSizeLocationIterator(1, 30, 5);
|
||||
|
||||
@@ -19,10 +19,9 @@ import static com.google.android.testing.mocking.AndroidMock.eq;
|
||||
import static com.google.android.testing.mocking.AndroidMock.expect;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory;
|
||||
import com.google.android.apps.mytracks.io.file.GpxImporter;
|
||||
import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory;
|
||||
import com.google.android.testing.mocking.AndroidMock;
|
||||
import com.google.android.testing.mocking.UsesMocks;
|
||||
@@ -106,7 +105,7 @@ public class GpxImporterTest extends AndroidTestCase {
|
||||
private static final long TRACK_POINT_ID_2 = 2;
|
||||
|
||||
private static final Uri TRACK_ID_URI = ContentUris.appendId(
|
||||
TracksColumns.CONTENT_URI.buildUpon(), TRACK_ID).build();
|
||||
TracksColumns.DATABASE_CONTENT_URI.buildUpon(), TRACK_ID).build();
|
||||
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
|
||||
|
||||
@@ -4,9 +4,10 @@ package com.google.android.apps.mytracks.io.file;
|
||||
|
||||
import static org.easymock.EasyMock.expect;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProvider;
|
||||
import com.google.android.apps.mytracks.content.DatabaseProvider;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils.Factory;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceTest.MockContext;
|
||||
@@ -140,11 +141,11 @@ public class TrackWriterTest extends AndroidTestCase {
|
||||
RenamingDelegatingContext targetContext = new RenamingDelegatingContext(
|
||||
getContext(), getContext(), "test.");
|
||||
Context context = new MockContext(mockContentResolver, targetContext);
|
||||
MyTracksProvider provider = new MyTracksProvider();
|
||||
DatabaseProvider provider = new DatabaseProvider();
|
||||
provider.attachInfo(context, null);
|
||||
mockContentResolver.addProvider(MyTracksProviderUtils.AUTHORITY, provider);
|
||||
mockContentResolver.addProvider(MyTracksProviderUtils.DATABASE_AUTHORITY, provider);
|
||||
setContext(context);
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
providerUtils = MyTracksProviderUtilsFactory.get(context);
|
||||
oldProviderUtilsFactory = TestingProviderUtilsFactory.installWithInstance(providerUtils);
|
||||
|
||||
mocksControl = EasyMock.createStrictControl();
|
||||
|
||||
+1
-6
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.MockPath;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
/**
|
||||
@@ -45,9 +43,6 @@ public class TrackPathDescriptorDynamicSpeedTest extends TrackPathPainterTestCas
|
||||
painter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, alwaysVisible,
|
||||
myTracksOverlay.getPoints());
|
||||
assertNotNull(myTracksOverlay.getLastPath());
|
||||
assertTrue(myTracksOverlay.getLastPath() instanceof MockPath);
|
||||
painter.drawTrack(canvas);
|
||||
|
||||
painter.drawTrack(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
-4
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.MockPath;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
/**
|
||||
@@ -45,8 +43,6 @@ public class TrackPathDescriptorFixedSpeedTest extends TrackPathPainterTestCase
|
||||
painter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, alwaysVisible,
|
||||
myTracksOverlay.getPoints());
|
||||
assertNotNull(myTracksOverlay.getLastPath());
|
||||
assertTrue(myTracksOverlay.getLastPath() instanceof MockPath);
|
||||
painter.drawTrack(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -16,7 +16,6 @@
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MockPath;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.content.Context;
|
||||
@@ -57,8 +56,8 @@ public class TrackPathPainterFactoryTest extends TrackPathPainterTestCase {
|
||||
|
||||
private <T> void testTrackPathPainterFactorySpecific(Context context, SharedPreferences prefs,
|
||||
int track_color_mode, Class <?> c) {
|
||||
prefs.edit().putString(context.getString(track_color_mode),
|
||||
context.getString(R.string.track_color_mode_key)).commit();
|
||||
prefs.edit().putString(context.getString(R.string.track_color_mode_key),
|
||||
context.getString(track_color_mode)).commit();
|
||||
|
||||
int startLocationIdx = 0;
|
||||
Boolean alwaysVisible = true;
|
||||
@@ -71,8 +70,6 @@ public class TrackPathPainterFactoryTest extends TrackPathPainterTestCase {
|
||||
painter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, alwaysVisible,
|
||||
myTracksOverlay.getPoints());
|
||||
assertNotNull(myTracksOverlay.getLastPath());
|
||||
assertTrue(myTracksOverlay.getLastPath() instanceof MockPath);
|
||||
painter.drawTrack(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
-4
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks.maps;
|
||||
|
||||
import com.google.android.apps.mytracks.MockPath;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
/**
|
||||
@@ -45,8 +43,6 @@ public class TrackPathPainterSingleColorTest extends TrackPathPainterTestCase {
|
||||
painter.updatePath(myTracksOverlay.getMapProjection(mockView),
|
||||
myTracksOverlay.getMapViewRect(mockView), startLocationIdx, alwaysVisible,
|
||||
myTracksOverlay.getPoints());
|
||||
assertNotNull(myTracksOverlay.getLastPath());
|
||||
assertTrue(myTracksOverlay.getLastPath() instanceof MockPath);
|
||||
painter.drawTrack(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
+22
-17
@@ -18,8 +18,10 @@ package com.google.android.apps.mytracks.services;
|
||||
import static com.google.android.apps.mytracks.Constants.RESUME_TRACK_EXTRA_NAME;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.content.DatabaseProvider;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProvider;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtilsFactory;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
@@ -144,12 +146,18 @@ public class TrackRecordingServiceTest
|
||||
RenamingDelegatingContext targetContext = new RenamingDelegatingContext(
|
||||
getContext(), getContext(), "test.");
|
||||
context = new MockContext(mockContentResolver, targetContext);
|
||||
MyTracksProvider provider = new MyTracksProvider();
|
||||
provider.attachInfo(context, null);
|
||||
mockContentResolver.addProvider(MyTracksProviderUtils.AUTHORITY, provider);
|
||||
|
||||
MyTracksProvider myTracksProvider = new MyTracksProvider();
|
||||
myTracksProvider.attachInfo(context, null);
|
||||
mockContentResolver.addProvider(MyTracksProviderUtils.AUTHORITY, myTracksProvider);
|
||||
|
||||
DatabaseProvider databaseProvider = new DatabaseProvider();
|
||||
databaseProvider.attachInfo(context, null);
|
||||
mockContentResolver.addProvider(MyTracksProviderUtils.DATABASE_AUTHORITY, databaseProvider);
|
||||
|
||||
setContext(context);
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(context);
|
||||
providerUtils = MyTracksProviderUtilsFactory.get(context);
|
||||
|
||||
sharedPreferences = context.getSharedPreferences(
|
||||
Constants.SETTINGS_NAME, 0);
|
||||
@@ -405,12 +413,10 @@ public class TrackRecordingServiceTest
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertTrue(service.isRecording());
|
||||
|
||||
try {
|
||||
service.startNewTrack();
|
||||
fail("Expecting IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
// Expected.
|
||||
}
|
||||
// Starting a new track again should just return -1.
|
||||
long newTrack = service.startNewTrack();
|
||||
assertEquals(-1L, newTrack);
|
||||
|
||||
assertEquals(123, sharedPreferences.getLong(
|
||||
context.getString(R.string.recording_track_key), 0));
|
||||
assertEquals(123, service.getRecordingTrackId());
|
||||
@@ -452,13 +458,12 @@ public class TrackRecordingServiceTest
|
||||
ITrackRecordingService service = bindAndGetService(createStartIntent());
|
||||
assertFalse(service.isRecording());
|
||||
|
||||
// End the current track.
|
||||
try {
|
||||
service.endCurrentTrack();
|
||||
fail("Expecting IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
// Expected.
|
||||
}
|
||||
/*
|
||||
* Ending the current track when no track is been recording should not cause
|
||||
* any error.
|
||||
*/
|
||||
service.endCurrentTrack();
|
||||
|
||||
assertEquals(-1, sharedPreferences.getLong(
|
||||
context.getString(R.string.recording_track_key), 0));
|
||||
assertEquals(-1, service.getRecordingTrackId());
|
||||
|
||||
Reference in New Issue
Block a user