diff --git a/MyTracks/.google_apis/drive-v2r30lv1.12.0-beta/drive/classpath-include b/MyTracks/.google_apis/drive-v2r30lv1.12.0-beta/drive/classpath-include index d2797b1e4..97fea11f4 100644 --- a/MyTracks/.google_apis/drive-v2r30lv1.12.0-beta/drive/classpath-include +++ b/MyTracks/.google_apis/drive-v2r30lv1.12.0-beta/drive/classpath-include @@ -17,7 +17,6 @@ - diff --git a/MyTracks/.google_apis/drive-v2r30lv1.12.0-beta/drive/descriptor.json b/MyTracks/.google_apis/drive-v2r30lv1.12.0-beta/drive/descriptor.json index 9ba628cdc..2733123f1 100644 --- a/MyTracks/.google_apis/drive-v2r30lv1.12.0-beta/drive/descriptor.json +++ b/MyTracks/.google_apis/drive-v2r30lv1.12.0-beta/drive/descriptor.json @@ -632,23 +632,6 @@ "generic" ] }, - { - "files": [ - { - "path": "libs/jsr305-1.3.9.jar", - "type": "binary" - }, - { - "path": "dependencies/APACHE-LICENSE.txt", - "type": "license" - } - ], - "version": "1.3.9", - "name": "JSR 305", - "environments": [ - "*" - ] - }, { "files": [ { diff --git a/MyTracks/.google_apis/drive-v2r30lv1.12.0-beta/drive/libs/jsr305-1.3.9.jar b/MyTracks/.google_apis/drive-v2r30lv1.12.0-beta/drive/libs/jsr305-1.3.9.jar deleted file mode 100644 index a9afc6619..000000000 Binary files a/MyTracks/.google_apis/drive-v2r30lv1.12.0-beta/drive/libs/jsr305-1.3.9.jar and /dev/null differ diff --git a/MyTracks/.google_apis/fusiontables-v1r16lv1.12.0-beta/fusiontables/classpath-include b/MyTracks/.google_apis/fusiontables-v1r16lv1.12.0-beta/fusiontables/classpath-include index d2797b1e4..97fea11f4 100644 --- a/MyTracks/.google_apis/fusiontables-v1r16lv1.12.0-beta/fusiontables/classpath-include +++ b/MyTracks/.google_apis/fusiontables-v1r16lv1.12.0-beta/fusiontables/classpath-include @@ -17,7 +17,6 @@ - diff --git a/MyTracks/.google_apis/fusiontables-v1r16lv1.12.0-beta/fusiontables/descriptor.json b/MyTracks/.google_apis/fusiontables-v1r16lv1.12.0-beta/fusiontables/descriptor.json index 67a607fba..fe8e5d8a0 100644 --- a/MyTracks/.google_apis/fusiontables-v1r16lv1.12.0-beta/fusiontables/descriptor.json +++ b/MyTracks/.google_apis/fusiontables-v1r16lv1.12.0-beta/fusiontables/descriptor.json @@ -632,23 +632,6 @@ "generic" ] }, - { - "files": [ - { - "path": "libs/jsr305-1.3.9.jar", - "type": "binary" - }, - { - "path": "dependencies/APACHE-LICENSE.txt", - "type": "license" - } - ], - "version": "1.3.9", - "name": "JSR 305", - "environments": [ - "*" - ] - }, { "files": [ { diff --git a/MyTracks/.google_apis/fusiontables-v1r16lv1.12.0-beta/fusiontables/libs/jsr305-1.3.9.jar b/MyTracks/.google_apis/fusiontables-v1r16lv1.12.0-beta/fusiontables/libs/jsr305-1.3.9.jar deleted file mode 100644 index a9afc6619..000000000 Binary files a/MyTracks/.google_apis/fusiontables-v1r16lv1.12.0-beta/fusiontables/libs/jsr305-1.3.9.jar and /dev/null differ diff --git a/MyTracks/.google_apis/gdata-spreadsheet-2.1/gdata-spreadsheet-3.0/google-collect-1.0-rc1.jar b/MyTracks/.google_apis/gdata-spreadsheet-2.1/gdata-spreadsheet-3.0/google-collect-1.0-rc1.jar deleted file mode 100644 index bc499eea6..000000000 Binary files a/MyTracks/.google_apis/gdata-spreadsheet-2.1/gdata-spreadsheet-3.0/google-collect-1.0-rc1.jar and /dev/null differ diff --git a/MyTracks/AndroidManifest.xml b/MyTracks/AndroidManifest.xml index 256113e91..55390026f 100755 --- a/MyTracks/AndroidManifest.xml +++ b/MyTracks/AndroidManifest.xml @@ -16,8 +16,8 @@ limitations under the License. --> @@ -93,7 +93,7 @@ limitations under the License. + android:targetSdkVersion="17" /> + \ No newline at end of file diff --git a/MyTracks/res/menu/track_list.xml b/MyTracks/res/menu/track_list.xml index 9f8034117..b95646da5 100644 --- a/MyTracks/res/menu/track_list.xml +++ b/MyTracks/res/menu/track_list.xml @@ -74,6 +74,10 @@ limitations under the License. android:icon="@drawable/menu_settings" android:id="@+id/track_list_settings" android:title="@string/menu_settings"/> + chartShowSpeed confirmPlayEarth confirmShareDrive - confirmShareMap + confirmShareMaps defaultActivity defaultMapPublic defaultTablePublic diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml index ec31ff01b..222d6b306 100644 --- a/MyTracks/res/values/strings.xml +++ b/MyTracks/res/values/strings.xml @@ -582,7 +582,7 @@ limitations under the License. By using Google\'s mobile products and services (“Services”), you agree to be bound by a) the YouTube Terms of Use (%1$s/tos_youtube) for YouTube-related Services, b) the Google Maps Terms and Conditions (%1$s/tos_maps) for mapping, local and location-based Services, c) the - Google Books Terms of Service (%1$s/tos_books) for Books-related Services, and e) the Google + Google Books Terms of Service (%1$s/tos_books) for Books-related Services, and d) the Google Terms of Service (%1$s/utos) for all other Services, as updated from time to time. External storage not available. - - External storage not writeable. + + External storage not writable. @@ -974,6 +974,12 @@ limitations under the License. Character limit: ~20 (1 line)"> Edit + + Feedback + + translation_description="When backing up to the external storage, the error message."> Unable to backup. Top medium speed - + - Resume a recording after reboot if the last recorded loation was within the last %1$s + Resume a recording after reboot if the last recorded location was within the last %1$s Date (local) @@ -2058,8 +2065,9 @@ limitations under the License. - Add emails + translation_description="The dialog title for entering email addresses for sharing a track + with."> + Share track with diff --git a/MyTracks/res/xml/track_widget_info.xml b/MyTracks/res/xml/track_widget_info.xml index 33f3feaf0..f6ede7b21 100644 --- a/MyTracks/res/xml/track_widget_info.xml +++ b/MyTracks/res/xml/track_widget_info.xml @@ -16,10 +16,12 @@ limitations under the License. --> + android:updatePeriodMillis="0" + android:widgetCategory="keyguard|home_screen" /> diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksApplication.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksApplication.java deleted file mode 100644 index 36d2043ff..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksApplication.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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; - -import com.google.android.apps.mytracks.services.RemoveTempFilesService; -import com.google.android.apps.mytracks.util.ApiAdapterFactory; -import com.google.android.maps.mytracks.BuildConfig; - -import android.app.Application; -import android.content.Intent; - -/** - * MyTracksApplication for keeping global state. - * - * @author Jimmy Shih - */ -public class MyTracksApplication extends Application { - - @Override - public void onCreate() { - super.onCreate(); - if (BuildConfig.DEBUG) { - ApiAdapterFactory.getApiAdapter().enableStrictMode(); - } - Intent intent = new Intent(this, RemoveTempFilesService.class); - startService(intent); - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/TrackDetailActivity.java b/MyTracks/src/com/google/android/apps/mytracks/TrackDetailActivity.java index c66403ce4..38695ae55 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/TrackDetailActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/TrackDetailActivity.java @@ -38,6 +38,7 @@ import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest; import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection; import com.google.android.apps.mytracks.settings.SettingsActivity; import com.google.android.apps.mytracks.util.AnalyticsUtils; +import com.google.android.apps.mytracks.util.GoogleFeedbackUtils; import com.google.android.apps.mytracks.util.IntentUtils; import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.StringUtils; @@ -104,6 +105,7 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity private MenuItem saveMenuItem; private MenuItem voiceFrequencyMenuItem; private MenuItem splitFrequencyMenuItem; + private MenuItem feedbackMenuItem; private final Runnable bindChangedCallback = new Runnable() { @Override @@ -309,7 +311,9 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity saveMenuItem = menu.findItem(R.id.track_detail_save); voiceFrequencyMenuItem = menu.findItem(R.id.track_detail_voice_frequency); splitFrequencyMenuItem = menu.findItem(R.id.track_detail_split_frequency); - + feedbackMenuItem = menu.findItem(R.id.track_detail_split_frequency); + feedbackMenuItem.setVisible(GoogleFeedbackUtils.isAvailable(this)); + updateMenuItems(trackId == recordingTrackId, recordingTrackPaused); return true; } @@ -351,8 +355,8 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity .show(getSupportFragmentManager(), ConfirmDialogFragment.CONFIRM_DIALOG_TAG); return true; case R.id.track_detail_share_maps: - ConfirmDialogFragment.newInstance(R.string.confirm_share_map_key, - PreferencesUtils.CONFIRM_SHARE_MAP_DEFAULT, StringUtils.getHtml( + ConfirmDialogFragment.newInstance(R.string.confirm_share_maps_key, + PreferencesUtils.CONFIRM_SHARE_MAPS_DEFAULT, StringUtils.getHtml( this, R.string.share_track_maps_confirm_message, R.string.maps_public_unlisted_url), trackId).show(getSupportFragmentManager(), ConfirmDialogFragment.CONFIRM_DIALOG_TAG); return true; @@ -407,6 +411,9 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity intent = IntentUtils.newIntent(this, SettingsActivity.class); startActivity(intent); return true; + case R.id.track_detail_feedback: + GoogleFeedbackUtils.bindFeedback(this); + return true; case R.id.track_detail_help: intent = IntentUtils.newIntent(this, HelpActivity.class); startActivity(intent); @@ -441,8 +448,8 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity .putExtra(SaveActivity.EXTRA_PLAY_TRACK, true); startActivity(intent); break; - case R.string.confirm_share_map_key: - AnalyticsUtils.sendPageViews(this, "/action/share_map"); + case R.string.confirm_share_maps_key: + AnalyticsUtils.sendPageViews(this, "/action/share_maps"); sendRequest = new SendRequest(trackId); sendRequest.setSendMaps(true); sendRequest.setMapsShare(true); diff --git a/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java b/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java index 2b461a545..292aeb354 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java @@ -40,11 +40,13 @@ import com.google.android.apps.mytracks.io.file.TrackFileFormat; import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest; import com.google.android.apps.mytracks.io.sync.SyncUtils; import com.google.android.apps.mytracks.services.ITrackRecordingService; +import com.google.android.apps.mytracks.services.RemoveTempFilesService; import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection; import com.google.android.apps.mytracks.settings.SettingsActivity; import com.google.android.apps.mytracks.util.AnalyticsUtils; import com.google.android.apps.mytracks.util.ApiAdapterFactory; import com.google.android.apps.mytracks.util.EulaUtils; +import com.google.android.apps.mytracks.util.GoogleFeedbackUtils; import com.google.android.apps.mytracks.util.GoogleLocationUtils; import com.google.android.apps.mytracks.util.IntentUtils; import com.google.android.apps.mytracks.util.ListItemUtils; @@ -54,6 +56,7 @@ import com.google.android.apps.mytracks.util.TrackIconUtils; import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; +import com.google.android.maps.mytracks.BuildConfig; import com.google.android.maps.mytracks.R; import android.app.Dialog; @@ -351,6 +354,7 @@ public class TrackListActivity extends AbstractSendToGoogleActivity private MenuItem saveAllMenuItem; private MenuItem deleteAllMenuItem; private MenuItem syncNowMenuItem; + private MenuItem feedbackMenuItem; private boolean startNewRecording = false; // true to start a new recording private boolean startGps = false; @@ -358,6 +362,13 @@ public class TrackListActivity extends AbstractSendToGoogleActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + if (BuildConfig.DEBUG) { + ApiAdapterFactory.getApiAdapter().enableStrictMode(); + } + Intent intent = new Intent(this, RemoveTempFilesService.class); + startService(intent); + setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this); @@ -545,6 +556,8 @@ public class TrackListActivity extends AbstractSendToGoogleActivity saveAllMenuItem = menu.findItem(R.id.track_list_save_all); deleteAllMenuItem = menu.findItem(R.id.track_list_delete_all); syncNowMenuItem = menu.findItem(R.id.track_list_sync_now); + feedbackMenuItem = menu.findItem(R.id.track_list_feedback); + feedbackMenuItem.setVisible(GoogleFeedbackUtils.isAvailable(this)); ApiAdapterFactory.getApiAdapter().configureSearchWidget(this, searchMenuItem); updateMenuItems(recordingTrackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT); @@ -607,6 +620,9 @@ public class TrackListActivity extends AbstractSendToGoogleActivity intent = IntentUtils.newIntent(this, SettingsActivity.class); startActivity(intent); return true; + case R.id.track_list_feedback: + GoogleFeedbackUtils.bindFeedback(this); + return true; case R.id.track_list_help: intent = IntentUtils.newIntent(this, HelpActivity.class); startActivity(intent); @@ -615,7 +631,7 @@ public class TrackListActivity extends AbstractSendToGoogleActivity return super.onOptionsItemSelected(item); } } - + @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/DeleteAllTrackDialogFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/DeleteAllTrackDialogFragment.java index f93a42f0b..3effd70c1 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/fragments/DeleteAllTrackDialogFragment.java +++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/DeleteAllTrackDialogFragment.java @@ -52,13 +52,8 @@ public class DeleteAllTrackDialogFragment extends DialogFragment { PreferencesUtils.setBoolean( fragmentActivity, R.string.drive_sync_key, PreferencesUtils.DRIVE_SYNC_DEFAULT); SyncUtils.disableSync(fragmentActivity); + SyncUtils.clearSyncState(fragmentActivity); MyTracksProviderUtils.Factory.get(fragmentActivity).deleteAllTracks(); - PreferencesUtils.setLong(fragmentActivity, R.string.drive_largest_change_id_key, - PreferencesUtils.DRIVE_LARGEST_CHANGE_ID_DEFAULT); - - // Clear the drive_deleted_list_key last - PreferencesUtils.setString(fragmentActivity, R.string.drive_deleted_list_key, - PreferencesUtils.DRIVE_DELETED_LIST_DEFAULT); } }).start(); } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/backup/BackupAsyncTask.java b/MyTracks/src/com/google/android/apps/mytracks/io/backup/BackupAsyncTask.java index 99b11bbcc..ce985a607 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/backup/BackupAsyncTask.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/backup/BackupAsyncTask.java @@ -81,12 +81,12 @@ public class BackupAsyncTask extends AsyncTask { @Override protected Boolean doInBackground(Void... params) { if (!FileUtils.isExternalStorageWriteable()) { - messageId = R.string.external_storage_not_writeable; + messageId = R.string.external_storage_not_writable; return false; } if (!externalFileBackup.isBackupsDirectoryAvailable(true)) { - messageId = R.string.external_storage_not_writeable; + messageId = R.string.external_storage_not_writable; return false; } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/file/SaveActivity.java b/MyTracks/src/com/google/android/apps/mytracks/io/file/SaveActivity.java index dd4336e7e..1b0d96140 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/file/SaveActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/file/SaveActivity.java @@ -83,7 +83,7 @@ public class SaveActivity extends Activity { playTrack = intent.getBooleanExtra(EXTRA_PLAY_TRACK, false); if (!FileUtils.isExternalStorageWriteable()) { - Toast.makeText(this, R.string.external_storage_not_writeable, Toast.LENGTH_LONG).show(); + Toast.makeText(this, R.string.external_storage_not_writable, Toast.LENGTH_LONG).show(); finish(); return; } @@ -94,7 +94,7 @@ public class SaveActivity extends Activity { File directory = new File(directoryName); if (!FileUtils.ensureDirectoryExists(directory)) { - Toast.makeText(this, R.string.external_storage_not_writeable, Toast.LENGTH_LONG).show(); + Toast.makeText(this, R.string.external_storage_not_writable, Toast.LENGTH_LONG).show(); finish(); return; } diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtils.java b/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtils.java index 74f0aa35b..989fd0db9 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/fusiontables/SendFusionTablesUtils.java @@ -32,9 +32,6 @@ import java.util.Locale; */ public class SendFusionTablesUtils { - public static final String SERVICE = "fusiontables"; - private static final String UTF8 = "UTF8"; - private static final String TABLE_ID = "tableid"; private static final String MAP_URL = "https://www.google.com/fusiontables/embedviz?" + "viz=MAP&q=select+col0,+col1,+col2,+col3+from+%s+&h=false&lat=%f&lng=%f&z=%d&t=1&l=col2"; private static final String TAG = SendFusionTablesUtils.class.getSimpleName(); diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncUtils.java b/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncUtils.java index f6bd217f4..bb3af6b1e 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/sync/SyncUtils.java @@ -41,6 +41,7 @@ import android.accounts.Account; import android.accounts.AccountManager; import android.content.ContentResolver; import android.content.Context; +import android.database.Cursor; import android.os.Bundle; import android.util.Log; @@ -137,6 +138,38 @@ public class SyncUtils { ContentResolver.requestSync(account, SYNC_AUTHORITY, new Bundle()); } + /** + * Clears the sync state. Assumes sync is turned off. Do not want clearing the + * state to cause sync activities. + */ + public static void clearSyncState(Context context) { + MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context); + Cursor cursor = null; + try { + cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.DRIVE_ID_TRACKS_QUERY, null, null); + if (cursor != null && cursor.moveToFirst()) { + do { + Track track = myTracksProviderUtils.createTrack(cursor); + if (track.isSharedWithMe()) { + myTracksProviderUtils.deleteTrack(track.getId()); + } else { + SyncUtils.updateTrackWithDriveFileInfo(myTracksProviderUtils, track, null); + } + } while (cursor.moveToNext()); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + PreferencesUtils.setLong(context, R.string.drive_largest_change_id_key, + PreferencesUtils.DRIVE_LARGEST_CHANGE_ID_DEFAULT); + + // Clear the drive_deleted_list_key last + PreferencesUtils.setString( + context, R.string.drive_deleted_list_key, PreferencesUtils.DRIVE_DELETED_LIST_DEFAULT); + } + /** * Gets the drive service. * diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/BackupResetSettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/BackupResetSettingsActivity.java index 1835dbfb7..e95a204ec 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/BackupResetSettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/settings/BackupResetSettingsActivity.java @@ -19,6 +19,7 @@ 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.IntentUtils; import com.google.android.apps.mytracks.util.PreferencesUtils; @@ -189,6 +190,9 @@ public class BackupResetSettingsActivity extends AbstractSettingsActivity { // 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 diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/GoogleSettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/GoogleSettingsActivity.java index 5cff65cef..6ef41ebc5 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/GoogleSettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/settings/GoogleSettingsActivity.java @@ -17,8 +17,6 @@ package com.google.android.apps.mytracks.settings; import com.google.android.apps.mytracks.Constants; -import com.google.android.apps.mytracks.content.MyTracksProviderUtils; -import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.io.sendtogoogle.PermissionCallback; import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils; import com.google.android.apps.mytracks.io.sync.SyncUtils; @@ -34,7 +32,6 @@ import android.app.Dialog; import android.content.ContentResolver; import android.content.DialogInterface; import android.content.Intent; -import android.database.Cursor; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.ListPreference; @@ -122,7 +119,6 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity { showDialog(DIALOG_CONFIRM_DRIVE_SYNC_ON); } else { handleSync(false); - clearSyncState(); } return false; } @@ -202,7 +198,6 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity { public void onClick(DialogInterface d, int button) { googleAccountPreference.setValue(newValue); handleSync(false); - clearSyncState(); updateUiByAccountName(newValue); } }); @@ -217,38 +212,6 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity { super.onPrepareDialog(id, dialog, bundle); } - /** - * Clears the sync state. Assumes sync is turned off. Do not want clearing the - * state to cause sync activities. - */ - private void clearSyncState() { - MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this); - Cursor cursor = null; - try { - cursor = myTracksProviderUtils.getTrackCursor(SyncUtils.DRIVE_ID_TRACKS_QUERY, null, null); - if (cursor != null && cursor.moveToFirst()) { - do { - Track track = myTracksProviderUtils.createTrack(cursor); - if (track.isSharedWithMe()) { - myTracksProviderUtils.deleteTrack(track.getId()); - } else { - SyncUtils.updateTrackWithDriveFileInfo(myTracksProviderUtils, track, null); - } - } while (cursor.moveToNext()); - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - PreferencesUtils.setLong(this, R.string.drive_largest_change_id_key, - PreferencesUtils.DRIVE_LARGEST_CHANGE_ID_DEFAULT); - - // Clear the drive_deleted_list_key last - PreferencesUtils.setString( - this, R.string.drive_deleted_list_key, PreferencesUtils.DRIVE_DELETED_LIST_DEFAULT); - } - /** * Handles sync. * @@ -275,6 +238,8 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity { break; } } + } else { + SyncUtils.clearSyncState(this); } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/MapSettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/MapSettingsActivity.java index 63446861a..607486c76 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/MapSettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/settings/MapSettingsActivity.java @@ -75,6 +75,7 @@ public class MapSettingsActivity extends AbstractSettingsActivity { /** * Configures the track color mode preference. */ + @SuppressWarnings("deprecation") private void configTrackColorModePerference() { ListPreference preference = (ListPreference) findPreference( getString(R.string.track_color_mode_key)); diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/RecordingSettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/RecordingSettingsActivity.java index ca456ce30..80ea5c3f0 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/RecordingSettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/settings/RecordingSettingsActivity.java @@ -64,6 +64,7 @@ public class RecordingSettingsActivity extends AbstractSettingsActivity { R.array.auto_resume_track_timeout_values, metricUnits); } + @SuppressWarnings("deprecation") private void configFrequencyPreference( int key, int defaultValue, int valueArray, boolean metricUnits) { ListPreference preference = (ListPreference) findPreference(getString(key)); @@ -73,6 +74,7 @@ public class RecordingSettingsActivity extends AbstractSettingsActivity { configureListPreference(preference, options, options, values, String.valueOf(value), null); } + @SuppressWarnings("deprecation") private void configTrackName() { ListPreference preference = (ListPreference) findPreference(getString(R.string.track_name_key)); String value = PreferencesUtils.getString( @@ -82,6 +84,7 @@ public class RecordingSettingsActivity extends AbstractSettingsActivity { configureListPreference(preference, options, options, values, value, null); } + @SuppressWarnings("deprecation") private void configDefaultActivity() { Preference preference = findPreference(getString(R.string.default_activity_key)); String value = PreferencesUtils.getString( @@ -101,6 +104,7 @@ public class RecordingSettingsActivity extends AbstractSettingsActivity { : getString(R.string.value_unknown)); } + @SuppressWarnings("deprecation") private void configListPreference( int key, int defaultValue, int valueArray, boolean metricUnits) { ListPreference preference = (ListPreference) findPreference(getString(key)); diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/SensorSettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/SensorSettingsActivity.java index a21bb27d9..bed1455b5 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/SensorSettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/settings/SensorSettingsActivity.java @@ -69,6 +69,7 @@ public class SensorSettingsActivity extends AbstractSettingsActivity { } } + @SuppressWarnings("deprecation") private void configSensorType(boolean hasAntSupport) { ListPreference preference = (ListPreference) findPreference( getString(R.string.sensor_type_key)); 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 c2ca2982a..9482b31e8 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/settings/SettingsActivity.java @@ -54,6 +54,7 @@ public class SettingsActivity extends AbstractSettingsActivity { * @param key the preference key * @param cl the class to start the new activity */ + @SuppressWarnings("deprecation") private void configPreference(int key, final Class cl) { Preference preference = findPreference(getString(key)); preference.setOnPreferenceClickListener(new OnPreferenceClickListener() { diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/Api16Adapter.java b/MyTracks/src/com/google/android/apps/mytracks/util/Api16Adapter.java new file mode 100644 index 000000000..7ce6f17f5 --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/util/Api16Adapter.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013 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.util; + +import com.google.android.apps.mytracks.widgets.TrackWidgetProvider; + +import android.annotation.TargetApi; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProviderInfo; +import android.os.Bundle; + +/** + * API level 16 specific implementation of the {@link ApiAdapter}. + * + * @author Jimmy Shih + */ +@TargetApi(16) +public class Api16Adapter extends Api14Adapter { + + private static final String APP_WIDGET_SIZE_KEY = "app_widget_size_key"; + + @Override + public int getAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId) { + Bundle bundle = appWidgetManager.getAppWidgetOptions(appWidgetId); + boolean isKeyguard = bundle.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1) + == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD; + return bundle.getInt(APP_WIDGET_SIZE_KEY, isKeyguard ? TrackWidgetProvider.KEYGUARD_DEFAULT_SIZE + : TrackWidgetProvider.HOME_SCREEN_DEFAULT_SIZE); + } + + @Override + public void setAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId, int size) { + Bundle bundle = new Bundle(); + bundle.putInt(APP_WIDGET_SIZE_KEY, size); + appWidgetManager.updateAppWidgetOptions(appWidgetId, bundle); + } +} diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/Api8Adapter.java b/MyTracks/src/com/google/android/apps/mytracks/util/Api8Adapter.java index b8c768821..3279e52eb 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/Api8Adapter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/Api8Adapter.java @@ -18,10 +18,12 @@ package com.google.android.apps.mytracks.util; import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.ContextualActionModeCallback; import com.google.android.apps.mytracks.services.sensors.BluetoothConnectionManager; +import com.google.android.apps.mytracks.widgets.TrackWidgetProvider; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.apache.ApacheHttpTransport; import android.app.Activity; +import android.appwidget.AppWidgetManager; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.content.SharedPreferences.Editor; @@ -136,4 +138,14 @@ public class Api8Adapter implements ApiAdapter { // Return false and allow the framework to handle the search key. return false; } + + @Override + public int getAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId) { + return TrackWidgetProvider.HOME_SCREEN_DEFAULT_SIZE; + } + + @Override + public void setAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId, int size) { + // Do nothing + } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapter.java b/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapter.java index 908cb3537..d4949c47d 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapter.java @@ -19,6 +19,7 @@ import com.google.android.apps.mytracks.ContextualActionModeCallback; import com.google.api.client.http.HttpTransport; import android.app.Activity; +import android.appwidget.AppWidgetManager; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.content.SharedPreferences; @@ -169,5 +170,24 @@ public interface ApiAdapter { * * @param menu the search menu */ - public boolean handleSearchKey(MenuItem menu); + public boolean handleSearchKey(MenuItem menu); + + /** + * Gets the app widget size. + *

+ * Due to changes in API level 16. + * + * @param appWidgetManager the app widget manager + * @param appWidgetId the app widget id + */ + public int getAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId); + + /** + * Sets the app widget size. + * + * @param appWidgetManager the app widget manager. + * @param appWidgetId the app widgit id + * @param size the size + */ + public void setAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId, int size); } diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapterFactory.java b/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapterFactory.java index d1ebdffe8..5b60e1e5a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapterFactory.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapterFactory.java @@ -31,21 +31,18 @@ public class ApiAdapterFactory { */ public static ApiAdapter getApiAdapter() { if (apiAdapter == null) { - if (Build.VERSION.SDK_INT >= 14) { + if (Build.VERSION.SDK_INT >= 16) { + apiAdapter = new Api16Adapter(); + } else if (Build.VERSION.SDK_INT >= 14) { apiAdapter = new Api14Adapter(); - return apiAdapter; } else if (Build.VERSION.SDK_INT >= 11) { apiAdapter = new Api11Adapter(); - return apiAdapter; } else if (Build.VERSION.SDK_INT >= 10) { apiAdapter = new Api10Adapter(); - return apiAdapter; } else if (Build.VERSION.SDK_INT >= 9) { apiAdapter = new Api9Adapter(); - return apiAdapter; } else { apiAdapter = new Api8Adapter(); - return apiAdapter; } } return apiAdapter; diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/GoogleFeedbackUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/GoogleFeedbackUtils.java new file mode 100644 index 000000000..71f2b50b2 --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/util/GoogleFeedbackUtils.java @@ -0,0 +1,91 @@ +/* + * Copyright 2013 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.util; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.Binder; +import android.os.IBinder; +import android.os.Parcel; +import android.os.RemoteException; +import android.util.Log; + +import java.util.List; + +/** + * Utilities for Google Feedback. + * + * @author Jimmy Shih + */ +public class GoogleFeedbackUtils { + + private static final String GOOGLE_FEEDBACK_PACKAGE_NAME = "com.google.android.feedback"; + private static final String TAG = GoogleFeedbackUtils.class.getSimpleName(); + + private static Boolean available = null; + + /** + * Returns true if the Google Feedback is available. + * + * @param context the context + */ + public static boolean isAvailable(Context context) { + if (available == null) { + List infos = context.getPackageManager().queryIntentServices( + new Intent(Intent.ACTION_BUG_REPORT), PackageManager.MATCH_DEFAULT_ONLY); + for (ResolveInfo info : infos) { + if (info.serviceInfo != null && info.serviceInfo.packageName != null + && info.serviceInfo.packageName.equals(GOOGLE_FEEDBACK_PACKAGE_NAME)) { + available = true; + break; + } + } + if (available == null) { + available = false; + } + } + return available; + } + + /** + * Binds the Google Feedback service. + * + * @param context the context + */ + public static void bindFeedback(Context context) { + Intent intent = new Intent(Intent.ACTION_BUG_REPORT); + ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + try { + service.transact(Binder.FIRST_CALL_TRANSACTION, Parcel.obtain(), null, 0); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException", e); + } + } + + @Override + public void onServiceDisconnected(ComponentName name) {} + }; + // Bind to the service after creating it if necessary + context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); + } +} diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/PreferencesUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/PreferencesUtils.java index c84acec70..b7f233ad5 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/PreferencesUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/PreferencesUtils.java @@ -52,7 +52,7 @@ public class PreferencesUtils { public static final boolean CONFIRM_PLAY_EARTH_DEFAULT = true; public static final boolean CONFIRM_SHARE_DRIVE_DEFAULT = true; - public static final boolean CONFIRM_SHARE_MAP_DEFAULT = true; + public static final boolean CONFIRM_SHARE_MAPS_DEFAULT = true; public static final String DEFAULT_ACTIVITY_DEFAULT = ""; public static final boolean DEFAULT_MAP_PUBLIC_DEFAULT = false; diff --git a/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java b/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java index 2c14eeac8..16cbc0e64 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java +++ b/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java @@ -22,6 +22,7 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.services.ControlRecordingService; import com.google.android.apps.mytracks.stats.TripStatistics; +import com.google.android.apps.mytracks.util.ApiAdapterFactory; import com.google.android.apps.mytracks.util.IntentUtils; import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.StringUtils; @@ -31,13 +32,13 @@ import android.annotation.TargetApi; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; +import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.SystemClock; import android.support.v4.app.TaskStackBuilder; -import android.util.SparseIntArray; import android.view.View; import android.widget.RemoteViews; @@ -51,14 +52,13 @@ import android.widget.RemoteViews; */ public class TrackWidgetProvider extends AppWidgetProvider { + public static final int KEYGUARD_DEFAULT_SIZE = 1; + public static final int HOME_SCREEN_DEFAULT_SIZE = 2; + private static final int TWO_CELLS = 110; private static final int THREE_CELLS = 180; private static final int FOUR_CELLS = 250; - // Array of appwidget id to height size in cells - private static final SparseIntArray HEIGHT_SIZE = new SparseIntArray(); - private static final int DEFAULT_SIZE = 2; - private static final int[] ITEM1_IDS = { R.id.track_widget_item1_label, R.id.track_widget_item1_value, R.id.track_widget_item1_unit, R.id.track_widget_item1_chronometer }; @@ -86,8 +86,9 @@ public class TrackWidgetProvider extends AppWidgetProvider { int[] appWidgetIds = appWidgetManager.getAppWidgetIds( new ComponentName(context, TrackWidgetProvider.class)); for (int appWidgetId : appWidgetIds) { - RemoteViews remoteViews = getRemoteViews( - context, trackId, HEIGHT_SIZE.get(appWidgetId, DEFAULT_SIZE)); + int size = ApiAdapterFactory.getApiAdapter() + .getAppWidgetSize(appWidgetManager, appWidgetId); + RemoteViews remoteViews = getRemoteViews(context, trackId, size); appWidgetManager.updateAppWidget(appWidgetId, remoteViews); } } @@ -99,19 +100,24 @@ public class TrackWidgetProvider extends AppWidgetProvider { Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { if (newOptions != null) { int size; - int height = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT); - if (height == 0) { - size = 2; - } else if (height >= FOUR_CELLS) { - size = 4; - } else if (height >= THREE_CELLS) { - size = 3; - } else if (height >= TWO_CELLS) { - size = 2; - } else { + if (newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1) + == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD) { size = 1; + } else { + int height = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT); + if (height == 0) { + size = 2; + } else if (height >= FOUR_CELLS) { + size = 4; + } else if (height >= THREE_CELLS) { + size = 3; + } else if (height >= TWO_CELLS) { + size = 2; + } else { + size = 1; + } } - HEIGHT_SIZE.put(appWidgetId, size); + ApiAdapterFactory.getApiAdapter().setAppWidgetSize(appWidgetManager, appWidgetId, size); RemoteViews remoteViews = getRemoteViews(context, -1L, size); appWidgetManager.updateAppWidget(appWidgetId, remoteViews); } @@ -126,8 +132,9 @@ public class TrackWidgetProvider extends AppWidgetProvider { */ public static void updateAppWidget( Context context, AppWidgetManager appWidgetManager, int appWidgetId) { - RemoteViews remoteViews = getRemoteViews( - context, -1L, HEIGHT_SIZE.get(appWidgetId, DEFAULT_SIZE)); + int size = ApiAdapterFactory.getApiAdapter().getAppWidgetSize(appWidgetManager, appWidgetId); + ApiAdapterFactory.getApiAdapter().setAppWidgetSize(appWidgetManager, appWidgetId, size); + RemoteViews remoteViews = getRemoteViews(context, -1L, size); appWidgetManager.updateAppWidget(appWidgetId, remoteViews); } diff --git a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/GoogleUtils.java b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/GoogleUtils.java index 6a14b6999..6bf27fc5c 100644 --- a/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/GoogleUtils.java +++ b/MyTracksTest_E2E/src/com/google/android/apps/mytracks/endtoendtest/GoogleUtils.java @@ -16,7 +16,6 @@ package com.google.android.apps.mytracks.endtoendtest; import com.google.android.apps.mytracks.Constants; -import com.google.android.apps.mytracks.io.fusiontables.SendFusionTablesUtils; import com.google.android.apps.mytracks.io.gdata.GDataClientFactory; import com.google.android.apps.mytracks.io.gdata.maps.MapFeatureEntry; import com.google.android.apps.mytracks.io.gdata.maps.MapsClient; @@ -81,6 +80,7 @@ public class GoogleUtils { private static final String APP_NAME_PREFIX = "Google-MyTracks-"; private static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; + private static final String FUSION_TABLES_SERVICE = "fusiontables"; private static final String FUSION_TABLES_BASE_URL = "https://www.google.com/fusiontables/api/query"; private static final String GDATA_VERSION = "2"; private static final String WORK_SHEET_NAME = "Log"; @@ -409,7 +409,7 @@ public class GoogleUtils { private static HttpResponse sendFusionTableQuery(String query, Context context) { try { String fusionTableAuthToken = AccountManager.get(context).blockingGetAuthToken( - getAccount(context), SendFusionTablesUtils.SERVICE, false); + getAccount(context), FUSION_TABLES_SERVICE, false); GenericUrl url = new GenericUrl(FUSION_TABLES_BASE_URL); String sql = "sql=" + query;