diff --git a/MyTracks/res/values/keys.xml b/MyTracks/res/values/keys.xml
index 86cbcb607..c723f4dc3 100644
--- a/MyTracks/res/values/keys.xml
+++ b/MyTracks/res/values/keys.xml
@@ -71,8 +71,6 @@ limitations under the License.
weight
settingsAdvanced
- settingsBackup
- settingsBackupReset
settingsChart
settingsGoogle
settingsMap
@@ -81,7 +79,6 @@ limitations under the License.
settingsMapSlowDisplay
settingsRecording
settingsReset
- settingsRestore
settingsSensor
settingsSensorAnt
settingsSensorAntResetBikeCadenceSensor
diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml
index 976943771..3abc31118 100644
--- a/MyTracks/res/values/strings.xml
+++ b/MyTracks/res/values/strings.xml
@@ -1551,100 +1551,6 @@ limitations under the License.
Photo size
-
-
- Backup & reset
-
-
-
-
- Backup
-
-
- This will write a full copy of all your tracks and settings to ‘%1$s’ on the
- external storage.
-
-
- Backup now?
-
-
- Unable to backup.
-
-
- Writing all tracks and settings…
-
-
- Finished backup.
-
-
-
-
- Restore
-
-
- Restoring a backup from external storage will delete all your tracks and settings, and update
- them with the backup copy. Google Drive sync will be turned off. No tracks will be deleted on
- Google Drive and on external storage.
-
-
- Restore now?
-
-
- Unable to restore from backup.
-
-
- No backups found in %1$s.
-
-
- Reading all tracks and settings…
-
-
- Select a backup to restore
-
-
- Finished restoring from backup.
-
-
+
\ No newline at end of file
diff --git a/MyTracks/res/xml/backup_reset_settings.xml b/MyTracks/res/xml/backup_reset_settings.xml
deleted file mode 100644
index fb61ac08b..000000000
--- a/MyTracks/res/xml/backup_reset_settings.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/MyTracks/res/xml/settings.xml b/MyTracks/res/xml/settings.xml
index d820c79e9..8f830cbc2 100644
--- a/MyTracks/res/xml/settings.xml
+++ b/MyTracks/res/xml/settings.xml
@@ -40,10 +40,6 @@ limitations under the License.
android:key="@string/settings_sensor_key"
android:persistent="false"
android:title="@string/settings_sensor" />
-
{
-
- private static final String TAG = BackupAsyncTask.class.getSimpleName();
-
- private BackupActivity backupActivity;
- private final ExternalFileBackup externalFileBackup;
-
- // true if the AsyncTask result is success
- private boolean success;
-
- // true if the AsyncTask has completed
- private boolean completed;
-
- // message id to return to the activity
- private int messageId;
-
- /**
- * Creates an AsyncTask.
- *
- * @param backupActivity the activity currently associated with this
- * AsyncTask
- */
- public BackupAsyncTask(BackupActivity backupActivity) {
- this.backupActivity = backupActivity;
- this.externalFileBackup = new ExternalFileBackup(backupActivity);
- success = false;
- completed = false;
- messageId = R.string.settings_backup_now_error;
- }
-
- /**
- * Sets the current {@link BackupActivity} associated with this AyncTask.
- *
- * @param activity the current {@link BackupActivity}, can be null
- */
- public void setActivity(BackupActivity activity) {
- this.backupActivity = activity;
- if (completed && backupActivity != null) {
- backupActivity.onAsyncTaskCompleted(success, messageId);
- }
- }
-
- @Override
- protected void onPreExecute() {
- if (backupActivity != null) {
- backupActivity.showProgressDialog();
- }
- }
-
- @Override
- protected Boolean doInBackground(Void... params) {
- if (!FileUtils.isExternalStorageWriteable()) {
- messageId = R.string.external_storage_not_writable;
- return false;
- }
-
- if (!externalFileBackup.isBackupsDirectoryAvailable(true)) {
- messageId = R.string.external_storage_not_writable;
- return false;
- }
-
- try {
- externalFileBackup.writeToDefaultFile();
- messageId = R.string.settings_backup_now_success;
- return true;
- } catch (IOException e) {
- Log.d(TAG, "IO exception", e);
- return false;
- }
- }
-
- @Override
- protected void onPostExecute(Boolean result) {
- success = result;
- completed = true;
- if (backupActivity != null) {
- backupActivity.onAsyncTaskCompleted(success, messageId);
- }
- }
-}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/DatabaseDumper.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/DatabaseDumper.java
deleted file mode 100644
index f6ce5080e..000000000
--- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/DatabaseDumper.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright 2010 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.io.backup;
-
-import com.google.android.apps.mytracks.content.ContentTypeIds;
-
-import android.database.Cursor;
-import android.database.MergeCursor;
-
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-/**
- * Database dumper which is able to write only part of the database
- * according to some query.
- *
- * This dumper is symmetrical to {@link DatabaseImporter}.
- *
- * @author Rodrigo Damazio
- */
-class DatabaseDumper {
-
- /** The names of the columns being dumped. */
- private final String[] columnNames;
- /** The types of the columns being dumped. */
- private final byte[] columnTypes;
- /** Whether to output null fields. */
- private final boolean outputNullFields;
-
- // Temporary state
- private int[] columnIndices;
- private boolean[] hasFields;
-
- public DatabaseDumper(String[] columnNames, byte[] columnTypes,
- boolean outputNullFields) {
- if (columnNames.length != columnTypes.length) {
- throw new IllegalArgumentException("Names don't match types");
- }
-
- this.columnNames = columnNames;
- this.columnTypes = columnTypes;
- this.outputNullFields = outputNullFields;
- }
-
- /**
- * Writes the header plus all rows that can be read from the given cursor.
- * This assumes the cursor will have the same column and column indices on
- * every row (and thus may not work with a {@link MergeCursor}).
- */
- public void writeAllRows(Cursor cursor, DataOutputStream writer)
- throws IOException {
- writeHeaders(cursor, cursor.getCount(), writer);
-
- if (!cursor.moveToFirst()) {
- return;
- }
-
- do {
- writeOneRow(cursor, writer);
- } while (cursor.moveToNext());
- }
-
- /**
- * Writes just the headers for the data that will come from the given cursor.
- * The headers include column information and the number of rows that will be
- * written.
- *
- * @param cursor the cursor to get columns from
- * @param numRows the number of rows that will be later written
- * @param writer the output to write to
- * @throws IOException if there are errors while writing
- */
- public void writeHeaders(Cursor cursor, int numRows, DataOutputStream writer)
- throws IOException {
- initializeCachedValues(cursor);
- writeQueryMetadata(numRows, writer);
- }
-
- /**
- * Writes the current row from the cursor. The cursor is not advanced.
- * This must be called after {@link #writeHeaders}.
- *
- * @param cursor the cursor to write data from
- * @param writer the output to write to
- * @throws IOException if there are any errors while writing
- */
- public void writeOneRow(Cursor cursor, DataOutputStream writer)
- throws IOException {
- if (columnIndices == null) {
- throw new IllegalStateException(
- "Cannot write rows before writing the header");
- }
-
- if (columnIndices.length > Long.SIZE) {
- throw new IllegalArgumentException("Too many fields");
- }
-
- // Build a bitmap of which fields are present
- long fields = 0;
- for (int i = 0; i < columnIndices.length; i++) {
- hasFields[i] = !cursor.isNull(columnIndices[i]);
- fields |= (hasFields[i] ? 1 : 0) << i;
- }
- writer.writeLong(fields);
-
- // Actually write the present fields
- for (int i = 0; i < columnIndices.length; i++) {
- if (hasFields[i]) {
- writeCell(columnIndices[i], columnTypes[i], cursor, writer);
- } else if (outputNullFields) {
- writeDummyCell(columnTypes[i], writer);
- }
- }
- }
-
- /**
- * Initializes the column indices and other temporary state for reading from
- * the given cursor.
- */
- private void initializeCachedValues(Cursor cursor) {
- // These indices are constant for every row (unless we're fed a MergeCursor)
- if (cursor instanceof MergeCursor) {
- throw new IllegalArgumentException("Cannot use a MergeCursor");
- }
-
- columnIndices = new int[columnNames.length];
- for (int i = 0; i < columnNames.length; i++) {
- String columnName = columnNames[i];
- columnIndices[i] = cursor.getColumnIndexOrThrow(columnName);
- }
-
- hasFields = new boolean[columnIndices.length];
- }
-
- /**
- * Writes metadata about the query to be dumped.
- *
- * @param numRows the number of rows that will be dumped
- * @param writer the output to write to
- * @throws IOException if there are any errors while writing
- */
- private void writeQueryMetadata(
- int numRows, DataOutputStream writer) throws IOException {
- // Write column data
- writer.writeInt(columnNames.length);
- for (int i = 0; i < columnNames.length; i++) {
- String columnName = columnNames[i];
- byte columnType = columnTypes[i];
- writer.writeUTF(columnName);
- writer.writeByte(columnType);
- }
-
- // Write the number of rows
- writer.writeInt(numRows);
- }
-
- /**
- * Writes a single cell of the database to the output.
- *
- * @param columnIdx the column index to read from
- * @param columnTypeId the type of the column to be read
- * @param cursor the cursor to read from
- * @param writer the output to write to
- * @throws IOException if there are any errors while writing
- */
- private void writeCell(
- int columnIdx, byte columnTypeId, Cursor cursor, DataOutputStream writer)
- throws IOException {
- switch (columnTypeId) {
- case ContentTypeIds.LONG_TYPE_ID:
- writer.writeLong(cursor.getLong(columnIdx));
- return;
- case ContentTypeIds.DOUBLE_TYPE_ID:
- writer.writeDouble(cursor.getDouble(columnIdx));
- return;
- case ContentTypeIds.FLOAT_TYPE_ID:
- writer.writeFloat(cursor.getFloat(columnIdx));
- return;
- case ContentTypeIds.BOOLEAN_TYPE_ID:
- writer.writeBoolean(cursor.getInt(columnIdx) != 0);
- return;
- case ContentTypeIds.INT_TYPE_ID:
- writer.writeInt(cursor.getInt(columnIdx));
- return;
- case ContentTypeIds.STRING_TYPE_ID:
- writer.writeUTF(cursor.getString(columnIdx));
- return;
- case ContentTypeIds.BLOB_TYPE_ID: {
- byte[] blob = cursor.getBlob(columnIdx);
- writer.writeInt(blob.length);
- writer.write(blob);
- return;
- }
- default:
- throw new IllegalArgumentException(
- "Type " + columnTypeId + " not supported");
- }
- }
-
- /**
- * Writes a dummy cell value to the output.
- *
- * @param columnTypeId the type of the value to write
- * @throws IOException if there are any errors while writing
- */
- private void writeDummyCell(byte columnTypeId, DataOutputStream writer)
- throws IOException {
- switch (columnTypeId) {
- case ContentTypeIds.LONG_TYPE_ID:
- writer.writeLong(0L);
- return;
- case ContentTypeIds.DOUBLE_TYPE_ID:
- writer.writeDouble(0.0);
- return;
- case ContentTypeIds.FLOAT_TYPE_ID:
- writer.writeFloat(0.0f);
- return;
- case ContentTypeIds.BOOLEAN_TYPE_ID:
- writer.writeBoolean(false);
- return;
- case ContentTypeIds.INT_TYPE_ID:
- writer.writeInt(0);
- return;
- case ContentTypeIds.STRING_TYPE_ID:
- writer.writeUTF("");
- return;
- case ContentTypeIds.BLOB_TYPE_ID:
- writer.writeInt(0);
- return;
- default:
- throw new IllegalArgumentException(
- "Type " + columnTypeId + " not supported");
- }
- }
-}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/DatabaseImporter.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/DatabaseImporter.java
deleted file mode 100644
index 949963d5f..000000000
--- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/DatabaseImporter.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright 2010 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.io.backup;
-
-import com.google.android.apps.mytracks.content.ContentTypeIds;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.net.Uri;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.Locale;
-
-/**
- * Database importer which reads values written by {@link DatabaseDumper}.
- *
- * @author Rodrigo Damazio
- */
-public class DatabaseImporter {
-
- /** Maximum number of entries in a bulk insertion */
- private static final int DEFAULT_BULK_SIZE = 1024;
-
- private final Uri destinationUri;
- private final ContentResolver resolver;
- private final boolean readNullFields;
- private final int bulkSize;
-
- // Metadata read from the reader
- private String[] columnNames;
- private byte[] columnTypes;
-
- public DatabaseImporter(Uri destinationUri, ContentResolver resolver,
- boolean readNullFields) {
- this(destinationUri, resolver, readNullFields, DEFAULT_BULK_SIZE);
- }
-
- protected DatabaseImporter(Uri destinationUri, ContentResolver resolver,
- boolean readNullFields, int bulkSize) {
- this.destinationUri = destinationUri;
- this.resolver = resolver;
- this.readNullFields = readNullFields;
- this.bulkSize = bulkSize;
- }
-
- /**
- * Reads the header which includes metadata about the table being imported.
- *
- * @throws IOException if there are any problems while reading
- */
- private void readHeaders(DataInputStream reader) throws IOException {
- int numColumns = reader.readInt();
- columnNames = new String[numColumns];
- columnTypes = new byte[numColumns];
- for (int i = 0; i < numColumns; i++) {
- columnNames[i] = reader.readUTF();
- columnTypes[i] = reader.readByte();
- }
- }
-
- /**
- * Imports all rows from the reader into the database.
- * Insertion is done in bulks for efficiency.
- *
- * @throws IOException if there are any errors while reading
- */
- public void importAllRows(DataInputStream reader) throws IOException {
- readHeaders(reader);
-
- ContentValues[] valueBulk = new ContentValues[bulkSize];
- int numValues = 0;
-
- int numRows = reader.readInt();
- int numColumns = columnNames.length;
-
- // For each row
- for (int r = 0; r < numRows; r++) {
- if (valueBulk[numValues] == null) {
- valueBulk[numValues] = new ContentValues(numColumns);
- } else {
- // Reuse values objects
- valueBulk[numValues].clear();
- }
-
- // Read the fields bitmap
- long fields = reader.readLong();
- for (int c = 0; c < numColumns; c++) {
- if ((fields & 1) == 1) {
- // Field is present, read into values
- readOneCell(columnNames[c], columnTypes[c], valueBulk[numValues],
- reader);
- } else if (readNullFields) {
- // Field not present but still written, read and discard
- readOneCell(columnNames[c], columnTypes[c], null, reader);
- }
-
- fields >>= 1;
- }
-
- numValues++;
-
- // If we have enough values, flush them as a bulk insertion
- if (numValues >= bulkSize) {
- doBulkInsert(valueBulk);
- numValues = 0;
- }
- }
-
- // Do a final bulk insert with the leftovers
- if (numValues > 0) {
- ContentValues[] leftovers = new ContentValues[numValues];
- System.arraycopy(valueBulk, 0, leftovers, 0, numValues);
- doBulkInsert(leftovers);
- }
- }
-
- protected void doBulkInsert(ContentValues[] values) {
- resolver.bulkInsert(destinationUri, values);
- }
-
- /**
- * Reads a single cell from the reader.
- *
- * @param name the name of the column to be read
- * @param typeId the type ID of the column to be read
- * @param values the {@link ContentValues} object to put the read cell value
- * in - if null, the value is just discarded
- * @throws IOException if there are any problems while reading
- */
- private void readOneCell(String name, byte typeId, ContentValues values,
- DataInputStream reader) throws IOException {
- switch (typeId) {
- case ContentTypeIds.BOOLEAN_TYPE_ID: {
- boolean value = reader.readBoolean();
- if (values != null) { values.put(name, value); }
- return;
- }
- case ContentTypeIds.LONG_TYPE_ID: {
- long value = reader.readLong();
- if (values != null) { values.put(name, value); }
- return;
- }
- case ContentTypeIds.DOUBLE_TYPE_ID: {
- double value = reader.readDouble();
- if (values != null) { values.put(name, value); }
- return;
- }
- case ContentTypeIds.FLOAT_TYPE_ID: {
- Float value = reader.readFloat();
- if (values != null) { values.put(name, value); }
- return;
- }
- case ContentTypeIds.INT_TYPE_ID: {
- int value = reader.readInt();
- if (values != null) { values.put(name, value); }
- return;
- }
- case ContentTypeIds.STRING_TYPE_ID: {
- String value = reader.readUTF();
- if (values != null) { values.put(name, value); }
- return;
- }
- case ContentTypeIds.BLOB_TYPE_ID: {
- int blobLength = reader.readInt();
- if (blobLength != 0) {
- byte[] blob = new byte[blobLength];
- int readBytes = reader.read(blob, 0, blobLength);
- if (readBytes != blobLength) {
- throw new IOException(String.format(Locale.US,
- "Short read on column %s; expected %d bytes, read %d",
- name, blobLength, readBytes));
- }
-
- if (values != null) {
- values.put(name, blob);
- }
- }
- return;
- }
- default:
- throw new IOException("Read unknown type " + typeId);
- }
- }
-}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/ExternalFileBackup.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/ExternalFileBackup.java
deleted file mode 100644
index 35c261bdd..000000000
--- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/ExternalFileBackup.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright 2010 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.io.backup;
-
-import com.google.android.apps.mytracks.Constants;
-import com.google.android.apps.mytracks.content.TrackPointsColumns;
-import com.google.android.apps.mytracks.content.TracksColumns;
-import com.google.android.apps.mytracks.content.WaypointsColumns;
-import com.google.android.apps.mytracks.util.FileUtils;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.util.Log;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.TimeZone;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipOutputStream;
-
-/**
- * Handler for writing or reading single-file backups.
- *
- * @author Rodrigo Damazio
- */
-class ExternalFileBackup {
-
- private static final String TAG = ExternalFileBackup.class.getSimpleName();
-
- // Filename format - in UTC
- private static final SimpleDateFormat BACKUP_FILENAME_FORMAT = new SimpleDateFormat(
- "'backup-'yyyy-MM-dd_HH-mm-ss'.zip'", Locale.US);
- static {
- BACKUP_FILENAME_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
- }
-
- private static final int BACKUP_FORMAT_VERSION = 1;
- private static final String ZIP_ENTRY_NAME =
- "backup.mytracks.v" + BACKUP_FORMAT_VERSION;
- private static final int COMPRESSION_LEVEL = 8;
-
- private final Context context;
-
- public ExternalFileBackup(Context context) {
- this.context = context;
- }
-
- /**
- * Returns whether the backups directory is (or can be made) available.
- *
- * @param create whether to try creating the directory if it doesn't exist
- */
- public boolean isBackupsDirectoryAvailable(boolean create) {
- return getBackupsDirectory(create) != null;
- }
-
- /**
- * Returns the backup directory, or null if not available.
- *
- * @param create whether to try creating the directory if it doesn't exist
- */
- private File getBackupsDirectory(boolean create) {
- String directoryPath = FileUtils.getPath(FileUtils.BACKUPS_DIR);
- final File dir = new File(directoryPath);
- Log.d(TAG, "Dir: " + dir.getAbsolutePath());
- if (create) {
- // Try to create - if that fails, return null
- return FileUtils.ensureDirectoryExists(dir) ? dir : null;
- } else {
- // Return it if it already exists, otherwise return null
- return FileUtils.isDirectory(dir) ? dir : null;
- }
- }
-
- /**
- * Returns a list of available backups to be restored.
- */
- public Date[] getAvailableBackups() {
- File dir = getBackupsDirectory(false);
- if (dir == null) { return null; }
- String[] fileNames = dir.list();
-
- List backupDates = new ArrayList(fileNames.length);
- for (int i = 0; i < fileNames.length; i++) {
- String fileName = fileNames[i];
- try {
- backupDates.add(BACKUP_FILENAME_FORMAT.parse(fileName));
- } catch (ParseException e) {
- // Not a backup file, ignore
- }
- }
-
- return backupDates.toArray(new Date[backupDates.size()]);
- }
-
- /**
- * Writes the backup to the default file.
- */
- public void writeToDefaultFile() throws IOException {
- writeToFile(getFileForDate(new Date()));
- }
-
- /**
- * Restores the backup from the given date.
- */
- public void restoreFromDate(Date when) throws IOException {
- restoreFromFile(getFileForDate(when));
- }
-
- /**
- * Produces the proper file descriptor for the given backup date.
- */
- private File getFileForDate(Date when) {
- File dir = getBackupsDirectory(false);
- String fileName = BACKUP_FILENAME_FORMAT.format(when);
- File file = new File(dir, fileName);
- return file;
- }
-
- /**
- * Synchronously writes a backup to the given file.
- */
- private void writeToFile(File outputFile) throws IOException {
- Log.d(TAG, "Writing backup to file " + outputFile.getAbsolutePath());
-
- // Create all the auxiliary classes that will do the writing
- PreferenceBackupHelper preferencesHelper = new PreferenceBackupHelper(context);
- DatabaseDumper trackDumper = new DatabaseDumper(
- TracksColumns.COLUMNS,
- TracksColumns.COLUMN_TYPES,
- false);
- DatabaseDumper waypointDumper = new DatabaseDumper(
- WaypointsColumns.COLUMNS,
- WaypointsColumns.COLUMN_TYPES,
- false);
- DatabaseDumper pointDumper = new DatabaseDumper(
- TrackPointsColumns.COLUMNS,
- TrackPointsColumns.COLUMN_TYPES,
- false);
-
- // Open the target for writing
- FileOutputStream outputStream = new FileOutputStream(outputFile);
- ZipOutputStream compressedStream = new ZipOutputStream(outputStream);
- compressedStream.setLevel(COMPRESSION_LEVEL);
- compressedStream.putNextEntry(new ZipEntry(ZIP_ENTRY_NAME));
- DataOutputStream outWriter = new DataOutputStream(compressedStream);
-
- try {
- // Dump the entire contents of each table
- ContentResolver contentResolver = context.getContentResolver();
- Cursor tracksCursor = null;
- try {
- tracksCursor = contentResolver.query(TracksColumns.CONTENT_URI, null, null, null, null);
- if (tracksCursor != null) {
- trackDumper.writeAllRows(tracksCursor, outWriter);
- }
- } finally {
- if (tracksCursor != null) {
- tracksCursor.close();
- }
- }
-
- Cursor waypointsCursor = null;
- try {
- waypointsCursor = contentResolver.query(
- WaypointsColumns.CONTENT_URI, null, null, null, null);
- if (waypointsCursor != null) {
- waypointDumper.writeAllRows(waypointsCursor, outWriter);
- }
- } finally {
- if (waypointsCursor != null) {
- waypointsCursor.close();
- }
- }
-
- Cursor pointsCursor = null;
- try {
- pointsCursor = contentResolver.query(
- TrackPointsColumns.CONTENT_URI, null, null, null, null);
- if (pointsCursor != null) {
- pointDumper.writeAllRows(pointsCursor, outWriter);
- }
- } finally {
- if (pointsCursor != null) {
- pointsCursor.close();
- }
- }
-
- // Dump preferences
- SharedPreferences preferences = context.getSharedPreferences(
- Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
- preferencesHelper.exportPreferences(preferences, outWriter);
- } catch (IOException e) {
- // We tried to delete the partially created file, but do nothing
- // if that also fails.
- if (!outputFile.delete()) {
- Log.w(TAG, "Failed to delete file " + outputFile.getAbsolutePath());
- }
-
- throw e;
- } finally {
- compressedStream.closeEntry();
- compressedStream.close();
- }
- }
-
- /**
- * Synchronously restores the backup from the given file.
- */
- private void restoreFromFile(File inputFile) throws IOException {
- Log.d(TAG, "Restoring from file " + inputFile.getAbsolutePath());
-
- PreferenceBackupHelper preferencesHelper = new PreferenceBackupHelper(context);
- 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);
-
- ZipFile zipFile = new ZipFile(inputFile, ZipFile.OPEN_READ);
- ZipEntry zipEntry = zipFile.getEntry(ZIP_ENTRY_NAME);
- if (zipEntry == null) {
- throw new IOException("Invalid backup ZIP file");
- }
-
- InputStream compressedStream = zipFile.getInputStream(zipEntry);
- DataInputStream reader = new DataInputStream(compressedStream);
-
- 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);
-
- // Import the new contents of each table
- trackImporter.importAllRows(reader);
- waypointImporter.importAllRows(reader);
- pointImporter.importAllRows(reader);
-
- // Restore preferences
- SharedPreferences preferences = context.getSharedPreferences(
- Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
- preferencesHelper.importPreferences(reader, preferences);
- } finally {
- compressedStream.close();
- zipFile.close();
- }
- }
-}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreActivity.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreActivity.java
deleted file mode 100644
index 83bf7d02a..000000000
--- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreActivity.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 2012 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.io.backup;
-
-import com.google.android.apps.mytracks.TrackListActivity;
-import com.google.android.apps.mytracks.util.DialogUtils;
-import com.google.android.apps.mytracks.util.IntentUtils;
-import com.google.android.maps.mytracks.R;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.widget.Toast;
-
-import java.util.Date;
-
-/**
- * An activity to restore data from the SD card.
- *
- * @author Jimmy Shih
- */
-public class RestoreActivity extends Activity {
-
- public static final String EXTRA_DATE = "date";
-
- private static final String TAG = RestoreActivity.class.getSimpleName();
- private static final int DIALOG_PROGRESS_ID = 0;
-
- private RestoreAsyncTask restoreAsyncTask;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- Object retained = getLastNonConfigurationInstance();
- if (retained instanceof RestoreAsyncTask) {
- restoreAsyncTask = (RestoreAsyncTask) retained;
- restoreAsyncTask.setActivity(this);
- } else {
- long date = getIntent().getLongExtra(EXTRA_DATE, -1L);
- if (date == -1L) {
- Log.d(TAG, "Invalid date");
- finish();
- return;
- }
- restoreAsyncTask = new RestoreAsyncTask(this, new Date(date));
- restoreAsyncTask.execute();
- }
- }
-
- @Override
- public Object onRetainNonConfigurationInstance() {
- restoreAsyncTask.setActivity(null);
- return restoreAsyncTask;
- }
-
- @Override
- protected Dialog onCreateDialog(int id) {
- if (id != DIALOG_PROGRESS_ID) {
- return null;
- }
- return DialogUtils.createSpinnerProgressDialog(this,
- R.string.settings_backup_restore_progress_message, new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- finish();
- }
- });
- }
-
- /**
- * Invokes when the associated AsyncTask completes.
- *
- * @param success true if the AsyncTask is successful
- * @param messageId message id to display to user
- */
- public void onAsyncTaskCompleted(boolean success, int messageId) {
- removeDialog(DIALOG_PROGRESS_ID);
- Toast.makeText(this, messageId, success ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG).show();
- Intent intent = IntentUtils.newIntent(this, TrackListActivity.class);
- startActivity(intent);
- }
-
- /**
- * Shows the progress dialog.
- */
- public void showProgressDialog() {
- showDialog(DIALOG_PROGRESS_ID);
- }
-}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreAsyncTask.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreAsyncTask.java
deleted file mode 100644
index 586937e37..000000000
--- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreAsyncTask.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2012 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.io.backup;
-
-import com.google.android.apps.mytracks.io.sync.SyncUtils;
-import com.google.android.apps.mytracks.util.PreferencesUtils;
-import com.google.android.maps.mytracks.R;
-
-import android.os.AsyncTask;
-import android.util.Log;
-
-import java.io.IOException;
-import java.util.Date;
-
-/**
- * AsyncTask to restore data from the SD card.
- *
- * @author Jimmy Shih
- */
-public class RestoreAsyncTask extends AsyncTask {
-
- private static final String TAG = RestoreAsyncTask.class.getSimpleName();
-
- private RestoreActivity restoreActivity;
- private final Date date;
- private final ExternalFileBackup externalFileBackup;
-
- // true if the AsyncTask result is success
- private boolean success;
-
- // true if the AsyncTask has completed
- private boolean completed;
-
- // message id to return to the activity
- private int messageId;
-
- /**
- * Creates an AsyncTask.
- *
- * @param restoreActivity the activity currently associated with this
- * AsyncTask
- * @param date the date to retore from
- */
- public RestoreAsyncTask(RestoreActivity restoreActivity, Date date) {
- this.restoreActivity = restoreActivity;
- this.date = date;
- this.externalFileBackup = new ExternalFileBackup(restoreActivity);
- success = false;
- completed = false;
- messageId = R.string.settings_backup_restore_error;
- }
-
- /**
- * Sets the current {@link RestoreActivity} associated with this AyncTask.
- *
- * @param activity the current {@link RestoreActivity}, can be null
- */
- public void setActivity(RestoreActivity activity) {
- this.restoreActivity = activity;
- if (completed && restoreActivity != null) {
- restoreActivity.onAsyncTaskCompleted(success, messageId);
- }
- }
-
- @Override
- protected void onPreExecute() {
- if (restoreActivity != null) {
- restoreActivity.showProgressDialog();
- }
- }
-
- @Override
- protected Boolean doInBackground(Void... params) {
- try {
- PreferencesUtils.setBoolean(
- restoreActivity, R.string.drive_sync_key, PreferencesUtils.DRIVE_SYNC_DEFAULT);
- SyncUtils.disableSync(restoreActivity);
- externalFileBackup.restoreFromDate(date);
- SyncUtils.clearSyncState(restoreActivity);
- messageId = R.string.settings_backup_restore_success;
- return true;
- } catch (IOException e) {
- Log.d(TAG, "IO exception", e);
- return false;
- }
- }
-
- @Override
- protected void onPostExecute(Boolean result) {
- success = result;
- completed = true;
- if (restoreActivity != null) {
- restoreActivity.onAsyncTaskCompleted(success, messageId);
- }
- }
-}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreChooserActivity.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreChooserActivity.java
deleted file mode 100644
index 65d36a441..000000000
--- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/RestoreChooserActivity.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2012 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.io.backup;
-
-import com.google.android.apps.mytracks.util.DialogUtils;
-import com.google.android.apps.mytracks.util.FileUtils;
-import com.google.android.apps.mytracks.util.IntentUtils;
-import com.google.android.apps.mytracks.util.StringUtils;
-import com.google.android.maps.mytracks.R;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.os.Bundle;
-import android.widget.Toast;
-
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Date;
-
-/**
- * An activity to choose a date to restore from.
- *
- * @author Jimmy Shih
- */
-public class RestoreChooserActivity extends Activity {
-
- private static final Comparator REVERSE_DATE_ORDER = new Comparator() {
- @Override
- public int compare(Date s1, Date s2) {
- return s2.compareTo(s1);
- }
- };
- private static final int DIALOG_CHOOSER_ID = 0;
-
- private Date[] backupDates;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- ExternalFileBackup externalFileBackup = new ExternalFileBackup(this);
-
- // Get the list of existing backups
- if (!FileUtils.isExternalStorageAvailable()) {
- Toast.makeText(this, R.string.external_storage_not_available, Toast.LENGTH_LONG).show();
- finish();
- return;
- }
-
- if (!externalFileBackup.isBackupsDirectoryAvailable(false)) {
- showNoBackupMessage();
- finish();
- return;
- }
-
- backupDates = externalFileBackup.getAvailableBackups();
- if (backupDates == null || backupDates.length == 0) {
- showNoBackupMessage();
- finish();
- return;
- }
-
- if (backupDates.length == 1) {
- Intent intent = IntentUtils.newIntent(this, RestoreActivity.class)
- .putExtra(RestoreActivity.EXTRA_DATE, backupDates[0].getTime());
- startActivity(intent);
- finish();
- return;
- }
-
- Arrays.sort(backupDates, REVERSE_DATE_ORDER);
- showDialog(DIALOG_CHOOSER_ID);
- }
-
- @Override
- protected Dialog onCreateDialog(int id) {
- if (id != DIALOG_CHOOSER_ID) {
- return null;
- }
- String items[] = new String[backupDates.length];
- for (int i = 0; i < backupDates.length; i++) {
- items[i] = StringUtils.formatDateTime(this, backupDates[i].getTime());
- }
- final Dialog dialog = new AlertDialog.Builder(this).setCancelable(true)
- .setItems(items, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int which) {
- Intent intent = IntentUtils.newIntent(
- RestoreChooserActivity.this, RestoreActivity.class)
- .putExtra(RestoreActivity.EXTRA_DATE, backupDates[which].getTime());
- startActivity(intent);
- finish();
- }
- }).setOnCancelListener(new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialogInterface) {
- finish();
- }
- }).setTitle(R.string.settings_backup_restore_select_title).create();
- dialog.setOnShowListener(new DialogInterface.OnShowListener() {
-
- @Override
- public void onShow(DialogInterface dialogInterface) {
- DialogUtils.setDialogTitleDivider(RestoreChooserActivity.this, dialog);
- }
- });
- return dialog;
- }
-
- /**
- * Shows a no backup message.
- */
- private void showNoBackupMessage() {
- String message = getString(R.string.settings_backup_restore_no_backups,
- FileUtils.getPathDisplayName(FileUtils.BACKUPS_DIR));
- Toast.makeText(this, message, Toast.LENGTH_LONG).show();
- }
-}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/AdvancedSettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/AdvancedSettingsActivity.java
index 170345b23..0a4a265d0 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/settings/AdvancedSettingsActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/settings/AdvancedSettingsActivity.java
@@ -16,17 +16,26 @@
package com.google.android.apps.mytracks.settings;
+import com.google.android.apps.mytracks.Constants;
+import com.google.android.apps.mytracks.io.sync.SyncUtils;
import com.google.android.apps.mytracks.util.DialogUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R;
import android.app.Dialog;
+import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.util.Log;
+import android.widget.Toast;
/**
* An activity for advanced settings.
@@ -35,9 +44,38 @@ import android.preference.Preference.OnPreferenceChangeListener;
*/
public class AdvancedSettingsActivity extends AbstractSettingsActivity {
+ private static final String TAG = AdvancedSettingsActivity.class.getSimpleName();
+
private static final int DIALOG_CONFIRM_ALLOW_ACCESS_ID = 0;
+ private static final int DIALOG_CONFIRM_RESET_ID = 1;
private CheckBoxPreference allowAccessCheckBoxPreference;
+ private Preference resetPreference;
+
+ private SharedPreferences sharedPreferences;
+ private long recordingTrackId = PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
+
+ /*
+ * Note that sharedPreferenceChangeListenr cannot be an anonymous inner class.
+ * Anonymous inner class will get garbage collected.
+ */
+ private final OnSharedPreferenceChangeListener
+ sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() {
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
+ if (key != null && key.equals(PreferencesUtils.getKey(
+ AdvancedSettingsActivity.this, R.string.recording_track_id_key))) {
+ recordingTrackId = PreferencesUtils.getLong(
+ AdvancedSettingsActivity.this, R.string.recording_track_id_key);
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ updateUi();
+ }
+ });
+ }
+ }
+ };
@SuppressWarnings("deprecation")
@Override
@@ -45,20 +83,6 @@ public class AdvancedSettingsActivity extends AbstractSettingsActivity {
super.onCreate(bundle);
addPreferencesFromResource(R.xml.advanced_settings);
- allowAccessCheckBoxPreference = (CheckBoxPreference) findPreference(
- getString(R.string.allow_access_key));
- allowAccessCheckBoxPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if ((Boolean) newValue) {
- showDialog(DIALOG_CONFIRM_ALLOW_ACCESS_ID);
- return false;
- } else {
- return true;
- }
- }
- });
-
ListPreference preference = (ListPreference) findPreference(getString(R.string.photo_size_key));
int value = PreferencesUtils.getInt(
this, R.string.photo_size_key, PreferencesUtils.PHOTO_SIZE_DEFAULT);
@@ -67,22 +91,72 @@ public class AdvancedSettingsActivity extends AbstractSettingsActivity {
String[] summary = new String[values.length];
setPhotoSizeSummaryAndOptions(summary, options, values);
configureListPreference(preference, summary, options, values, String.valueOf(value), null);
+
+ allowAccessCheckBoxPreference = (CheckBoxPreference) findPreference(
+ getString(R.string.allow_access_key));
+ allowAccessCheckBoxPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object newValue) {
+ if ((Boolean) newValue) {
+ showDialog(DIALOG_CONFIRM_ALLOW_ACCESS_ID);
+ return false;
+ } else {
+ return true;
+ }
+ }
+ });
+
+ sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
+
+ resetPreference = findPreference(getString(R.string.settings_reset_key));
+ resetPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference arg0) {
+ showDialog(DIALOG_CONFIRM_RESET_ID);
+ return true;
+ }
+ });
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
+ recordingTrackId = PreferencesUtils.getLong(this, R.string.recording_track_id_key);
+ updateUi();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
}
@Override
protected Dialog onCreateDialog(int id) {
- if (id != DIALOG_CONFIRM_ALLOW_ACCESS_ID) {
- return null;
+ switch (id) {
+ case DIALOG_CONFIRM_ALLOW_ACCESS_ID:
+ return DialogUtils.createConfirmationDialog(this,
+ R.string.settings_sharing_allow_access_confirm_title,
+ getString(R.string.settings_sharing_allow_access_confirm_message),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int button) {
+ allowAccessCheckBoxPreference.setChecked(true);
+ }
+ });
+ case DIALOG_CONFIRM_RESET_ID:
+ return DialogUtils.createConfirmationDialog(this, R.string.settings_reset_confirm_title,
+ getString(R.string.settings_reset_confirm_message),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface d, int button) {
+ onResetPreferencesConfirmed();
+ }
+ });
+ default:
+ return null;
}
- return DialogUtils.createConfirmationDialog(this,
- R.string.settings_sharing_allow_access_confirm_title,
- getString(R.string.settings_sharing_allow_access_confirm_message),
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int button) {
- allowAccessCheckBoxPreference.setChecked(true);
- }
- });
}
private void setPhotoSizeSummaryAndOptions(String[] summary, String[] options, String[] values) {
@@ -101,4 +175,46 @@ public class AdvancedSettingsActivity extends AbstractSettingsActivity {
}
}
}
+
+ /**
+ * Updates the UI based on the recording state.
+ */
+ private void updateUi() {
+ boolean isRecording = recordingTrackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
+ resetPreference.setEnabled(!isRecording);
+ resetPreference.setSummary(isRecording ? getString(R.string.settings_not_while_recording) : "");
+ }
+
+ /**
+ * Callback when the user confirms resetting all settings.
+ */
+ private void onResetPreferencesConfirmed() {
+ // Change preferences in a separate thread
+ new Thread() {
+ @Override
+ public void run() {
+ Log.i(TAG, "Resetting all settings");
+
+ // Actually wipe preferences and save synchronously
+ sharedPreferences.edit().clear().commit();
+
+ SyncUtils.disableSync(AdvancedSettingsActivity.this);
+ SyncUtils.clearSyncState(AdvancedSettingsActivity.this);
+
+ // Give UI feedback in the UI thread
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Toast.makeText(
+ AdvancedSettingsActivity.this, R.string.settings_reset_done, Toast.LENGTH_SHORT)
+ .show();
+ // Restart the settings activity so all changes are loaded
+ Intent intent = getIntent()
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ }
+ });
+ }
+ }.start();
+ }
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/BackupResetSettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/BackupResetSettingsActivity.java
deleted file mode 100644
index 0046e3ff5..000000000
--- a/MyTracks/src/com/google/android/apps/mytracks/settings/BackupResetSettingsActivity.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright 2012 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.settings;
-
-import com.google.android.apps.mytracks.Constants;
-import com.google.android.apps.mytracks.io.backup.BackupActivity;
-import com.google.android.apps.mytracks.io.backup.RestoreChooserActivity;
-import com.google.android.apps.mytracks.io.sync.SyncUtils;
-import com.google.android.apps.mytracks.util.DialogUtils;
-import com.google.android.apps.mytracks.util.FileUtils;
-import com.google.android.apps.mytracks.util.IntentUtils;
-import com.google.android.apps.mytracks.util.PreferencesUtils;
-import com.google.android.maps.mytracks.R;
-
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
-import android.os.Bundle;
-import android.preference.Preference;
-import android.preference.Preference.OnPreferenceClickListener;
-import android.util.Log;
-import android.widget.Toast;
-
-/**
- * An activity for accessing the backup and reset settings.
- *
- * @author Jimmy Shih
- */
-public class BackupResetSettingsActivity extends AbstractSettingsActivity {
-
- private static final String TAG = BackupResetSettingsActivity.class.getSimpleName();
- private static final int DIALOG_CONFIRM_BACKUP_ID = 0;
- private static final int DIALOG_CONFIRM_RESTORE_ID = 1;
- private static final int DIALOG_CONFIRM_RESET_ID = 2;
-
- private SharedPreferences sharedPreferences;
- private Preference backupPreference;
- private Preference restoreNowPreference;
- private Preference resetPreference;
-
- private long recordingTrackId = PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
-
- /*
- * Note that sharedPreferenceChangeListenr cannot be an anonymous inner class.
- * Anonymous inner class will get garbage collected.
- */
- private final OnSharedPreferenceChangeListener
- sharedPreferenceChangeListener = new OnSharedPreferenceChangeListener() {
- @Override
- public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
- if (key != null && key.equals(PreferencesUtils.getKey(
- BackupResetSettingsActivity.this, R.string.recording_track_id_key))) {
- recordingTrackId = PreferencesUtils.getLong(
- BackupResetSettingsActivity.this, R.string.recording_track_id_key);
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- updateUi();
- }
- });
- }
- }
- };
-
- @SuppressWarnings("deprecation")
- @Override
- protected void onCreate(Bundle bundle) {
- super.onCreate(bundle);
- addPreferencesFromResource(R.xml.backup_reset_settings);
-
- sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
-
- backupPreference = findPreference(getString(R.string.settings_backup_key));
- backupPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- showDialog(DIALOG_CONFIRM_BACKUP_ID);
- return true;
- }
- });
- restoreNowPreference = findPreference(getString(R.string.settings_restore_key));
- restoreNowPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- showDialog(DIALOG_CONFIRM_RESTORE_ID);
- return true;
- }
- });
-
- resetPreference = findPreference(getString(R.string.settings_reset_key));
- resetPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference arg0) {
- showDialog(DIALOG_CONFIRM_RESET_ID);
- return true;
- }
- });
- }
-
- @Override
- protected Dialog onCreateDialog(int id) {
- String message;
- Dialog dialog;
- switch (id) {
- case DIALOG_CONFIRM_BACKUP_ID:
- message = getString(R.string.settings_backup_confirm_message,
- FileUtils.getPathDisplayName(FileUtils.BACKUPS_DIR));
- dialog = DialogUtils.createConfirmationDialog(this, R.string.settings_backup_confirm_title,
- message, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface d, int which) {
- Intent intent = IntentUtils.newIntent(
- BackupResetSettingsActivity.this, BackupActivity.class);
- startActivity(intent);
- }
- });
- break;
- case DIALOG_CONFIRM_RESTORE_ID:
- message = getString(R.string.settings_backup_restore_confirm_message);
- dialog = DialogUtils.createConfirmationDialog(this,
- R.string.settings_backup_restore_confirm_title, message,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface d, int which) {
- Intent intent = IntentUtils.newIntent(
- BackupResetSettingsActivity.this, RestoreChooserActivity.class);
- startActivity(intent);
- }
- });
- break;
- case DIALOG_CONFIRM_RESET_ID:
- message = getString(R.string.settings_reset_confirm_message);
- dialog = DialogUtils.createConfirmationDialog(this, R.string.settings_reset_confirm_title,
- message, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface d, int button) {
- onResetPreferencesConfirmed();
- }
- });
- break;
- default:
- dialog = null;
- }
- return dialog;
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
- recordingTrackId = PreferencesUtils.getLong(this, R.string.recording_track_id_key);
- updateUi();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
- }
-
- /**
- * Updates the UI based on the recording state.
- */
- private void updateUi() {
- boolean isRecording = recordingTrackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT;
- String summary = isRecording ? getString(R.string.settings_not_while_recording) : "";
- backupPreference.setEnabled(!isRecording);
- backupPreference.setSummary(summary);
- restoreNowPreference.setEnabled(!isRecording);
- restoreNowPreference.setSummary(summary);
- resetPreference.setEnabled(!isRecording);
- resetPreference.setSummary(summary);
- }
-
- /**
- * Callback when the user confirms resetting all settings.
- */
- private void onResetPreferencesConfirmed() {
- // Change preferences in a separate thread
- new Thread() {
- @Override
- public void run() {
- Log.i(TAG, "Resetting all settings");
-
- // Actually wipe preferences and save synchronously
- sharedPreferences.edit().clear().commit();
-
- SyncUtils.disableSync(BackupResetSettingsActivity.this);
- SyncUtils.clearSyncState(BackupResetSettingsActivity.this);
-
- // Give UI feedback in the UI thread
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(
- BackupResetSettingsActivity.this, R.string.settings_reset_done, Toast.LENGTH_SHORT)
- .show();
- // Restart the settings activity so all changes are loaded
- Intent intent = getIntent()
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(intent);
- }
- });
- }
- }.start();
- }
-}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java
index c3df05ace..35280417c 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java
@@ -44,7 +44,6 @@ public class SettingsActivity extends AbstractSettingsActivity {
configPreference(R.string.settings_stats_key, StatsSettingsActivity.class);
configPreference(R.string.settings_recording_key, RecordingSettingsActivity.class);
configPreference(R.string.settings_sensor_key, SensorSettingsActivity.class);
- configPreference(R.string.settings_backup_reset_key, BackupResetSettingsActivity.class);
configPreference(R.string.settings_advanced_key, AdvancedSettingsActivity.class);
}
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/DatabaseDumperTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/DatabaseDumperTest.java
deleted file mode 100644
index 2f74afb5c..000000000
--- a/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/DatabaseDumperTest.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright 2010 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.io.backup;
-
-import com.google.android.apps.mytracks.content.ContentTypeIds;
-
-import android.database.MatrixCursor;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for {@link DatabaseDumper}.
- *
- * @author Rodrigo Damazio
- */
-public class DatabaseDumperTest extends TestCase {
- /**
- * This class is the same as {@link MatrixCursor}, except this class
- * implements {@link #getBlob} ({@link MatrixCursor} leaves it
- * unimplemented).
- */
- private class BlobAwareMatrixCursor extends MatrixCursor {
- public BlobAwareMatrixCursor(String[] columnNames) {
- super(columnNames);
- }
-
- @Override public byte[] getBlob(int columnIndex) {
- return getString(columnIndex).getBytes();
- }
- }
-
- private static final String[] COLUMN_NAMES = {
- "intCol", "longCol", "floatCol", "doubleCol", "stringCol", "boolCol", "blobCol"
- };
- private static final byte[] COLUMN_TYPES = {
- ContentTypeIds.INT_TYPE_ID, ContentTypeIds.LONG_TYPE_ID,
- ContentTypeIds.FLOAT_TYPE_ID, ContentTypeIds.DOUBLE_TYPE_ID,
- ContentTypeIds.STRING_TYPE_ID, ContentTypeIds.BOOLEAN_TYPE_ID,
- ContentTypeIds.BLOB_TYPE_ID
- };
- private static final String[][] FAKE_DATA = {
- { "42", "123456789", "3.1415", "2.72", "lolcat", "1", "blob" },
- { null, "123456789", "3.1415", "2.72", "lolcat", "1", "blob" },
- { "42", null, "3.1415", "2.72", "lolcat", "1", "blob" },
- { "42", "123456789", null, "2.72", "lolcat", "1", "blob" },
- { "42", "123456789", "3.1415", null, "lolcat", "1", "blob" },
- { "42", "123456789", "3.1415", "2.72", null, "1", "blob" },
- { "42", "123456789", "3.1415", "2.72", "lolcat", null, "blob" },
- { "42", "123456789", "3.1415", "2.72", "lolcat", "1", null },
- };
- private static final long[] EXPECTED_FIELD_SETS = {
- 0x7F, 0x7E, 0x7D, 0x7B, 0x77, 0x6F, 0x5F, 0x3F
- };
-
- private BlobAwareMatrixCursor cursor;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- // Add fake data to the cursor
- cursor = new BlobAwareMatrixCursor(COLUMN_NAMES);
- for (String[] row : FAKE_DATA) {
- cursor.addRow(row);
- }
- }
-
- public void testWriteAllRows_noNulls() throws Exception {
- testWriteAllRows(false);
- }
-
- public void testWriteAllRows_withNulls() throws Exception {
- testWriteAllRows(true);
- }
-
- private void testWriteAllRows(boolean hasNullFields) throws Exception {
- // Dump it
- DatabaseDumper dumper = new DatabaseDumper(COLUMN_NAMES, COLUMN_TYPES, hasNullFields);
- ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);
- DataOutputStream writer = new DataOutputStream(outStream );
- dumper.writeAllRows(cursor, writer);
-
- // Read the results
- byte[] result = outStream.toByteArray();
- ByteArrayInputStream inputStream = new ByteArrayInputStream(result);
- DataInputStream reader = new DataInputStream(inputStream);
-
- // Verify the header
- assertHeader(reader);
-
- // Verify the number of rows
- assertEquals(FAKE_DATA.length, reader.readInt());
-
- // Row 0 -- everything populated
- assertEquals(EXPECTED_FIELD_SETS[0], reader.readLong());
- assertEquals(42, reader.readInt());
- assertEquals(123456789L, reader.readLong());
- assertEquals(3.1415f, reader.readFloat());
- assertEquals(2.72, reader.readDouble());
- assertEquals("lolcat", reader.readUTF());
- assertTrue(reader.readBoolean());
- assertEquals(4, reader.readInt());
- assertEquals("blob", readBlob(reader, 4));
-
- // Row 1 -- no int
- assertEquals(EXPECTED_FIELD_SETS[1], reader.readLong());
- if (hasNullFields) reader.readInt();
- assertEquals(123456789L, reader.readLong());
- assertEquals(3.1415f, reader.readFloat());
- assertEquals(2.72, reader.readDouble());
- assertEquals("lolcat", reader.readUTF());
- assertTrue(reader.readBoolean());
- assertEquals(4, reader.readInt());
- assertEquals("blob", readBlob(reader, 4));
-
- // Row 2 -- no long
- assertEquals(EXPECTED_FIELD_SETS[2], reader.readLong());
- assertEquals(42, reader.readInt());
- if (hasNullFields) reader.readLong();
- assertEquals(3.1415f, reader.readFloat());
- assertEquals(2.72, reader.readDouble());
- assertEquals("lolcat", reader.readUTF());
- assertTrue(reader.readBoolean());
- assertEquals(4, reader.readInt());
- assertEquals("blob", readBlob(reader, 4));
-
- // Row 3 -- no float
- assertEquals(EXPECTED_FIELD_SETS[3], reader.readLong());
- assertEquals(42, reader.readInt());
- assertEquals(123456789L, reader.readLong());
- if (hasNullFields) reader.readFloat();
- assertEquals(2.72, reader.readDouble());
- assertEquals("lolcat", reader.readUTF());
- assertTrue(reader.readBoolean());
- assertEquals(4, reader.readInt());
- assertEquals("blob", readBlob(reader, 4));
-
- // Row 4 -- no double
- assertEquals(EXPECTED_FIELD_SETS[4], reader.readLong());
- assertEquals(42, reader.readInt());
- assertEquals(123456789L, reader.readLong());
- assertEquals(3.1415f, reader.readFloat());
- if (hasNullFields) reader.readDouble();
- assertEquals("lolcat", reader.readUTF());
- assertTrue(reader.readBoolean());
- assertEquals(4, reader.readInt());
- assertEquals("blob", readBlob(reader, 4));
-
- // Row 5 -- no string
- assertEquals(EXPECTED_FIELD_SETS[5], reader.readLong());
- assertEquals(42, reader.readInt());
- assertEquals(123456789L, reader.readLong());
- assertEquals(3.1415f, reader.readFloat());
- assertEquals(2.72, reader.readDouble());
- if (hasNullFields) reader.readUTF();
- assertTrue(reader.readBoolean());
- assertEquals(4, reader.readInt());
- assertEquals("blob", readBlob(reader, 4));
-
- // Row 6 -- no boolean
- assertEquals(EXPECTED_FIELD_SETS[6], reader.readLong());
- assertEquals(42, reader.readInt());
- assertEquals(123456789L, reader.readLong());
- assertEquals(3.1415f, reader.readFloat());
- assertEquals(2.72, reader.readDouble());
- assertEquals("lolcat", reader.readUTF());
- if (hasNullFields) reader.readBoolean();
- assertEquals(4, reader.readInt());
- assertEquals("blob", readBlob(reader, 4));
-
- // Row 7 -- no blob
- assertEquals(EXPECTED_FIELD_SETS[7], reader.readLong());
- assertEquals(42, reader.readInt());
- assertEquals(123456789L, reader.readLong());
- assertEquals(3.1415f, reader.readFloat());
- assertEquals(2.72, reader.readDouble());
- assertEquals("lolcat", reader.readUTF());
- assertTrue(reader.readBoolean());
- if (hasNullFields) {
- int length = reader.readInt();
- readBlob(reader, length);
- }
- }
-
- public void testFewerRows() throws Exception {
- // Dump only the first two rows
- DatabaseDumper dumper = new DatabaseDumper(COLUMN_NAMES, COLUMN_TYPES, false);
- ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);
- DataOutputStream writer = new DataOutputStream(outStream);
-
- dumper.writeHeaders(cursor, 2, writer);
- cursor.moveToFirst();
- dumper.writeOneRow(cursor, writer);
- cursor.moveToNext();
- dumper.writeOneRow(cursor, writer);
-
- // Read the results
- byte[] result = outStream.toByteArray();
- ByteArrayInputStream inputStream = new ByteArrayInputStream(result);
- DataInputStream reader = new DataInputStream(inputStream);
-
- // Verify the header
- assertHeader(reader);
-
- // Verify the number of rows
- assertEquals(2, reader.readInt());
-
- // Row 0
- assertEquals(EXPECTED_FIELD_SETS[0], reader.readLong());
- assertEquals(42, reader.readInt());
- assertEquals(123456789L, reader.readLong());
- assertEquals(3.1415f, reader.readFloat());
- assertEquals(2.72, reader.readDouble());
- assertEquals("lolcat", reader.readUTF());
- assertTrue(reader.readBoolean());
- assertEquals(4, reader.readInt());
- assertEquals("blob", readBlob(reader, 4));
-
- // Row 1
- assertEquals(EXPECTED_FIELD_SETS[1], reader.readLong());
- // Null field not read
- assertEquals(123456789L, reader.readLong());
- assertEquals(3.1415f, reader.readFloat());
- assertEquals(2.72, reader.readDouble());
- assertEquals("lolcat", reader.readUTF());
- assertTrue(reader.readBoolean());
- assertEquals(4, reader.readInt());
- assertEquals("blob", readBlob(reader, 4));
- }
-
- private void assertHeader(DataInputStream reader) throws IOException {
- assertEquals(COLUMN_NAMES.length, reader.readInt());
- for (int i = 0; i < COLUMN_NAMES.length; i++) {
- assertEquals(COLUMN_NAMES[i], reader.readUTF());
- assertEquals(COLUMN_TYPES[i], reader.readByte());
- }
- }
-
- private String readBlob(InputStream reader, int length) throws Exception {
- if (length == 0) {
- return "";
- }
-
- byte[] blob = new byte[length];
- assertEquals(length, reader.read(blob));
- return new String(blob);
- }
-}
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/DatabaseImporterTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/DatabaseImporterTest.java
deleted file mode 100644
index 916af61d3..000000000
--- a/MyTracksTest/src/com/google/android/apps/mytracks/io/backup/DatabaseImporterTest.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright 2010 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.io.backup;
-
-import com.google.android.apps.mytracks.content.ContentTypeIds;
-
-import android.content.ContentValues;
-import android.net.Uri;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for {@link DatabaseImporter}.
- *
- * @author Rodrigo Damazio
- */
-public class DatabaseImporterTest extends TestCase {
-
- private static final Uri DESTINATION_URI = Uri.parse("http://www.google.com/");
- private static final int TEST_BULK_SIZE = 10;
- private ArrayList insertedValues;
-
- private class TestableDatabaseImporter extends DatabaseImporter {
- public TestableDatabaseImporter(boolean readNullFields) {
- super(DESTINATION_URI, null, readNullFields, TEST_BULK_SIZE);
- }
-
- @Override
- protected void doBulkInsert(ContentValues[] values) {
- insertedValues.ensureCapacity(insertedValues.size() + values.length);
-
- // We need to make a copy of the values since the objects are re-used
- for (ContentValues contentValues : values) {
- insertedValues.add(new ContentValues(contentValues));
- }
- }
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- insertedValues = new ArrayList();
- }
-
- public void testImportAllRows() throws Exception {
- testImportAllRows(false);
- }
-
- public void testImportAllRows_readNullFields() throws Exception {
- testImportAllRows(true);
- }
-
- private void testImportAllRows(boolean readNullFields) throws Exception {
- // Create a fake data stream to be read
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024);
- DataOutputStream writer = new DataOutputStream(outputStream);
-
- writeFullHeader(writer);
-
- // Add the number of rows
- writer.writeInt(2);
-
- // Add a row with all fields present
- writer.writeLong(0x7F);
- writer.writeInt(42);
- writer.writeBoolean(true);
- writer.writeUTF("lolcat");
- writer.writeFloat(3.1415f);
- writer.writeDouble(2.72);
- writer.writeLong(123456789L);
- writer.writeInt(4);
- writer.writeBytes("blob");
-
- // Add a row with some missing fields
- writer.writeLong(0x15);
- writer.writeInt(42);
- if (readNullFields) writer.writeBoolean(false);
- writer.writeUTF("lolcat");
- if (readNullFields) writer.writeFloat(0.0f);
- writer.writeDouble(2.72);
- if (readNullFields) writer.writeLong(0L);
- if (readNullFields) writer.writeInt(0); // empty blob
-
- writer.flush();
-
- // Do the importing
- DatabaseImporter importer = new TestableDatabaseImporter(readNullFields);
- byte[] dataBytes = outputStream.toByteArray();
- importer.importAllRows(new DataInputStream(new ByteArrayInputStream(dataBytes)));
-
- assertEquals(2, insertedValues.size());
-
- // Verify the first row
- ContentValues value = insertedValues.get(0);
- assertEquals(value.toString(), 7, value.size());
-
- assertValue(42, "col1", value);
- assertValue(true, "col2", value);
- assertValue("lolcat", "col3", value);
- assertValue(3.1415f, "col4", value);
- assertValue(2.72, "col5", value);
- assertValue(123456789L, "col6", value);
- assertBlobValue("blob", "col7", value);
-
- // Verify the second row
- value = insertedValues.get(1);
- assertEquals(value.toString(), 3, value.size());
-
- assertValue(42, "col1", value);
- assertValue("lolcat", "col3", value);
- assertValue(2.72, "col5", value);
- }
-
- public void testImportAllRows_noRows() throws Exception {
- // Create a fake data stream to be read
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024);
- DataOutputStream writer = new DataOutputStream(outputStream);
-
- writeFullHeader(writer);
-
- // Add the number of rows
- writer.writeInt(0);
-
- writer.flush();
-
- // Do the importing
- DatabaseImporter importer = new TestableDatabaseImporter(false);
- byte[] dataBytes = outputStream.toByteArray();
- importer.importAllRows(new DataInputStream(new ByteArrayInputStream(dataBytes)));
-
- assertTrue(insertedValues.isEmpty());
- }
-
- public void testImportAllRows_emptyRows() throws Exception {
- testImportAllRowsWithEmptyRows(false);
- }
-
- public void testImportAllRows_emptyRowsWithNulls() throws Exception {
- testImportAllRowsWithEmptyRows(true);
- }
-
- private void testImportAllRowsWithEmptyRows(boolean readNullFields) throws Exception {
- // Create a fake data stream to be read
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024);
- DataOutputStream writer = new DataOutputStream(outputStream);
-
- writeFullHeader(writer);
-
- // Add the number of rows
- writer.writeInt(3);
-
- // Add 2 rows with no fields
- for (int i = 0; i < 2; i++) {
- writer.writeLong(0);
- if (readNullFields) {
- writer.writeInt(0);
- writer.writeBoolean(false);
- writer.writeUTF("");
- writer.writeFloat(0.0f);
- writer.writeDouble(0.0);
- writer.writeLong(0L);
- writer.writeInt(0); // empty blob
- }
- }
-
- // Add a row with some missing fields
- writer.writeLong(0x15);
- writer.writeInt(42);
- if (readNullFields) writer.writeBoolean(false);
- writer.writeUTF("lolcat");
- if (readNullFields) writer.writeFloat(0.0f);
- writer.writeDouble(2.72);
- if (readNullFields) writer.writeLong(0L);
- if (readNullFields) writer.writeInt(0); // empty blob
-
- writer.flush();
-
- // Do the importing
- DatabaseImporter importer = new TestableDatabaseImporter(readNullFields);
- byte[] dataBytes = outputStream.toByteArray();
- importer.importAllRows(new DataInputStream(new ByteArrayInputStream(dataBytes)));
-
- assertEquals(insertedValues.toString(), 3, insertedValues.size());
-
- ContentValues value = insertedValues.get(0);
- assertEquals(value.toString(), 0, value.size());
-
- value = insertedValues.get(1);
- assertEquals(value.toString(), 0, value.size());
-
- // Verify the third row (only one with values)
- value = insertedValues.get(2);
- assertEquals(value.toString(), 3, value.size());
-
- assertFalse(value.containsKey("col2"));
- assertFalse(value.containsKey("col4"));
- assertFalse(value.containsKey("col6"));
-
- assertValue(42, "col1", value);
- assertValue("lolcat", "col3", value);
- assertValue(2.72, "col5", value);
- }
-
- public void testImportAllRows_bulks() throws Exception {
- // Create a fake data stream to be read
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024);
- DataOutputStream writer = new DataOutputStream(outputStream);
-
- // Add the header
- writer.writeInt(2);
- writer.writeUTF("col1");
- writer.writeByte(ContentTypeIds.INT_TYPE_ID);
- writer.writeUTF("col2");
- writer.writeByte(ContentTypeIds.STRING_TYPE_ID);
-
- // Add lots of rows (so the insertions are split in multiple bulks)
- int numRows = TEST_BULK_SIZE * 5 / 2;
- writer.writeInt(numRows);
- for (int i = 0; i < numRows; i++) {
- writer.writeLong(3);
- writer.writeInt(i);
- writer.writeUTF(Integer.toString(i * 2));
- }
-
- writer.flush();
-
- // Do the importing
- DatabaseImporter importer = new TestableDatabaseImporter(false);
- byte[] dataBytes = outputStream.toByteArray();
- importer.importAllRows(new DataInputStream(new ByteArrayInputStream(dataBytes)));
-
- // Verify the rows
- assertEquals(numRows, insertedValues.size());
- for (int i = 0; i < numRows; i++) {
- ContentValues value = insertedValues.get(i);
- assertEquals(value.toString(), 2, value.size());
- assertValue(i, "col1", value);
- assertValue(Integer.toString(i * 2), "col2", value);
- }
- }
-
- private void writeFullHeader(DataOutputStream writer) throws IOException {
- // Add the header
- writer.writeInt(7);
- writer.writeUTF("col1");
- writer.writeByte(ContentTypeIds.INT_TYPE_ID);
- writer.writeUTF("col2");
- writer.writeByte(ContentTypeIds.BOOLEAN_TYPE_ID);
- writer.writeUTF("col3");
- writer.writeByte(ContentTypeIds.STRING_TYPE_ID);
- writer.writeUTF("col4");
- writer.writeByte(ContentTypeIds.FLOAT_TYPE_ID);
- writer.writeUTF("col5");
- writer.writeByte(ContentTypeIds.DOUBLE_TYPE_ID);
- writer.writeUTF("col6");
- writer.writeByte(ContentTypeIds.LONG_TYPE_ID);
- writer.writeUTF("col7");
- writer.writeByte(ContentTypeIds.BLOB_TYPE_ID);
- }
-
- private void assertValue(T expectedValue, String name, ContentValues values) {
- @SuppressWarnings("unchecked")
- T value = (T) values.get(name);
- assertNotNull(value);
- assertEquals(expectedValue, value);
- }
-
- private void assertBlobValue(String expectedValue, String name, ContentValues values ){
- byte[] blob = values.getAsByteArray(name);
- assertEquals(expectedValue, new String(blob));
- }
-}
diff --git a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/common/SettingTest.java b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/common/SettingTest.java
index 332347ee1..2248bbf01 100644
--- a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/common/SettingTest.java
+++ b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/common/SettingTest.java
@@ -271,73 +271,6 @@ public class SettingTest extends ActivityInstrumentationTestCase2