Merge heads

This commit is contained in:
youtaol
2013-02-26 10:51:24 +08:00
parent d740f5a09d
commit da04450a2b
40 changed files with 326 additions and 182 deletions
@@ -17,7 +17,6 @@
<classpathentry kind="lib" path="libs/httpcore-{{ features.httpCoreVersion }}.jar" sourcepath="libs-sources/httpcore-{{ features.httpCoreVersion }}-sources.jar"/> <classpathentry kind="lib" path="libs/httpcore-{{ features.httpCoreVersion }}.jar" sourcepath="libs-sources/httpcore-{{ features.httpCoreVersion }}-sources.jar"/>
<classpathentry kind="lib" path="libs/jackson-core-asl-{{ features.jacksonCoreAslVersion }}.jar" sourcepath="libs-sources/jackson-core-asl-{{ features.jacksonCoreAslVersion }}-sources.jar"/> <classpathentry kind="lib" path="libs/jackson-core-asl-{{ features.jacksonCoreAslVersion }}.jar" sourcepath="libs-sources/jackson-core-asl-{{ features.jacksonCoreAslVersion }}-sources.jar"/>
<classpathentry kind="lib" path="libs/jdo2-api-{{ features.jdo2ApiVersion }}.jar" sourcepath="libs-sources/jdo2-api-{{ features.jdo2ApiVersion }}-sources.jar"/> <classpathentry kind="lib" path="libs/jdo2-api-{{ features.jdo2ApiVersion }}.jar" sourcepath="libs-sources/jdo2-api-{{ features.jdo2ApiVersion }}-sources.jar"/>
<classpathentry kind="lib" path="libs/jsr305-{{ features.jsr305Version }}.jar"/>
<classpathentry kind="lib" path="libs/protobuf-java-{{ features.protobufVersion }}.jar" sourcepath="libs-sources/protobuf-java-{{ features.protobufVersion }}-sources.jar"/> <classpathentry kind="lib" path="libs/protobuf-java-{{ features.protobufVersion }}.jar" sourcepath="libs-sources/protobuf-java-{{ features.protobufVersion }}-sources.jar"/>
<classpathentry kind="lib" path="libs/transaction-api-{{ features.transactionApiVersion }}.jar" sourcepath="libs-sources/transaction-api-{{ features.transactionApiVersion }}-sources.jar"/> <classpathentry kind="lib" path="libs/transaction-api-{{ features.transactionApiVersion }}.jar" sourcepath="libs-sources/transaction-api-{{ features.transactionApiVersion }}-sources.jar"/>
<classpathentry kind="lib" path="libs/xpp3-{{ features.xpp3Version }}.jar" sourcepath="libs-sources/xpp3-{{ features.xpp3Version }}-sources.jar"/> <classpathentry kind="lib" path="libs/xpp3-{{ features.xpp3Version }}.jar" sourcepath="libs-sources/xpp3-{{ features.xpp3Version }}-sources.jar"/>
@@ -632,23 +632,6 @@
"generic" "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": [ "files": [
{ {
@@ -17,7 +17,6 @@
<classpathentry kind="lib" path="libs/httpcore-{{ features.httpCoreVersion }}.jar" sourcepath="libs-sources/httpcore-{{ features.httpCoreVersion }}-sources.jar"/> <classpathentry kind="lib" path="libs/httpcore-{{ features.httpCoreVersion }}.jar" sourcepath="libs-sources/httpcore-{{ features.httpCoreVersion }}-sources.jar"/>
<classpathentry kind="lib" path="libs/jackson-core-asl-{{ features.jacksonCoreAslVersion }}.jar" sourcepath="libs-sources/jackson-core-asl-{{ features.jacksonCoreAslVersion }}-sources.jar"/> <classpathentry kind="lib" path="libs/jackson-core-asl-{{ features.jacksonCoreAslVersion }}.jar" sourcepath="libs-sources/jackson-core-asl-{{ features.jacksonCoreAslVersion }}-sources.jar"/>
<classpathentry kind="lib" path="libs/jdo2-api-{{ features.jdo2ApiVersion }}.jar" sourcepath="libs-sources/jdo2-api-{{ features.jdo2ApiVersion }}-sources.jar"/> <classpathentry kind="lib" path="libs/jdo2-api-{{ features.jdo2ApiVersion }}.jar" sourcepath="libs-sources/jdo2-api-{{ features.jdo2ApiVersion }}-sources.jar"/>
<classpathentry kind="lib" path="libs/jsr305-{{ features.jsr305Version }}.jar"/>
<classpathentry kind="lib" path="libs/protobuf-java-{{ features.protobufVersion }}.jar" sourcepath="libs-sources/protobuf-java-{{ features.protobufVersion }}-sources.jar"/> <classpathentry kind="lib" path="libs/protobuf-java-{{ features.protobufVersion }}.jar" sourcepath="libs-sources/protobuf-java-{{ features.protobufVersion }}-sources.jar"/>
<classpathentry kind="lib" path="libs/transaction-api-{{ features.transactionApiVersion }}.jar" sourcepath="libs-sources/transaction-api-{{ features.transactionApiVersion }}-sources.jar"/> <classpathentry kind="lib" path="libs/transaction-api-{{ features.transactionApiVersion }}.jar" sourcepath="libs-sources/transaction-api-{{ features.transactionApiVersion }}-sources.jar"/>
<classpathentry kind="lib" path="libs/xpp3-{{ features.xpp3Version }}.jar" sourcepath="libs-sources/xpp3-{{ features.xpp3Version }}-sources.jar"/> <classpathentry kind="lib" path="libs/xpp3-{{ features.xpp3Version }}.jar" sourcepath="libs-sources/xpp3-{{ features.xpp3Version }}-sources.jar"/>
@@ -632,23 +632,6 @@
"generic" "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": [ "files": [
{ {
+4 -4
View File
@@ -16,8 +16,8 @@ limitations under the License.
--> -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="auto" android:installLocation="auto"
android:versionCode="63" android:versionCode="64"
android:versionName="2.0.3" android:versionName="2.0.4"
package="com.google.android.maps.mytracks" > package="com.google.android.maps.mytracks" >
<!-- Permission to initialize services --> <!-- Permission to initialize services -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@@ -93,7 +93,7 @@ limitations under the License.
<uses-permission android:name="com.google.android.maps.mytracks.permission.MAPS_RECEIVE" /> <uses-permission android:name="com.google.android.maps.mytracks.permission.MAPS_RECEIVE" />
<uses-sdk <uses-sdk
android:minSdkVersion="8" android:minSdkVersion="8"
android:targetSdkVersion="16" /> android:targetSdkVersion="17" />
<!-- Required features --> <!-- Required features -->
<uses-feature <uses-feature
android:glEsVersion="0x00020000" android:glEsVersion="0x00020000"
@@ -136,11 +136,11 @@ limitations under the License.
android:smallScreens="true" android:smallScreens="true"
android:xlargeScreens="true" /> android:xlargeScreens="true" />
<application <application
android:allowBackup="true"
android:backupAgent="com.google.android.apps.mytracks.io.backup.MyTracksBackupAgent" android:backupAgent="com.google.android.apps.mytracks.io.backup.MyTracksBackupAgent"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:icon="@drawable/my_tracks_icon" android:icon="@drawable/my_tracks_icon"
android:label="@string/my_tracks_app_name" android:label="@string/my_tracks_app_name"
android:name="com.google.android.apps.mytracks.MyTracksApplication"
android:theme="@style/ThemeSelector" > android:theme="@style/ThemeSelector" >
<!-- For data backup --> <!-- For data backup -->
<meta-data <meta-data
+1 -1
View File
@@ -4,7 +4,7 @@ applications that wish to use these files should consult the appropriate
licenses or the JAR's authors. licenses or the JAR's authors.
Android Support Package: Android Support Package:
android-support-v4.jar android-support-v4.jar (version 11)
Ant+: Ant+:
antlib.jar - see http://www.thisisant.com/pages/developer-zone/android-api antlib.jar - see http://www.thisisant.com/pages/developer-zone/android-api
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+6 -1
View File
@@ -103,9 +103,14 @@ limitations under the License.
android:id="@+id/track_detail_settings" android:id="@+id/track_detail_settings"
android:orderInCategory="14" android:orderInCategory="14"
android:title="@string/menu_settings"/> android:title="@string/menu_settings"/>
<item
android:icon="@drawable/menu_feedback"
android:id="@+id/track_detail_feedback"
android:orderInCategory="15"
android:title="@string/menu_feedback"/>
<item <item
android:icon="@drawable/menu_help" android:icon="@drawable/menu_help"
android:id="@+id/track_detail_help" android:id="@+id/track_detail_help"
android:orderInCategory="15" android:orderInCategory="16"
android:title="@string/menu_help"/> android:title="@string/menu_help"/>
</menu> </menu>
+4
View File
@@ -74,6 +74,10 @@ limitations under the License.
android:icon="@drawable/menu_settings" android:icon="@drawable/menu_settings"
android:id="@+id/track_list_settings" android:id="@+id/track_list_settings"
android:title="@string/menu_settings"/> android:title="@string/menu_settings"/>
<item
android:icon="@drawable/menu_feedback"
android:id="@+id/track_list_feedback"
android:title="@string/menu_feedback"/>
<item <item
android:icon="@drawable/menu_help" android:icon="@drawable/menu_help"
android:id="@+id/track_list_help" android:id="@+id/track_list_help"
+1 -1
View File
@@ -31,7 +31,7 @@ limitations under the License.
<string name="chart_show_speed_key">chartShowSpeed</string> <string name="chart_show_speed_key">chartShowSpeed</string>
<string name="confirm_play_earth_key">confirmPlayEarth</string> <string name="confirm_play_earth_key">confirmPlayEarth</string>
<string name="confirm_share_drive_key">confirmShareDrive</string> <string name="confirm_share_drive_key">confirmShareDrive</string>
<string name="confirm_share_map_key">confirmShareMap</string> <string name="confirm_share_maps_key">confirmShareMaps</string>
<string name="default_activity_key">defaultActivity</string> <string name="default_activity_key">defaultActivity</string>
<string name="default_map_public_key">defaultMapPublic</string> <string name="default_map_public_key">defaultMapPublic</string>
<string name="default_table_public_key">defaultTablePublic</string> <string name="default_table_public_key">defaultTablePublic</string>
+19 -11
View File
@@ -582,7 +582,7 @@ limitations under the License.
By using Google\'s mobile products and services (&#8220;Services&#8221;), you agree to be bound By using Google\'s mobile products and services (&#8220;Services&#8221;), you agree to be bound
by a) the YouTube Terms of Use (%1$s/tos_youtube) for YouTube-related Services, b) the Google 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 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. Terms of Service (%1$s/utos) for all other Services, as updated from time to time.
</string> </string>
<string name="eula_copyright_year" <string name="eula_copyright_year"
@@ -617,9 +617,9 @@ limitations under the License.
translation_description="Error message when the external storage is not available."> translation_description="Error message when the external storage is not available.">
External storage not available. External storage not available.
</string> </string>
<string name="external_storage_not_writeable" <string name="external_storage_not_writable"
translation_description="Error message when the external storage is not writeable."> translation_description="Error message when the external storage is not writable.">
External storage not writeable. External storage not writable.
</string> </string>
<!-- Files --> <!-- Files -->
@@ -974,6 +974,12 @@ limitations under the License.
Character limit: ~20 (1 line)"> Character limit: ~20 (1 line)">
Edit Edit
</string> </string>
<string name="menu_feedback"
translation_description="In the menu, to enter feedback.
Character limit: ~20 (1 line)">
Feedback
</string>
<string name="menu_help" <string name="menu_help"
translation_description="In the menu, to go to the help page. translation_description="In the menu, to go to the help page.
@@ -1478,7 +1484,7 @@ limitations under the License.
Backup now Backup now
</string> </string>
<string name="settings_backup_now_error" <string name="settings_backup_now_error"
translation_description="When backing up to the external storage, the error messag."> translation_description="When backing up to the external storage, the error message.">
Unable to backup. Unable to backup.
</string> </string>
<string name="settings_backup_now_progress_message" <string name="settings_backup_now_progress_message"
@@ -1660,7 +1666,8 @@ limitations under the License.
Character limit: ~23 (1 line)"> Character limit: ~23 (1 line)">
Top medium speed Top medium speed
</string><string name="settings_map_percentage" </string>
<string name="settings_map_percentage"
translation_description="In the 'Map' settings, under the 'Dynamic thresholds' section, the translation_description="In the 'Map' settings, under the 'Dynamic thresholds' section, the
option to configure the medium speed range as a percentage from the average speed. option to configure the medium speed range as a percentage from the average speed.
@@ -1744,7 +1751,7 @@ limitations under the License.
when a time value is selected. when a time value is selected.
%1$s time value. E.g., '5 min'."> %1$s time value. E.g., '5 min'.">
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
</string> </string>
<string name="settings_recording_auto_resume_track_timeout_title" <string name="settings_recording_auto_resume_track_timeout_title"
translation_description="In the 'Recording' settings, the title to configure automatically translation_description="In the 'Recording' settings, the title to configure automatically
@@ -1817,14 +1824,14 @@ limitations under the License.
Date (ISO 8601) Date (ISO 8601)
</string> </string>
<string name="settings_recording_track_name_date_local_option" <string name="settings_recording_track_name_date_local_option"
translation_description="In the 'Recording' settings, the option in the 'Defaul track name' translation_description="In the 'Recording' settings, the option in the 'Default track name'
setting to use the track starting time in the local format as the default track name. setting to use the track starting time in the local format as the default track name.
Character limit: ~20 (1 line)"> Character limit: ~20 (1 line)">
Date (local) Date (local)
</string> </string>
<string name="settings_recording_track_name_location_option" <string name="settings_recording_track_name_location_option"
translation_description="In the 'Recording' settings, the option in the 'Defaul track name' translation_description="In the 'Recording' settings, the option in the 'Default track name'
setting to use the track starting location as the default track name. setting to use the track starting location as the default track name.
Character limit: ~20 (1 line)"> Character limit: ~20 (1 line)">
@@ -2058,8 +2065,9 @@ limitations under the License.
<!-- Share Track --> <!-- Share Track -->
<string name="share_track_add_emails_title" <string name="share_track_add_emails_title"
translation_description="The dialog title for adding emails to share a track with."> translation_description="The dialog title for entering email addresses for sharing a track
Add emails with.">
Share track with
</string> </string>
<string name="share_track_add_emails_hint" <string name="share_track_add_emails_hint"
translation_description="The hint in the auto complete text box for entering email addresses."> translation_description="The hint in the auto complete text box for entering email addresses.">
+3 -1
View File
@@ -16,10 +16,12 @@ limitations under the License.
--> -->
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:configure="com.google.android.apps.mytracks.widgets.TrackWidgetConfigActivity" android:configure="com.google.android.apps.mytracks.widgets.TrackWidgetConfigActivity"
android:initialKeyguardLayout="@layout/track_widget_4x1"
android:initialLayout="@layout/track_widget_4x2" android:initialLayout="@layout/track_widget_4x2"
android:minHeight="110dp" android:minHeight="110dp"
android:minResizeHeight="40dp" android:minResizeHeight="40dp"
android:minResizeWidth="250dp" android:minResizeWidth="250dp"
android:minWidth="250dp" android:minWidth="250dp"
android:resizeMode="vertical" android:resizeMode="vertical"
android:updatePeriodMillis="0" /> android:updatePeriodMillis="0"
android:widgetCategory="keyguard|home_screen" />
@@ -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);
}
}
@@ -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.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.settings.SettingsActivity; import com.google.android.apps.mytracks.settings.SettingsActivity;
import com.google.android.apps.mytracks.util.AnalyticsUtils; 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.IntentUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.apps.mytracks.util.StringUtils;
@@ -104,6 +105,7 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
private MenuItem saveMenuItem; private MenuItem saveMenuItem;
private MenuItem voiceFrequencyMenuItem; private MenuItem voiceFrequencyMenuItem;
private MenuItem splitFrequencyMenuItem; private MenuItem splitFrequencyMenuItem;
private MenuItem feedbackMenuItem;
private final Runnable bindChangedCallback = new Runnable() { private final Runnable bindChangedCallback = new Runnable() {
@Override @Override
@@ -309,7 +311,9 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
saveMenuItem = menu.findItem(R.id.track_detail_save); saveMenuItem = menu.findItem(R.id.track_detail_save);
voiceFrequencyMenuItem = menu.findItem(R.id.track_detail_voice_frequency); voiceFrequencyMenuItem = menu.findItem(R.id.track_detail_voice_frequency);
splitFrequencyMenuItem = menu.findItem(R.id.track_detail_split_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); updateMenuItems(trackId == recordingTrackId, recordingTrackPaused);
return true; return true;
} }
@@ -351,8 +355,8 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
.show(getSupportFragmentManager(), ConfirmDialogFragment.CONFIRM_DIALOG_TAG); .show(getSupportFragmentManager(), ConfirmDialogFragment.CONFIRM_DIALOG_TAG);
return true; return true;
case R.id.track_detail_share_maps: case R.id.track_detail_share_maps:
ConfirmDialogFragment.newInstance(R.string.confirm_share_map_key, ConfirmDialogFragment.newInstance(R.string.confirm_share_maps_key,
PreferencesUtils.CONFIRM_SHARE_MAP_DEFAULT, StringUtils.getHtml( PreferencesUtils.CONFIRM_SHARE_MAPS_DEFAULT, StringUtils.getHtml(
this, R.string.share_track_maps_confirm_message, R.string.maps_public_unlisted_url), this, R.string.share_track_maps_confirm_message, R.string.maps_public_unlisted_url),
trackId).show(getSupportFragmentManager(), ConfirmDialogFragment.CONFIRM_DIALOG_TAG); trackId).show(getSupportFragmentManager(), ConfirmDialogFragment.CONFIRM_DIALOG_TAG);
return true; return true;
@@ -407,6 +411,9 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
intent = IntentUtils.newIntent(this, SettingsActivity.class); intent = IntentUtils.newIntent(this, SettingsActivity.class);
startActivity(intent); startActivity(intent);
return true; return true;
case R.id.track_detail_feedback:
GoogleFeedbackUtils.bindFeedback(this);
return true;
case R.id.track_detail_help: case R.id.track_detail_help:
intent = IntentUtils.newIntent(this, HelpActivity.class); intent = IntentUtils.newIntent(this, HelpActivity.class);
startActivity(intent); startActivity(intent);
@@ -441,8 +448,8 @@ public class TrackDetailActivity extends AbstractSendToGoogleActivity
.putExtra(SaveActivity.EXTRA_PLAY_TRACK, true); .putExtra(SaveActivity.EXTRA_PLAY_TRACK, true);
startActivity(intent); startActivity(intent);
break; break;
case R.string.confirm_share_map_key: case R.string.confirm_share_maps_key:
AnalyticsUtils.sendPageViews(this, "/action/share_map"); AnalyticsUtils.sendPageViews(this, "/action/share_maps");
sendRequest = new SendRequest(trackId); sendRequest = new SendRequest(trackId);
sendRequest.setSendMaps(true); sendRequest.setSendMaps(true);
sendRequest.setMapsShare(true); sendRequest.setMapsShare(true);
@@ -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.sendtogoogle.SendRequest;
import com.google.android.apps.mytracks.io.sync.SyncUtils; import com.google.android.apps.mytracks.io.sync.SyncUtils;
import com.google.android.apps.mytracks.services.ITrackRecordingService; 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.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.settings.SettingsActivity; import com.google.android.apps.mytracks.settings.SettingsActivity;
import com.google.android.apps.mytracks.util.AnalyticsUtils; import com.google.android.apps.mytracks.util.AnalyticsUtils;
import com.google.android.apps.mytracks.util.ApiAdapterFactory; import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.apps.mytracks.util.EulaUtils; 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.GoogleLocationUtils;
import com.google.android.apps.mytracks.util.IntentUtils; import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.ListItemUtils; 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.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.maps.mytracks.BuildConfig;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.Dialog; import android.app.Dialog;
@@ -351,6 +354,7 @@ public class TrackListActivity extends AbstractSendToGoogleActivity
private MenuItem saveAllMenuItem; private MenuItem saveAllMenuItem;
private MenuItem deleteAllMenuItem; private MenuItem deleteAllMenuItem;
private MenuItem syncNowMenuItem; private MenuItem syncNowMenuItem;
private MenuItem feedbackMenuItem;
private boolean startNewRecording = false; // true to start a new recording private boolean startNewRecording = false; // true to start a new recording
private boolean startGps = false; private boolean startGps = false;
@@ -358,6 +362,13 @@ public class TrackListActivity extends AbstractSendToGoogleActivity
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (BuildConfig.DEBUG) {
ApiAdapterFactory.getApiAdapter().enableStrictMode();
}
Intent intent = new Intent(this, RemoveTempFilesService.class);
startService(intent);
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this); myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
@@ -545,6 +556,8 @@ public class TrackListActivity extends AbstractSendToGoogleActivity
saveAllMenuItem = menu.findItem(R.id.track_list_save_all); saveAllMenuItem = menu.findItem(R.id.track_list_save_all);
deleteAllMenuItem = menu.findItem(R.id.track_list_delete_all); deleteAllMenuItem = menu.findItem(R.id.track_list_delete_all);
syncNowMenuItem = menu.findItem(R.id.track_list_sync_now); 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); ApiAdapterFactory.getApiAdapter().configureSearchWidget(this, searchMenuItem);
updateMenuItems(recordingTrackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT); updateMenuItems(recordingTrackId != PreferencesUtils.RECORDING_TRACK_ID_DEFAULT);
@@ -607,6 +620,9 @@ public class TrackListActivity extends AbstractSendToGoogleActivity
intent = IntentUtils.newIntent(this, SettingsActivity.class); intent = IntentUtils.newIntent(this, SettingsActivity.class);
startActivity(intent); startActivity(intent);
return true; return true;
case R.id.track_list_feedback:
GoogleFeedbackUtils.bindFeedback(this);
return true;
case R.id.track_list_help: case R.id.track_list_help:
intent = IntentUtils.newIntent(this, HelpActivity.class); intent = IntentUtils.newIntent(this, HelpActivity.class);
startActivity(intent); startActivity(intent);
@@ -615,7 +631,7 @@ public class TrackListActivity extends AbstractSendToGoogleActivity
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
} }
@Override @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo); super.onCreateContextMenu(menu, v, menuInfo);
@@ -52,13 +52,8 @@ public class DeleteAllTrackDialogFragment extends DialogFragment {
PreferencesUtils.setBoolean( PreferencesUtils.setBoolean(
fragmentActivity, R.string.drive_sync_key, PreferencesUtils.DRIVE_SYNC_DEFAULT); fragmentActivity, R.string.drive_sync_key, PreferencesUtils.DRIVE_SYNC_DEFAULT);
SyncUtils.disableSync(fragmentActivity); SyncUtils.disableSync(fragmentActivity);
SyncUtils.clearSyncState(fragmentActivity);
MyTracksProviderUtils.Factory.get(fragmentActivity).deleteAllTracks(); 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(); }).start();
} }
@@ -81,12 +81,12 @@ public class BackupAsyncTask extends AsyncTask<Void, Integer, Boolean> {
@Override @Override
protected Boolean doInBackground(Void... params) { protected Boolean doInBackground(Void... params) {
if (!FileUtils.isExternalStorageWriteable()) { if (!FileUtils.isExternalStorageWriteable()) {
messageId = R.string.external_storage_not_writeable; messageId = R.string.external_storage_not_writable;
return false; return false;
} }
if (!externalFileBackup.isBackupsDirectoryAvailable(true)) { if (!externalFileBackup.isBackupsDirectoryAvailable(true)) {
messageId = R.string.external_storage_not_writeable; messageId = R.string.external_storage_not_writable;
return false; return false;
} }
@@ -83,7 +83,7 @@ public class SaveActivity extends Activity {
playTrack = intent.getBooleanExtra(EXTRA_PLAY_TRACK, false); playTrack = intent.getBooleanExtra(EXTRA_PLAY_TRACK, false);
if (!FileUtils.isExternalStorageWriteable()) { 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(); finish();
return; return;
} }
@@ -94,7 +94,7 @@ public class SaveActivity extends Activity {
File directory = new File(directoryName); File directory = new File(directoryName);
if (!FileUtils.ensureDirectoryExists(directory)) { 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(); finish();
return; return;
} }
@@ -32,9 +32,6 @@ import java.util.Locale;
*/ */
public class SendFusionTablesUtils { 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?" 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"; + "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(); private static final String TAG = SendFusionTablesUtils.class.getSimpleName();
@@ -41,6 +41,7 @@ import android.accounts.Account;
import android.accounts.AccountManager; import android.accounts.AccountManager;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.database.Cursor;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
@@ -137,6 +138,38 @@ public class SyncUtils {
ContentResolver.requestSync(account, SYNC_AUTHORITY, new Bundle()); 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. * Gets the drive service.
* *
@@ -19,6 +19,7 @@ package com.google.android.apps.mytracks.settings;
import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.io.backup.BackupActivity; 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.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.DialogUtils;
import com.google.android.apps.mytracks.util.IntentUtils; import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
@@ -189,6 +190,9 @@ public class BackupResetSettingsActivity extends AbstractSettingsActivity {
// Actually wipe preferences and save synchronously // Actually wipe preferences and save synchronously
sharedPreferences.edit().clear().commit(); sharedPreferences.edit().clear().commit();
SyncUtils.disableSync(BackupResetSettingsActivity.this);
SyncUtils.clearSyncState(BackupResetSettingsActivity.this);
// Give UI feedback in the UI thread // Give UI feedback in the UI thread
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
@@ -17,8 +17,6 @@
package com.google.android.apps.mytracks.settings; package com.google.android.apps.mytracks.settings;
import com.google.android.apps.mytracks.Constants; 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.PermissionCallback;
import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils; import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils;
import com.google.android.apps.mytracks.io.sync.SyncUtils; import com.google.android.apps.mytracks.io.sync.SyncUtils;
@@ -34,7 +32,6 @@ import android.app.Dialog;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle; import android.os.Bundle;
import android.preference.CheckBoxPreference; import android.preference.CheckBoxPreference;
import android.preference.ListPreference; import android.preference.ListPreference;
@@ -122,7 +119,6 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity {
showDialog(DIALOG_CONFIRM_DRIVE_SYNC_ON); showDialog(DIALOG_CONFIRM_DRIVE_SYNC_ON);
} else { } else {
handleSync(false); handleSync(false);
clearSyncState();
} }
return false; return false;
} }
@@ -202,7 +198,6 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity {
public void onClick(DialogInterface d, int button) { public void onClick(DialogInterface d, int button) {
googleAccountPreference.setValue(newValue); googleAccountPreference.setValue(newValue);
handleSync(false); handleSync(false);
clearSyncState();
updateUiByAccountName(newValue); updateUiByAccountName(newValue);
} }
}); });
@@ -217,38 +212,6 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity {
super.onPrepareDialog(id, dialog, bundle); 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. * Handles sync.
* *
@@ -275,6 +238,8 @@ public class GoogleSettingsActivity extends AbstractSettingsActivity {
break; break;
} }
} }
} else {
SyncUtils.clearSyncState(this);
} }
} }
@@ -75,6 +75,7 @@ public class MapSettingsActivity extends AbstractSettingsActivity {
/** /**
* Configures the track color mode preference. * Configures the track color mode preference.
*/ */
@SuppressWarnings("deprecation")
private void configTrackColorModePerference() { private void configTrackColorModePerference() {
ListPreference preference = (ListPreference) findPreference( ListPreference preference = (ListPreference) findPreference(
getString(R.string.track_color_mode_key)); getString(R.string.track_color_mode_key));
@@ -64,6 +64,7 @@ public class RecordingSettingsActivity extends AbstractSettingsActivity {
R.array.auto_resume_track_timeout_values, metricUnits); R.array.auto_resume_track_timeout_values, metricUnits);
} }
@SuppressWarnings("deprecation")
private void configFrequencyPreference( private void configFrequencyPreference(
int key, int defaultValue, int valueArray, boolean metricUnits) { int key, int defaultValue, int valueArray, boolean metricUnits) {
ListPreference preference = (ListPreference) findPreference(getString(key)); ListPreference preference = (ListPreference) findPreference(getString(key));
@@ -73,6 +74,7 @@ public class RecordingSettingsActivity extends AbstractSettingsActivity {
configureListPreference(preference, options, options, values, String.valueOf(value), null); configureListPreference(preference, options, options, values, String.valueOf(value), null);
} }
@SuppressWarnings("deprecation")
private void configTrackName() { private void configTrackName() {
ListPreference preference = (ListPreference) findPreference(getString(R.string.track_name_key)); ListPreference preference = (ListPreference) findPreference(getString(R.string.track_name_key));
String value = PreferencesUtils.getString( String value = PreferencesUtils.getString(
@@ -82,6 +84,7 @@ public class RecordingSettingsActivity extends AbstractSettingsActivity {
configureListPreference(preference, options, options, values, value, null); configureListPreference(preference, options, options, values, value, null);
} }
@SuppressWarnings("deprecation")
private void configDefaultActivity() { private void configDefaultActivity() {
Preference preference = findPreference(getString(R.string.default_activity_key)); Preference preference = findPreference(getString(R.string.default_activity_key));
String value = PreferencesUtils.getString( String value = PreferencesUtils.getString(
@@ -101,6 +104,7 @@ public class RecordingSettingsActivity extends AbstractSettingsActivity {
: getString(R.string.value_unknown)); : getString(R.string.value_unknown));
} }
@SuppressWarnings("deprecation")
private void configListPreference( private void configListPreference(
int key, int defaultValue, int valueArray, boolean metricUnits) { int key, int defaultValue, int valueArray, boolean metricUnits) {
ListPreference preference = (ListPreference) findPreference(getString(key)); ListPreference preference = (ListPreference) findPreference(getString(key));
@@ -69,6 +69,7 @@ public class SensorSettingsActivity extends AbstractSettingsActivity {
} }
} }
@SuppressWarnings("deprecation")
private void configSensorType(boolean hasAntSupport) { private void configSensorType(boolean hasAntSupport) {
ListPreference preference = (ListPreference) findPreference( ListPreference preference = (ListPreference) findPreference(
getString(R.string.sensor_type_key)); getString(R.string.sensor_type_key));
@@ -54,6 +54,7 @@ public class SettingsActivity extends AbstractSettingsActivity {
* @param key the preference key * @param key the preference key
* @param cl the class to start the new activity * @param cl the class to start the new activity
*/ */
@SuppressWarnings("deprecation")
private void configPreference(int key, final Class<?> cl) { private void configPreference(int key, final Class<?> cl) {
Preference preference = findPreference(getString(key)); Preference preference = findPreference(getString(key));
preference.setOnPreferenceClickListener(new OnPreferenceClickListener() { preference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@@ -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);
}
}
@@ -18,10 +18,12 @@ package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.ContextualActionModeCallback; import com.google.android.apps.mytracks.ContextualActionModeCallback;
import com.google.android.apps.mytracks.services.sensors.BluetoothConnectionManager; 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.HttpTransport;
import com.google.api.client.http.apache.ApacheHttpTransport; import com.google.api.client.http.apache.ApacheHttpTransport;
import android.app.Activity; import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothSocket;
import android.content.SharedPreferences.Editor; 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 and allow the framework to handle the search key.
return false; 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
}
} }
@@ -19,6 +19,7 @@ import com.google.android.apps.mytracks.ContextualActionModeCallback;
import com.google.api.client.http.HttpTransport; import com.google.api.client.http.HttpTransport;
import android.app.Activity; import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothSocket;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@@ -169,5 +170,24 @@ public interface ApiAdapter {
* *
* @param menu the search menu * @param menu the search menu
*/ */
public boolean handleSearchKey(MenuItem menu); public boolean handleSearchKey(MenuItem menu);
/**
* Gets the app widget size.
* <p>
* 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);
} }
@@ -31,21 +31,18 @@ public class ApiAdapterFactory {
*/ */
public static ApiAdapter getApiAdapter() { public static ApiAdapter getApiAdapter() {
if (apiAdapter == null) { 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(); apiAdapter = new Api14Adapter();
return apiAdapter;
} else if (Build.VERSION.SDK_INT >= 11) { } else if (Build.VERSION.SDK_INT >= 11) {
apiAdapter = new Api11Adapter(); apiAdapter = new Api11Adapter();
return apiAdapter;
} else if (Build.VERSION.SDK_INT >= 10) { } else if (Build.VERSION.SDK_INT >= 10) {
apiAdapter = new Api10Adapter(); apiAdapter = new Api10Adapter();
return apiAdapter;
} else if (Build.VERSION.SDK_INT >= 9) { } else if (Build.VERSION.SDK_INT >= 9) {
apiAdapter = new Api9Adapter(); apiAdapter = new Api9Adapter();
return apiAdapter;
} else { } else {
apiAdapter = new Api8Adapter(); apiAdapter = new Api8Adapter();
return apiAdapter;
} }
} }
return apiAdapter; return apiAdapter;
@@ -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<ResolveInfo> 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);
}
}
@@ -52,7 +52,7 @@ public class PreferencesUtils {
public static final boolean CONFIRM_PLAY_EARTH_DEFAULT = true; public static final boolean CONFIRM_PLAY_EARTH_DEFAULT = true;
public static final boolean CONFIRM_SHARE_DRIVE_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 String DEFAULT_ACTIVITY_DEFAULT = "";
public static final boolean DEFAULT_MAP_PUBLIC_DEFAULT = false; public static final boolean DEFAULT_MAP_PUBLIC_DEFAULT = false;
@@ -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.content.Track;
import com.google.android.apps.mytracks.services.ControlRecordingService; import com.google.android.apps.mytracks.services.ControlRecordingService;
import com.google.android.apps.mytracks.stats.TripStatistics; 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.IntentUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.apps.mytracks.util.StringUtils;
@@ -31,13 +32,13 @@ import android.annotation.TargetApi;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider; import android.appwidget.AppWidgetProvider;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.v4.app.TaskStackBuilder; import android.support.v4.app.TaskStackBuilder;
import android.util.SparseIntArray;
import android.view.View; import android.view.View;
import android.widget.RemoteViews; import android.widget.RemoteViews;
@@ -51,14 +52,13 @@ import android.widget.RemoteViews;
*/ */
public class TrackWidgetProvider extends AppWidgetProvider { 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 TWO_CELLS = 110;
private static final int THREE_CELLS = 180; private static final int THREE_CELLS = 180;
private static final int FOUR_CELLS = 250; 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, 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_value, R.id.track_widget_item1_unit,
R.id.track_widget_item1_chronometer }; R.id.track_widget_item1_chronometer };
@@ -86,8 +86,9 @@ public class TrackWidgetProvider extends AppWidgetProvider {
int[] appWidgetIds = appWidgetManager.getAppWidgetIds( int[] appWidgetIds = appWidgetManager.getAppWidgetIds(
new ComponentName(context, TrackWidgetProvider.class)); new ComponentName(context, TrackWidgetProvider.class));
for (int appWidgetId : appWidgetIds) { for (int appWidgetId : appWidgetIds) {
RemoteViews remoteViews = getRemoteViews( int size = ApiAdapterFactory.getApiAdapter()
context, trackId, HEIGHT_SIZE.get(appWidgetId, DEFAULT_SIZE)); .getAppWidgetSize(appWidgetManager, appWidgetId);
RemoteViews remoteViews = getRemoteViews(context, trackId, size);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews); appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
} }
} }
@@ -99,19 +100,24 @@ public class TrackWidgetProvider extends AppWidgetProvider {
Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
if (newOptions != null) { if (newOptions != null) {
int size; int size;
int height = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT); if (newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1)
if (height == 0) { == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD) {
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; 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); RemoteViews remoteViews = getRemoteViews(context, -1L, size);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews); appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
} }
@@ -126,8 +132,9 @@ public class TrackWidgetProvider extends AppWidgetProvider {
*/ */
public static void updateAppWidget( public static void updateAppWidget(
Context context, AppWidgetManager appWidgetManager, int appWidgetId) { Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
RemoteViews remoteViews = getRemoteViews( int size = ApiAdapterFactory.getApiAdapter().getAppWidgetSize(appWidgetManager, appWidgetId);
context, -1L, HEIGHT_SIZE.get(appWidgetId, DEFAULT_SIZE)); ApiAdapterFactory.getApiAdapter().setAppWidgetSize(appWidgetManager, appWidgetId, size);
RemoteViews remoteViews = getRemoteViews(context, -1L, size);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews); appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
} }
@@ -16,7 +16,6 @@
package com.google.android.apps.mytracks.endtoendtest; package com.google.android.apps.mytracks.endtoendtest;
import com.google.android.apps.mytracks.Constants; 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.GDataClientFactory;
import com.google.android.apps.mytracks.io.gdata.maps.MapFeatureEntry; import com.google.android.apps.mytracks.io.gdata.maps.MapFeatureEntry;
import com.google.android.apps.mytracks.io.gdata.maps.MapsClient; 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 APP_NAME_PREFIX = "Google-MyTracks-";
private static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; 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 FUSION_TABLES_BASE_URL = "https://www.google.com/fusiontables/api/query";
private static final String GDATA_VERSION = "2"; private static final String GDATA_VERSION = "2";
private static final String WORK_SHEET_NAME = "Log"; private static final String WORK_SHEET_NAME = "Log";
@@ -409,7 +409,7 @@ public class GoogleUtils {
private static HttpResponse sendFusionTableQuery(String query, Context context) { private static HttpResponse sendFusionTableQuery(String query, Context context) {
try { try {
String fusionTableAuthToken = AccountManager.get(context).blockingGetAuthToken( 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); GenericUrl url = new GenericUrl(FUSION_TABLES_BASE_URL);
String sql = "sql=" + query; String sql = "sql=" + query;