merge heads
@@ -1,22 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="lib" path="libs/googleloginclient-helper.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="libs/google-common.jar"/>
|
||||
<classpathentry kind="lib" path="libs/libGoogleAnalytics.jar"/>
|
||||
<classpathentry kind="lib" path="libs/google-api-client/commons-codec-1.3.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="libs/google-api-client/commons-logging-1.1.1.jar"/>
|
||||
<classpathentry kind="lib" path="libs/google-api-client/google-api-client-1.5.0-beta.jar"/>
|
||||
<classpathentry kind="lib" path="libs/google-api-client/google-http-client-1.5.0-beta.jar"/>
|
||||
<classpathentry kind="lib" path="libs/google-api-client/google-oauth-client-1.5.0-beta.jar"/>
|
||||
<classpathentry kind="lib" path="libs/google-api-client/gson-1.6.jar"/>
|
||||
<classpathentry kind="lib" path="libs/google-api-client/guava-r09.jar"/>
|
||||
<classpathentry kind="lib" path="libs/google-api-client/jackson-core-asl-1.6.7.jar"/>
|
||||
<classpathentry kind="lib" path="libs/google-api-client/jsr305-1.3.9.jar"/>
|
||||
<classpathentry kind="lib" path="libs/android-support-v4.jar"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry exported="true" kind="lib" path="/MyTracksLib/libs/protobuf-java-2.3.0-lite.jar"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
|
||||
@@ -190,28 +190,6 @@ limitations under the License.
|
||||
android:name="android.app.default_searchable"
|
||||
android:value="com.google.android.apps.mytracks.SearchActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale"
|
||||
android:name="com.google.android.apps.mytracks.MyTracks" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="vnd.android.cursor.item/vnd.google.track" />
|
||||
<data android:mimeType="vnd.android.cursor.item/vnd.google.waypoint" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.default_searchable"
|
||||
android:value="com.google.android.apps.mytracks.SearchActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:launchMode="singleTop"
|
||||
android:name="com.google.android.apps.mytracks.SearchActivity" >
|
||||
@@ -244,9 +222,10 @@ limitations under the License.
|
||||
android:name="android.app.default_searchable"
|
||||
android:value="com.google.android.apps.mytracks.SearchActivity" />
|
||||
</activity>
|
||||
<activity android:name="com.google.android.apps.mytracks.TrackDetailActivity" />
|
||||
<activity
|
||||
android:label="@string/track_detail_title"
|
||||
android:name="com.google.android.apps.mytracks.TrackDetail" >
|
||||
android:label="@string/track_edit_title"
|
||||
android:name="com.google.android.apps.mytracks.TrackEditActivity" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.EDIT" />
|
||||
|
||||
@@ -257,6 +236,11 @@ limitations under the License.
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.google.android.apps.mytracks.TrackListActivity" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.app.default_searchable"
|
||||
android:value="com.google.android.apps.mytracks.SearchActivity" />
|
||||
|
||||
@@ -3,10 +3,21 @@ own licenses, which allow their usage for the My Tracks application. Any other
|
||||
applications that wish to use these files should consult the appropriate
|
||||
licenses or the JAR's authors.
|
||||
|
||||
google-api-client/
|
||||
- see http://code.google.com/p/google-api-java-client/.
|
||||
- contains Google API client library, google-api-client-1.5.0-beta.jar, and its
|
||||
dependencies.
|
||||
Android Support Package:
|
||||
android-support-v4.jar
|
||||
- see http://developer.android.com/sdk/compatibility-library.html
|
||||
|
||||
Google APIs Client Library for Java:
|
||||
commons-codec-1.3.jar
|
||||
commons-logging-1.1.1.jar
|
||||
google-api-client-1.5.0-beta.jar
|
||||
google-http-client-1.5.0-beta.jar
|
||||
google-oauth-client-1.5.0-beta.jar
|
||||
gson-1.6.jar
|
||||
guava-r09.jar
|
||||
jackson-core-asl-1.6.7.jar
|
||||
jsr305-1.3.9.jar
|
||||
- see http://code.google.com/p/google-api-java-client/
|
||||
- google-api-client-1.5.0-beta.jar depends on protobuf-java-2.2.0.jar, however,
|
||||
MyTracksLib already includes protobuf-java.2.3.0-lite.jar. Thus using the
|
||||
newer version, protobuf-java.2.3.0-lite.jar.
|
||||
@@ -14,9 +25,9 @@ google-api-client/
|
||||
some of its classes are already included in the android framework, thus not
|
||||
including xpp3-1.1.4c.jar.
|
||||
|
||||
google-common.jar
|
||||
|
||||
googleloginclient-helper.jar
|
||||
|
||||
Google Analytics:
|
||||
libGoogleAnalytics.jar
|
||||
- see http://code.google.com/mobile/analytics/docs/.
|
||||
- see http://code.google.com/apis/analytics/docs/mobile/android.html
|
||||
|
||||
Others:
|
||||
google-common.jar
|
||||
@@ -1,44 +1,43 @@
|
||||
-target 6
|
||||
-optimizationpasses 5
|
||||
#
|
||||
# Section 1
|
||||
# Default eclipse project proguard settings.
|
||||
#
|
||||
-dontusemixedcaseclassnames
|
||||
-dontskipnonpubliclibraryclasses
|
||||
-dontpreverify
|
||||
-verbose
|
||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
|
||||
# Add the libraries, but ignore warnings about them
|
||||
-libraryjars libs
|
||||
-libraryjars ../MyTracksLib/libs
|
||||
-dontwarn com.google.android.googleapps.**
|
||||
-dontwarn com.android.common.**
|
||||
-dontwarn com.google.android.gsf.**
|
||||
-dontwarn org.codehaus.**
|
||||
-dontwarn com.google.appengine.**
|
||||
-dontwarn org.apache.avalon.framework.logger.**
|
||||
-dontwarn org.apache.log.**
|
||||
-dontwarn org.apache.log4j.**
|
||||
-dontwarn javax.servlet.**
|
||||
-dontpreverify
|
||||
|
||||
# Make our stack traces useful
|
||||
# Line numbers will be correct, file names will be replaced by "MT" since the
|
||||
# class name is enough to get the file name.
|
||||
-renamesourcefileattribute MT
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
|
||||
# change from 5 to 2. With 5 passes, the CursorLoader in the android.support.v4 will not compile.
|
||||
# See http://stackoverflow.com/questions/6605971/android-sdk-tools-revision-12-has-problem-with-proguard-error-conversion-to
|
||||
-optimizationpasses 2
|
||||
-allowaccessmodification
|
||||
|
||||
# Keep everything android references from XMLs
|
||||
-keepattributes *Annotation*
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Application
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.app.backup.BackupAgent
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class * extends android.app.backup.BackupAgent
|
||||
-keep public class * extends android.preference.Preference
|
||||
-keep public class * extends android.support.v4.app.Fragment
|
||||
-keep public class * extends android.app.Fragment
|
||||
-keep public class com.android.vending.licensing.ILicensingService
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
-keep public class * extends android.view.View {
|
||||
public <init>(android.content.Context);
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
public void set*(...);
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
}
|
||||
@@ -47,6 +46,11 @@
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
}
|
||||
|
||||
-keepclassmembers class * extends android.app.Activity {
|
||||
public void *(android.view.View);
|
||||
}
|
||||
|
||||
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
@@ -56,20 +60,55 @@
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
||||
|
||||
# Needed by google-api-client to keep generic types and @Key annotations accessed via reflection
|
||||
-keepclassmembers class **.R$* {
|
||||
public static <fields>;
|
||||
}
|
||||
|
||||
# The support library contains references to newer platform versions.
|
||||
# Don't warn about those in case this app is linking against an older
|
||||
# platform version. We know about them, and they are safe.
|
||||
-dontwarn android.support.**
|
||||
|
||||
#
|
||||
# Section 2
|
||||
# Google APIs Client Library for Java proguard settings.
|
||||
#
|
||||
|
||||
# Needed by google-api-client to keep generic types and @Key annotations accessed via reflection
|
||||
-keepclassmembers class * {
|
||||
@com.google.api.client.util.Key <fields>;
|
||||
}
|
||||
|
||||
-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
|
||||
|
||||
# Needed by Guava
|
||||
|
||||
-dontwarn sun.misc.Unsafe
|
||||
|
||||
# See https://groups.google.com/forum/#!topic/guava-discuss/YCZzeCiIVoI
|
||||
-dontwarn com.google.common.collect.MinMaxPriorityQueue
|
||||
|
||||
#
|
||||
# Section 3
|
||||
# My Tracks specific proguard settings.
|
||||
#
|
||||
|
||||
# Add the libraries, but ignore warnings about them
|
||||
-libraryjars libs
|
||||
-libraryjars ../MyTracksLib/libs
|
||||
-dontwarn com.android.common.**
|
||||
-dontwarn com.google.android.googleapps.**
|
||||
-dontwarn com.google.android.gsf.**
|
||||
-dontwarn javax.servlet.**
|
||||
-dontwarn org.apache.avalon.framework.logger.**
|
||||
-dontwarn org.apache.log.**
|
||||
-dontwarn org.apache.log4j.**
|
||||
|
||||
# Make our stack traces useful
|
||||
# Line numbers will be correct, file names will be replaced by "MT" since the
|
||||
# class name is enough to get the file name.
|
||||
-renamesourcefileattribute MT
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# Keep services needed by ANT+ protocol
|
||||
-keep public class com.dsi.ant.IAnt_6
|
||||
-keep public class com.dsi.ant.IAnt
|
||||
-keep public class com.dsi.ant.IServiceSettings
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
@@ -59,23 +59,4 @@ limitations under the License.
|
||||
android:minHeight="80dp"
|
||||
android:layout_gravity="center"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_gravity="center"
|
||||
android:paddingTop="10dp">
|
||||
<LinearLayout
|
||||
android:layout_width = "wrap_content"
|
||||
android:layout_height= "wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
<ImageButton
|
||||
android:id="@+id/showOptions"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"
|
||||
android:visibility="visible"
|
||||
android:src="@android:drawable/ic_menu_more"/>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -35,7 +35,7 @@ limitations under the License.
|
||||
<TextView
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:text="@string/track_detail_track_name"
|
||||
android:text="@string/track_edit_track_name"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:layout_height="wrap_content"
|
||||
@@ -53,8 +53,8 @@ limitations under the License.
|
||||
/>
|
||||
<EditText
|
||||
android:inputType="textAutoCorrect|textCapWords"
|
||||
android:hint="@string/track_detail_track_name"
|
||||
android:id="@+id/track_detail_track_name"
|
||||
android:hint="@string/track_edit_track_name"
|
||||
android:id="@+id/track_edit_track_name"
|
||||
android:imeOptions="actionNext"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
@@ -65,24 +65,24 @@ limitations under the License.
|
||||
<TextView
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:text="@string/track_detail_activity_type"
|
||||
android:text="@string/track_edit_activity_type"
|
||||
/>
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/track_detail_activity_type"
|
||||
android:id="@+id/track_edit_activity_type"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:hint="@string/track_detail_activity_type_hint"
|
||||
android:hint="@string/track_edit_activity_type_hint"
|
||||
android:imeOptions="actionNext"/>
|
||||
<TextView
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:text="@string/track_detail_track_description"
|
||||
android:text="@string/track_edit_track_description"
|
||||
/>
|
||||
<EditText
|
||||
android:inputType="textAutoCorrect|textCapSentences"
|
||||
android:hint="@string/track_detail_track_description"
|
||||
android:id="@+id/track_detail_track_description"
|
||||
android:hint="@string/track_edit_track_description"
|
||||
android:id="@+id/track_edit_track_description"
|
||||
android:imeOptions="actionDone"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
@@ -95,13 +95,13 @@ limitations under the License.
|
||||
<LinearLayout style="@style/ButtonLayout">
|
||||
<LinearLayout style="@style/ButtonSpacer"/>
|
||||
<Button
|
||||
android:id="@+id/track_detail_save"
|
||||
android:id="@+id/track_edit_save"
|
||||
android:layout_gravity="left"
|
||||
android:text="@string/generic_save"
|
||||
style="@style/Button"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/track_detail_cancel"
|
||||
android:id="@+id/track_edit_cancel"
|
||||
android:layout_gravity="right"
|
||||
android:text="@string/generic_cancel"
|
||||
style="@style/Button"
|
||||
@@ -15,48 +15,74 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<item
|
||||
android:icon="@drawable/menu_record_track"
|
||||
android:id="@+id/menu_record_track"
|
||||
android:showAsAction="always"
|
||||
android:title="@string/menu_record_track"/>
|
||||
<item
|
||||
android:icon="@drawable/menu_stop_recording"
|
||||
android:id="@+id/menu_stop_recording"
|
||||
android:showAsAction="always"
|
||||
android:title="@string/menu_stop_recording"/>
|
||||
<item
|
||||
android:icon="@drawable/ic_menu_tracklist"
|
||||
android:id="@+id/menu_tracks"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/menu_tracks"/>
|
||||
android:icon="@drawable/menu_insert_marker"
|
||||
android:id="@+id/menu_insert_marker"
|
||||
android:showAsAction="always"
|
||||
android:title="@string/menu_insert_marker"/>
|
||||
<item
|
||||
android:icon="@drawable/menu_play"
|
||||
android:id="@+id/menu_play"
|
||||
android:showAsAction="always"
|
||||
android:title="@string/menu_play"/>
|
||||
<item
|
||||
android:icon="@drawable/menu_share"
|
||||
android:id="@+id/menu_share"
|
||||
android:showAsAction="always"
|
||||
android:title="@string/menu_share">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/menu_share_map"
|
||||
android:title="@string/menu_share_map"/>
|
||||
<item
|
||||
android:id="@+id/menu_share_fusion_table"
|
||||
android:title="@string/menu_share_fusion_table"/>
|
||||
<item android:id="@+id/menu_share_gpx"/>
|
||||
<item android:id="@+id/menu_share_kml"/>
|
||||
<item android:id="@+id/menu_share_csv"/>
|
||||
<item android:id="@+id/menu_share_tcx"/>
|
||||
</menu>
|
||||
</item>
|
||||
<item
|
||||
android:icon="@drawable/ic_menu_waypoints"
|
||||
android:id="@+id/menu_markers"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/menu_markers"/>
|
||||
<item
|
||||
android:icon="@drawable/ic_menu_chartsettings"
|
||||
android:id="@+id/menu_chart_settings"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/menu_chart_settings"
|
||||
android:visible="false"/>
|
||||
android:id="@+id/menu_send_google"
|
||||
android:title="@string/menu_send_google"/>
|
||||
<item
|
||||
android:id="@+id/menu_save"
|
||||
android:title="@string/menu_save">
|
||||
<menu>
|
||||
<item android:id="@+id/menu_save_gpx"/>
|
||||
<item android:id="@+id/menu_save_kml"/>
|
||||
<item android:id="@+id/menu_save_csv"/>
|
||||
<item android:id="@+id/menu_save_tcx"/>
|
||||
</menu>
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/menu_edit"
|
||||
android:title="@string/menu_edit"/>
|
||||
<item
|
||||
android:id="@+id/menu_delete"
|
||||
android:title="@string/menu_delete"/>
|
||||
<item
|
||||
android:icon="@android:drawable/ic_menu_mylocation"
|
||||
android:id="@+id/menu_my_location"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/menu_my_location"
|
||||
android:visible="false"/>
|
||||
android:title="@string/menu_my_location"/>
|
||||
<item
|
||||
android:icon="@android:drawable/ic_menu_mapmode"
|
||||
android:id="@+id/menu_satellite_mode"
|
||||
android:showAsAction="ifRoom"
|
||||
android:title="@string/menu_satellite_mode"
|
||||
android:visible="false"/>
|
||||
android:title="@string/menu_satellite_mode"/>
|
||||
<item
|
||||
android:icon="@drawable/menu_search"
|
||||
android:id="@+id/menu_search"
|
||||
android:title="@string/menu_search"/>
|
||||
android:icon="@drawable/ic_menu_chartsettings"
|
||||
android:id="@+id/menu_chart_settings"
|
||||
android:title="@string/menu_chart_settings"/>
|
||||
<item
|
||||
android:icon="@drawable/ic_menu_sensorstatus"
|
||||
android:id="@+id/menu_sensor_state"
|
||||
@@ -65,9 +91,6 @@ limitations under the License.
|
||||
android:icon="@drawable/menu_settings"
|
||||
android:id="@+id/menu_settings"
|
||||
android:title="@string/menu_settings"/>
|
||||
<item
|
||||
android:id="@+id/menu_aggregated_statistics"
|
||||
android:title="@string/menu_aggregated_statistics"/>
|
||||
<item
|
||||
android:icon="@drawable/menu_help"
|
||||
android:id="@+id/menu_help"
|
||||
@@ -977,10 +977,25 @@ limitations under the License.
|
||||
translation_description="In the menu, to delete all the tracks.">
|
||||
Delete all
|
||||
</string>
|
||||
<string name="menu_delete"
|
||||
translation_description="In the menu, to delete a track or a marker.">
|
||||
Delete
|
||||
</string>
|
||||
<string name="menu_edit"
|
||||
translation_description="In the menu, to edit a track or a marker.">
|
||||
Edit
|
||||
</string>
|
||||
<string name="menu_export_all"
|
||||
translation_description="In the menu, to export all the tracks to the SD card.">
|
||||
Export all
|
||||
</string>
|
||||
<string name="menu_export_all_format"
|
||||
translation_description="Under the 'Export all' menu option, the option to export all tracks as
|
||||
a certain file format.
|
||||
|
||||
%1$s: file format. 'GPX', 'KML', 'CSV', or 'TCX'.">
|
||||
Export as %1$s
|
||||
</string>
|
||||
<string name="menu_help"
|
||||
translation_description="In the menu, to go to the help page.">
|
||||
Help
|
||||
@@ -989,6 +1004,10 @@ limitations under the License.
|
||||
translation_description="In the menu, to import all the tracks from the SD card.">
|
||||
Import all
|
||||
</string>
|
||||
<string name="menu_insert_marker"
|
||||
translation_description="In the menu, to insert a marker.">
|
||||
Insert marker
|
||||
</string>
|
||||
<string name="menu_map_mode"
|
||||
translation_description="In the menu, to switch the display to the map mode.">
|
||||
Map mode
|
||||
@@ -1001,6 +1020,10 @@ limitations under the License.
|
||||
translation_description="In the menu, to display the user's current location.">
|
||||
My location
|
||||
</string>
|
||||
<string name="menu_play"
|
||||
translation_description="In the menu, to play a track.">
|
||||
Play
|
||||
</string>
|
||||
<string name="menu_record_track"
|
||||
translation_description="In the menu, to start recording a track.">
|
||||
Record track
|
||||
@@ -1009,10 +1032,25 @@ limitations under the License.
|
||||
translation_description="In the menu, to switch the display to the satellite mode.">
|
||||
Satellite mode
|
||||
</string>
|
||||
<string name="menu_save"
|
||||
translation_description="In the menu, to save a track to the SD card.">
|
||||
Save to SD card...
|
||||
</string>
|
||||
<string name="menu_save_format"
|
||||
translation_description="Under the 'Save to SD card...' menu option, the option to save a track
|
||||
as a certain file format.
|
||||
|
||||
%1$s: file format. 'GPX', 'KML', 'CSV', or 'TCX'.">
|
||||
As a %1$s file
|
||||
</string>
|
||||
<string name="menu_search"
|
||||
translation_description="In the menu, to start a textual search for tracks or waypoints.">
|
||||
Search
|
||||
</string>
|
||||
<string name="menu_send_google"
|
||||
translation_description="In the menu, to send a track to Google.">
|
||||
Send to Google...
|
||||
</string>
|
||||
<string name="menu_sensor_state"
|
||||
translation_description="In the menu, to go to the sensor state page.">
|
||||
Sensor state
|
||||
@@ -1025,11 +1063,31 @@ limitations under the License.
|
||||
translation_description="In the menu, to stop recording a track.">
|
||||
Stop recording
|
||||
</string>
|
||||
<string name="menu_tracks"
|
||||
translation_description="In the menu, to show a list of all the tracks.">
|
||||
Tracks
|
||||
<string name="menu_share"
|
||||
translation_description="In the menu, to share a track with friends through other
|
||||
applications.">
|
||||
Share with friends...
|
||||
</string>
|
||||
<string name="menu_share_file"
|
||||
translation_description="Under the 'Share with friends...' menu option, the option to share a
|
||||
track as a certain file format.
|
||||
|
||||
%1$s: file format. 'GPX', 'KML', 'CSV', or 'TCX'.">
|
||||
A %1$s file
|
||||
</string>
|
||||
<string name="menu_share_fusion_table"
|
||||
translation_description="Under the 'Share with friends...' menu option, the option to save a
|
||||
track to Google Fusion Tables and share the Fusion Table url with friends. 'Fusion Table' in
|
||||
this context means a Google Fusion Table.">
|
||||
Fusion Table
|
||||
</string>
|
||||
<string name="menu_share_map"
|
||||
translation_description="Under the 'Share with friends...' menu option, the option to save a
|
||||
track to Google Maps and share the Map url with friends. 'Map' in this context means a Google
|
||||
Map.">
|
||||
Map
|
||||
</string>
|
||||
|
||||
<!-- My Location -->
|
||||
<string name="my_location_approximate_location"
|
||||
translation_description="When displaying the user's current location, a status message
|
||||
@@ -1200,6 +1258,13 @@ limitations under the License.
|
||||
search results.">
|
||||
No tracks or waypoints matched your search.
|
||||
</string>
|
||||
<string name="search_track_location"
|
||||
translation_description="In the 'Search Result' page, the text field indicating the track that a
|
||||
waypoint belongs to.
|
||||
|
||||
%1$s: track name. E.g., 'Grand Canyon trail'">
|
||||
In track \'%1$s\'.
|
||||
</string>
|
||||
<string name="search_voice_prompt"
|
||||
translation_description="Prompt shown when the user activates voice search, asking him to speak
|
||||
what will be searched for.">
|
||||
@@ -2238,196 +2303,71 @@ limitations under the License.
|
||||
</string>
|
||||
|
||||
<!-- Track -->
|
||||
<string name="track_detail_activity_type"
|
||||
translation_description="In the detail page for a track, the text field for the activity type,
|
||||
including for examples.
|
||||
|
||||
Screenshot: track_detail.png">
|
||||
Activity type (e.g. hiking, cycling, running...)
|
||||
<string name="track_detail_delete_confirm_message"
|
||||
translation_description="When deleting a track, the confirmation message informing the user that
|
||||
the track and its markers will be permanently deleted from the phone.">
|
||||
The track and its markers will be permanently deleted from the phone.
|
||||
</string>
|
||||
<string name="track_detail_activity_type_hint"
|
||||
translation_description="In the detail page for a track, the hint in the 'Activity type' text
|
||||
field when it is empty.
|
||||
|
||||
Screenshot: track_detail.png">
|
||||
Activity type
|
||||
</string>
|
||||
<string name="track_detail_title"
|
||||
translation_description="In the detail page for a track, the title of the page.
|
||||
|
||||
Screenshot: track_detail.png">
|
||||
Track details
|
||||
</string>
|
||||
<string name="track_detail_track_description"
|
||||
translation_description="In the detail page for a track, the text field for the track
|
||||
description.
|
||||
|
||||
Screenshot: track_detail.png">
|
||||
Track description
|
||||
</string>
|
||||
<string name="track_detail_track_name"
|
||||
translation_description="In the detail page for a track, the text field for the track name.
|
||||
|
||||
Screenshot: track_detail.png">
|
||||
Track name
|
||||
<string name="track_detail_install_earth_message"
|
||||
translation_description="When playing a track, the message informing the user that he needs
|
||||
Google Earth to play the track and asking him if he wants to install Google Earth from the
|
||||
Play Store.">
|
||||
You need Google Earth to play the track. Do you want to install from the Play Store?
|
||||
</string>
|
||||
<string name="track_icon_description"
|
||||
translation_description="The accessibility description for the track icon.">
|
||||
Track
|
||||
</string>
|
||||
<string name="track_list_clear_map"
|
||||
translation_description="In the context menu for a track, the menu option to clear the map of
|
||||
any track.
|
||||
|
||||
Screenshot: track_list_context_menu.png">
|
||||
Clear map
|
||||
<string name="track_edit_activity_type"
|
||||
translation_description="In the page to edit a track, the title for the text field to edit the
|
||||
activity type, including some examples of activity types.">
|
||||
Activity type (e.g. hiking, cycling, running...)
|
||||
</string>
|
||||
<string name="track_list_context_menu_title"
|
||||
translation_description="In the context menu for a track, the title indicating that all the menu
|
||||
options below are for this track.
|
||||
|
||||
Screenshot: track_list_context_menu.png">
|
||||
This track
|
||||
<string name="track_edit_activity_type_hint"
|
||||
translation_description="In the page to edit a track, the hint in the 'Activity type' text field
|
||||
when it is empty.">
|
||||
Activity type
|
||||
</string>
|
||||
<string name="track_edit_title"
|
||||
translation_description="The title of the page to edit a track.">
|
||||
Edit track
|
||||
</string>
|
||||
<string name="track_edit_track_description"
|
||||
translation_description="In the page to edit a track, the title for the text field to edit the
|
||||
track description.">
|
||||
Track description
|
||||
</string>
|
||||
<string name="track_edit_track_name"
|
||||
translation_description="In the page to edit a track, the title for the text field to edit the
|
||||
track name.">
|
||||
Track name
|
||||
</string>
|
||||
<string name="track_list_delete_all_confirm_message"
|
||||
translation_description="In the 'Tracks' page, when pressing the 'Delete all' button, the
|
||||
confirmation dialog message informing the user that all tracks and markers will be permanently
|
||||
deleted from the phone.
|
||||
|
||||
Screenshot: track_list_delete_all_confirm_message.png">
|
||||
translation_description="When deleting all the tracks, the confirmation dialog message informing
|
||||
the user that all tracks and markers will be permanently deleted from the phone.">
|
||||
All tracks and markers will be permanently deleted from the phone.
|
||||
</string>
|
||||
<string name="track_list_delete_track"
|
||||
translation_description="In the context menu for a track, the menu option to delete the
|
||||
track from the phone.
|
||||
|
||||
Screenshot: track_list_context_menu.png">
|
||||
Delete from phone...
|
||||
<string name="track_list_record_error"
|
||||
translation_description="When starting a new track recording, the error message informing the
|
||||
user not able to record and asking the user to try again.">
|
||||
Unable to start recording. No GPS location. Try again.
|
||||
</string>
|
||||
<string name="track_list_delete_track_confirm_message"
|
||||
translation_description="In the context menu for a track, when pressing the 'Delete from
|
||||
phone...' option, the confirmation dialog message informing the user that the track and its
|
||||
markers will be permanently deleted from the phone.
|
||||
|
||||
Screenshot: track_list_delete_track_confirm_message.png">
|
||||
The track and its markers will be permanently deleted from the phone.
|
||||
</string>
|
||||
<string name="track_list_edit_track"
|
||||
translation_description="In the context menu for a track, the menu option to edit the track's
|
||||
metadata (e.g., name, activity type, etc.).
|
||||
|
||||
Screenshot: track_list_context_menu.png">
|
||||
Edit
|
||||
</string>
|
||||
<string name="track_list_export_file"
|
||||
translation_description="In the 'Tracks' page, after pressing the 'Export all' button, the menu
|
||||
option to export all the tracks as a certain file format
|
||||
|
||||
%1$s: file format. 'GPX', 'KML', 'CSV', or 'TCX'.
|
||||
Screenshot: track_list_export_file.png">
|
||||
Export as %1$s
|
||||
</string>
|
||||
<string name="track_list_play"
|
||||
translation_description="In the context menu for a track, the menu option to play the track.">
|
||||
Play
|
||||
</string>
|
||||
<string name="track_list_play_install_earth_message"
|
||||
translation_description="After pressing the menu option to play a track, the message informing
|
||||
the user that he needs Google Earth to play the track and asking him if he wants to install
|
||||
Google Earth from the Android Market.">
|
||||
You need Google Earth to play the track. Do you want to install from the Market?
|
||||
</string>
|
||||
<string name="track_list_save_file"
|
||||
translation_description="In the context menu for a track, under the 'Save to SD card...'
|
||||
option, the menu option to save the track as a certain file format.
|
||||
|
||||
%1$s: file format. 'GPX', 'KML', 'CSV', or 'TCX'.
|
||||
Screenshot: track_list_save_file.png">
|
||||
As a %1$s file
|
||||
</string>
|
||||
<string name="track_list_save_sd"
|
||||
translation_description="In the context menu for a track, the menu option to save the track to
|
||||
the SD card.
|
||||
|
||||
Screenshot: track_list_context_menu.png">
|
||||
Save to SD card...
|
||||
</string>
|
||||
<string name="track_list_send_google"
|
||||
translation_description="In the context menu for a track, the menu option to send the track to
|
||||
Google.
|
||||
|
||||
Screenshot: track_list_context_menu.png">
|
||||
Send to Google...
|
||||
</string>
|
||||
<string name="track_list_share_file"
|
||||
translation_description="In the context menu for a track, under the 'Share with friends...'
|
||||
option, the menu option to share the track as a certain file format.
|
||||
|
||||
%1$s: file format. 'GPX', 'KML', 'CSV', or 'TCX'.
|
||||
Screenshot: track_list_share_options.png">
|
||||
A %1$s file
|
||||
</string>
|
||||
<string name="track_list_share_fusion_table"
|
||||
translation_description="In the context menu for a track, under the 'Share with friends...'
|
||||
option, the menu option to save a track to Google Fusion Tables and share the Fusion Table
|
||||
with friends. 'Fusion Table' in this context means a Google Fusion Table.">
|
||||
Fusion Table
|
||||
</string>
|
||||
<string name="track_list_share_map"
|
||||
translation_description="In the context menu for a track, under the 'Share with friends...'
|
||||
option, the menu option to save a track to Google Maps and share the Map with friends. 'Map'
|
||||
in this context means a Google Map.">
|
||||
Map
|
||||
</string>
|
||||
<string name="track_list_share_track"
|
||||
translation_description="In the context menu for a track, the menu option to share the track
|
||||
with friends through other applications.
|
||||
|
||||
Screenshot: track_list_context_menu.png">
|
||||
Share with friends...
|
||||
</string>
|
||||
<string name="track_list_show_on_map"
|
||||
translation_description="In the context menu for a track, the menu option to show the track on
|
||||
the map.
|
||||
|
||||
Screenshot: track_list_show_on_map.png">
|
||||
Show on map
|
||||
</string>
|
||||
<string name="track_list_track_name"
|
||||
translation_description="In the 'Search Result' page, the text field indicating the track that a
|
||||
waypoint belongs to.
|
||||
|
||||
%1$s: track name. E.g., 'Grand Canyon trail'">
|
||||
In track \'%1$s\'.
|
||||
<string name="track_list_record_success"
|
||||
translation_description="When starting a new track recording, a status message indicating
|
||||
success.">
|
||||
Now recording a new track.
|
||||
</string>
|
||||
<string name="track_name_format"
|
||||
translation_description="When creating a new track, the string format to name the track.
|
||||
|
||||
%1$d: track number. E.g., '1'.
|
||||
Screenshot: track_name_format.png">
|
||||
%1$d: track number. E.g., '1'.">
|
||||
Track %1$d
|
||||
</string>
|
||||
<string name="track_record_error"
|
||||
translation_description="When starting a recording, message when not able to start due to no GPS
|
||||
location and asking the user to try again.
|
||||
|
||||
Screenshot: track_record_error.png">
|
||||
Unable to start recording. No GPS location. Try again.
|
||||
</string>
|
||||
<string name="track_record_notification"
|
||||
translation_description="When recording a track, the message on the My Tracks notification
|
||||
informing the user that My Tracks is actively recording his track.
|
||||
|
||||
Screenshot: track_record_notification.png">
|
||||
informing the user that My Tracks is actively recording his track.">
|
||||
Recording your track...
|
||||
</string>
|
||||
<string name="track_record_success"
|
||||
translation_description="When starting a new track recording, a status message indicating
|
||||
success.
|
||||
|
||||
Screenshot: track_record_success.png">
|
||||
Now recording a new track.
|
||||
</string>
|
||||
|
||||
<!-- Unit -->
|
||||
<string name="unit_feet"
|
||||
|
||||
@@ -36,31 +36,15 @@ public abstract class Constants {
|
||||
/*
|
||||
* onActivityResult request codes:
|
||||
*/
|
||||
public static final int SHOW_TRACK = 0;
|
||||
public static final int SHOW_WAYPOINT = 1;
|
||||
public static final int WELCOME = 2;
|
||||
public static final int SHOW_WAYPOINT = 0;
|
||||
|
||||
/*
|
||||
* Context menu ids. Sorted alphabetically.
|
||||
*/
|
||||
public static final int MENU_CLEAR_MAP = 100;
|
||||
public static final int MENU_DELETE = 101;
|
||||
public static final int MENU_EDIT = 102;
|
||||
public static final int MENU_PLAY = 103;
|
||||
public static final int MENU_SAVE_CSV_FILE = 104;
|
||||
public static final int MENU_SAVE_GPX_FILE = 105;
|
||||
public static final int MENU_SAVE_KML_FILE = 106;
|
||||
public static final int MENU_SAVE_TCX_FILE = 107;
|
||||
public static final int MENU_SEND_TO_GOOGLE = 108;
|
||||
public static final int MENU_SHARE = 109;
|
||||
public static final int MENU_SHARE_CSV_FILE = 110;
|
||||
public static final int MENU_SHARE_FUSION_TABLE = 111;
|
||||
public static final int MENU_SHARE_GPX_FILE = 112;
|
||||
public static final int MENU_SHARE_KML_FILE = 113;
|
||||
public static final int MENU_SHARE_MAP = 114;
|
||||
public static final int MENU_SHARE_TCX_FILE = 115;
|
||||
public static final int MENU_SHOW = 116;
|
||||
public static final int MENU_WRITE_TO_SD_CARD = 117;
|
||||
public static final int MENU_DELETE = 100;
|
||||
public static final int MENU_EDIT = 101;
|
||||
public static final int MENU_SHOW = 102;
|
||||
|
||||
/*
|
||||
* Main screen tab tags:
|
||||
*/
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.util.DialogUtils;
|
||||
import com.google.android.apps.mytracks.util.FileUtils;
|
||||
import com.google.android.apps.mytracks.util.UriUtils;
|
||||
@@ -26,7 +25,6 @@ import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ContentUris;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
@@ -129,7 +127,7 @@ public class ImportActivity extends Activity {
|
||||
.getQuantityString(R.plurals.importGpxFiles, totalCount, totalCount);
|
||||
message = getString(R.string.import_success, successCount, totalFiles, path);
|
||||
}
|
||||
return new AlertDialog.Builder(this).setCancelable(true)
|
||||
return new AlertDialog.Builder(this)
|
||||
.setCancelable(true)
|
||||
.setMessage(message)
|
||||
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@@ -142,12 +140,10 @@ public class ImportActivity extends Activity {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (!importAll && trackId != -1L) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.setDataAndType(
|
||||
ContentUris.withAppendedId(TracksColumns.CONTENT_URI, trackId),
|
||||
TracksColumns.CONTENT_ITEMTYPE);
|
||||
Intent intent = new Intent(ImportActivity.this, TrackDetailActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.putExtra(TrackDetailActivity.TRACK_ID, trackId);
|
||||
startActivity(intent);
|
||||
}
|
||||
finish();
|
||||
|
||||
@@ -23,42 +23,23 @@ import com.google.android.apps.mytracks.content.TrackDataHub;
|
||||
import com.google.android.apps.mytracks.content.TrackDataHub.ListenerDataType;
|
||||
import com.google.android.apps.mytracks.content.TrackDataListener;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.io.file.SaveActivity;
|
||||
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.UploadServiceChooserActivity;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
|
||||
import com.google.android.apps.mytracks.util.DialogUtils;
|
||||
import com.google.android.apps.mytracks.util.GeoRect;
|
||||
import com.google.android.apps.mytracks.util.LocationUtils;
|
||||
import com.google.android.apps.mytracks.util.PlayTrackUtils;
|
||||
import com.google.android.maps.GeoPoint;
|
||||
import com.google.android.maps.MapController;
|
||||
import com.google.android.maps.MapView;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.location.Location;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.provider.Settings;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SubMenu;
|
||||
import android.view.View;
|
||||
import android.view.View.OnCreateContextMenuListener;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
@@ -76,9 +57,6 @@ public class MapActivity extends com.google.android.maps.MapActivity
|
||||
implements View.OnTouchListener, View.OnClickListener,
|
||||
TrackDataListener {
|
||||
|
||||
private static final int DIALOG_INSTALL_EARTH_ID = 0;
|
||||
private static final int DIALOG_DELETE_CURRENT_ID = 1;
|
||||
|
||||
// Saved instance state keys:
|
||||
// ---------------------------
|
||||
|
||||
@@ -133,7 +111,6 @@ public class MapActivity extends com.google.android.maps.MapActivity
|
||||
private LinearLayout messagePane;
|
||||
private TextView messageText;
|
||||
private LinearLayout busyPane;
|
||||
private ImageButton optionsBtn;
|
||||
|
||||
/**
|
||||
* We are not displaying driving directions. Just an arbitrary track that is
|
||||
@@ -185,10 +162,6 @@ public class MapActivity extends com.google.android.maps.MapActivity
|
||||
messagePane = (LinearLayout) findViewById(R.id.messagepane);
|
||||
messageText = (TextView) findViewById(R.id.messagetext);
|
||||
busyPane = (LinearLayout) findViewById(R.id.busypane);
|
||||
optionsBtn = (ImageButton) findViewById(R.id.showOptions);
|
||||
|
||||
optionsBtn.setOnCreateContextMenuListener(contextMenuListener);
|
||||
optionsBtn.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -243,45 +216,6 @@ public class MapActivity extends com.google.android.maps.MapActivity
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
switch (id) {
|
||||
case DIALOG_INSTALL_EARTH_ID:
|
||||
return PlayTrackUtils.createInstallEarthDialog(this);
|
||||
case DIALOG_DELETE_CURRENT_ID:
|
||||
return DialogUtils.createConfirmationDialog(this,
|
||||
R.string.track_list_delete_track_confirm_message,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
long trackId = dataHub.getSelectedTrackId();
|
||||
MyTracksProviderUtils.Factory.get(MapActivity.this).deleteTrack(trackId);
|
||||
// If the deleted track was selected, unselect it.
|
||||
String selectedTrackKey = getString(R.string.selected_track_key);
|
||||
SharedPreferences sharedPreferences = getSharedPreferences(
|
||||
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
if (sharedPreferences.getLong(selectedTrackKey, -1L) == trackId) {
|
||||
Editor editor = sharedPreferences.edit().putLong(selectedTrackKey, -1L);
|
||||
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor);
|
||||
}
|
||||
}
|
||||
});
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Utility functions:
|
||||
// -------------------
|
||||
|
||||
/**
|
||||
* Shows the options button if a track is selected, or hide it if not.
|
||||
*/
|
||||
private void updateOptionsButton(boolean trackSelected) {
|
||||
optionsBtn.setVisibility(
|
||||
trackSelected ? View.VISIBLE : View.INVISIBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if a location is visible.
|
||||
*
|
||||
@@ -451,8 +385,6 @@ public class MapActivity extends com.google.android.maps.MapActivity
|
||||
@Override
|
||||
public void run() {
|
||||
boolean trackSelected = track != null;
|
||||
updateOptionsButton(trackSelected);
|
||||
|
||||
mapOverlay.setTrackDrawingEnabled(trackSelected);
|
||||
|
||||
if (trackSelected) {
|
||||
@@ -473,133 +405,6 @@ public class MapActivity extends com.google.android.maps.MapActivity
|
||||
});
|
||||
}
|
||||
|
||||
private final OnCreateContextMenuListener contextMenuListener =
|
||||
new OnCreateContextMenuListener() {
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
||||
menu.setHeaderTitle(R.string.track_list_context_menu_title);
|
||||
menu.add(Menu.NONE, Constants.MENU_EDIT, Menu.NONE, R.string.track_list_edit_track);
|
||||
if (!dataHub.isRecordingSelected()) {
|
||||
String saveFileFormat = getString(R.string.track_list_save_file);
|
||||
String shareFileFormat = getString(R.string.track_list_share_file);
|
||||
String fileTypes[] = getResources().getStringArray(R.array.file_types);
|
||||
|
||||
menu.add(Menu.NONE, Constants.MENU_PLAY, Menu.NONE, R.string.track_list_play);
|
||||
menu.add(Menu.NONE, Constants.MENU_SEND_TO_GOOGLE, Menu.NONE,
|
||||
R.string.track_list_send_google);
|
||||
SubMenu share = menu.addSubMenu(
|
||||
Menu.NONE, Constants.MENU_SHARE, Menu.NONE, R.string.track_list_share_track);
|
||||
share.add(
|
||||
Menu.NONE, Constants.MENU_SHARE_MAP, Menu.NONE, R.string.track_list_share_map);
|
||||
share.add(Menu.NONE, Constants.MENU_SHARE_FUSION_TABLE, Menu.NONE,
|
||||
R.string.track_list_share_fusion_table);
|
||||
share.add(Menu.NONE, Constants.MENU_SHARE_GPX_FILE, Menu.NONE,
|
||||
String.format(shareFileFormat, fileTypes[0]));
|
||||
share.add(Menu.NONE, Constants.MENU_SHARE_KML_FILE, Menu.NONE,
|
||||
String.format(shareFileFormat, fileTypes[1]));
|
||||
share.add(Menu.NONE, Constants.MENU_SHARE_CSV_FILE, Menu.NONE,
|
||||
String.format(shareFileFormat, fileTypes[2]));
|
||||
share.add(Menu.NONE, Constants.MENU_SHARE_TCX_FILE, Menu.NONE,
|
||||
String.format(shareFileFormat, fileTypes[3]));
|
||||
SubMenu save = menu.addSubMenu(
|
||||
Menu.NONE, Constants.MENU_WRITE_TO_SD_CARD, Menu.NONE, R.string.track_list_save_sd);
|
||||
save.add(Menu.NONE, Constants.MENU_SAVE_GPX_FILE, Menu.NONE,
|
||||
String.format(saveFileFormat, fileTypes[0]));
|
||||
save.add(Menu.NONE, Constants.MENU_SAVE_KML_FILE, Menu.NONE,
|
||||
String.format(saveFileFormat, fileTypes[1]));
|
||||
save.add(Menu.NONE, Constants.MENU_SAVE_CSV_FILE, Menu.NONE,
|
||||
String.format(saveFileFormat, fileTypes[2]));
|
||||
save.add(Menu.NONE, Constants.MENU_SAVE_TCX_FILE, Menu.NONE,
|
||||
String.format(saveFileFormat, fileTypes[3]));
|
||||
menu.add(Menu.NONE, Constants.MENU_CLEAR_MAP, Menu.NONE, R.string.track_list_clear_map);
|
||||
menu.add(Menu.NONE, Constants.MENU_DELETE, Menu.NONE, R.string.track_list_delete_track);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemSelected(int featureId, MenuItem item) {
|
||||
Intent intent;
|
||||
long trackId = dataHub.getSelectedTrackId();
|
||||
switch (item.getItemId()) {
|
||||
case Constants.MENU_EDIT:
|
||||
intent = new Intent(this, TrackDetail.class).putExtra(TrackDetail.TRACK_ID, trackId);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case Constants.MENU_PLAY:
|
||||
if (PlayTrackUtils.isEarthInstalled(this)) {
|
||||
PlayTrackUtils.playTrack(this, trackId);
|
||||
return true;
|
||||
} else {
|
||||
showDialog(DIALOG_INSTALL_EARTH_ID);
|
||||
return true;
|
||||
}
|
||||
case Constants.MENU_SEND_TO_GOOGLE:
|
||||
intent = new Intent(this, UploadServiceChooserActivity.class)
|
||||
.putExtra(SendRequest.SEND_REQUEST_KEY, new SendRequest(trackId, true, true, true));
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case Constants.MENU_SHARE_MAP:
|
||||
intent = new Intent(this, UploadServiceChooserActivity.class)
|
||||
.putExtra(SendRequest.SEND_REQUEST_KEY, new SendRequest(trackId, true, false, false));
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case Constants.MENU_SHARE_FUSION_TABLE:
|
||||
intent = new Intent(this, UploadServiceChooserActivity.class)
|
||||
.putExtra(SendRequest.SEND_REQUEST_KEY, new SendRequest(trackId, false, true, false));
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case Constants.MENU_SHARE_GPX_FILE:
|
||||
startSaveActivity(trackId, TrackFileFormat.GPX, true);
|
||||
return true;
|
||||
case Constants.MENU_SHARE_KML_FILE:
|
||||
startSaveActivity(trackId, TrackFileFormat.KML, true);
|
||||
return true;
|
||||
case Constants.MENU_SHARE_CSV_FILE:
|
||||
startSaveActivity(trackId, TrackFileFormat.CSV, true);
|
||||
return true;
|
||||
case Constants.MENU_SHARE_TCX_FILE:
|
||||
startSaveActivity(trackId, TrackFileFormat.TCX, true);
|
||||
return true;
|
||||
case Constants.MENU_SAVE_GPX_FILE:
|
||||
startSaveActivity(trackId, TrackFileFormat.GPX, false);
|
||||
return true;
|
||||
case Constants.MENU_SAVE_KML_FILE:
|
||||
startSaveActivity(trackId, TrackFileFormat.KML, false);
|
||||
return true;
|
||||
case Constants.MENU_SAVE_CSV_FILE:
|
||||
startSaveActivity(trackId, TrackFileFormat.CSV, false);
|
||||
return true;
|
||||
case Constants.MENU_SAVE_TCX_FILE:
|
||||
startSaveActivity(trackId, TrackFileFormat.TCX, false);
|
||||
return true;
|
||||
case Constants.MENU_CLEAR_MAP:
|
||||
dataHub.unloadCurrentTrack();
|
||||
return true;
|
||||
case Constants.MENU_DELETE:
|
||||
showDialog(DIALOG_DELETE_CURRENT_ID);
|
||||
return true;
|
||||
default:
|
||||
return super.onMenuItemSelected(featureId, item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the {@link SaveActivity} to save a track.
|
||||
*
|
||||
* @param trackId the track id
|
||||
* @param trackFileFormat the track file format
|
||||
* @param shareTrack true to share the track after saving
|
||||
*/
|
||||
private void startSaveActivity(
|
||||
long trackId, TrackFileFormat trackFileFormat, boolean shareTrack) {
|
||||
Intent intent = new Intent(this, SaveActivity.class)
|
||||
.putExtra(SaveActivity.EXTRA_TRACK_ID, trackId)
|
||||
.putExtra(SaveActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) trackFileFormat)
|
||||
.putExtra(SaveActivity.EXTRA_SHARE_TRACK, shareTrack);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the map is currently in satellite view mode.
|
||||
*/
|
||||
@@ -618,8 +423,6 @@ public class MapActivity extends com.google.android.maps.MapActivity
|
||||
public void onClick(View v) {
|
||||
if (v == messagePane) {
|
||||
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
|
||||
} else if (v == optionsBtn) {
|
||||
optionsBtn.performLongClick();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import static com.google.android.apps.mytracks.Constants.CHART_TAB_TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.MAP_TAB_TAG;
|
||||
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
/**
|
||||
* Manage the application menus.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
class MenuManager {
|
||||
|
||||
private final MyTracks activity;
|
||||
private MenuItem recordTrack;
|
||||
private MenuItem stopRecording;
|
||||
|
||||
public MenuManager(MyTracks activity) {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the menu with its initial options.
|
||||
*
|
||||
* @param menu the menu to fill
|
||||
* @return true on success, false otherwise
|
||||
*/
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
activity.getMenuInflater().inflate(R.menu.main, menu);
|
||||
|
||||
// TODO: Replace search button with search widget if API level >= 11
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the menu for display.
|
||||
*
|
||||
* @param menu the menu to update for display
|
||||
* @param hasRecorded whether any track has been recorded
|
||||
* @param isRecording whether we're recording a track now
|
||||
* @param hasSelectedTrack whether there's a track currently selected for display
|
||||
* @param isSatelliteMode whether the map is currently in satellite mode
|
||||
* @param currentTabTag the tag for the currently-displayed tab
|
||||
*/
|
||||
public void onPrepareOptionsMenu(Menu menu, boolean hasRecorded,
|
||||
boolean isRecording, boolean hasSelectedTrack,
|
||||
boolean isSatelliteMode, String currentTabTag) {
|
||||
menu.findItem(R.id.menu_markers)
|
||||
.setEnabled(hasRecorded && hasSelectedTrack);
|
||||
|
||||
recordTrack = menu.findItem(R.id.menu_record_track);
|
||||
stopRecording = menu.findItem(R.id.menu_stop_recording);
|
||||
updateActionItems(isRecording);
|
||||
|
||||
menu.findItem(R.id.menu_chart_settings)
|
||||
.setVisible(CHART_TAB_TAG.equals(currentTabTag));
|
||||
|
||||
boolean isMapTab = MAP_TAB_TAG.equals(currentTabTag);
|
||||
menu.findItem(R.id.menu_my_location)
|
||||
.setVisible(isMapTab);
|
||||
menu.findItem(R.id.menu_satellite_mode)
|
||||
.setVisible(isMapTab)
|
||||
.setTitle(isSatelliteMode ? R.string.menu_map_mode : R.string.menu_satellite_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the action items.<br>
|
||||
* TODO: also update the action items when
|
||||
* <ul>
|
||||
* <li>start/stop a recording from the home screen widget.<il>
|
||||
* <li>receive a direct service call to start/stop a recording.<il>
|
||||
* </ul>
|
||||
*
|
||||
* @param isRecording true if recording a track
|
||||
*/
|
||||
private void updateActionItems(boolean isRecording) {
|
||||
recordTrack.setEnabled(!isRecording).setVisible(!isRecording);
|
||||
stopRecording.setEnabled(isRecording).setVisible(isRecording);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an option from the menu is selected.
|
||||
*
|
||||
* @param item the selected item
|
||||
* @return true if the action was handled, false otherwise
|
||||
*/
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_record_track: {
|
||||
activity.startRecording();
|
||||
updateActionItems(true);
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_stop_recording: {
|
||||
activity.stopRecording();
|
||||
updateActionItems(false);
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_tracks: {
|
||||
activity.startActivityForResult(new Intent(activity, TrackListActivity.class),
|
||||
Constants.SHOW_TRACK);
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_markers: {
|
||||
Intent startIntent = new Intent(activity, WaypointsList.class);
|
||||
startIntent.putExtra("trackid", activity.getSelectedTrackId());
|
||||
activity.startActivityForResult(startIntent, Constants.SHOW_WAYPOINT);
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_sensor_state: {
|
||||
return startActivity(SensorStateActivity.class);
|
||||
}
|
||||
case R.id.menu_settings: {
|
||||
return startActivity(SettingsActivity.class);
|
||||
}
|
||||
case R.id.menu_aggregated_statistics: {
|
||||
return startActivity(AggregatedStatsActivity.class);
|
||||
}
|
||||
case R.id.menu_help: {
|
||||
return startActivity(WelcomeActivity.class);
|
||||
}
|
||||
case R.id.menu_search: {
|
||||
// TODO: Pass the current track ID and current location to do some fancier ranking.
|
||||
activity.onSearchRequested();
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_chart_settings: {
|
||||
activity.showChartSettings();
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_my_location: {
|
||||
activity.showMyLocation();
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_satellite_mode: {
|
||||
activity.toggleSatelliteView();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an activity with the given class.
|
||||
*/
|
||||
private boolean startActivity(Class<? extends Activity> activityClass) {
|
||||
activity.startActivity(new Intent(activity, activityClass));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,580 +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 static com.google.android.apps.mytracks.Constants.CHART_TAB_TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.MAP_TAB_TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.STATS_TAB_TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.TrackDataHub;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
import com.google.android.apps.mytracks.content.WaypointsColumns;
|
||||
import com.google.android.apps.mytracks.services.ITrackRecordingService;
|
||||
import com.google.android.apps.mytracks.services.ServiceUtils;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
|
||||
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.UriUtils;
|
||||
import com.google.android.maps.mytracks.BuildConfig;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.TabActivity;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* The super activity that embeds our sub activities.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class MyTracks extends TabActivity implements OnTouchListener {
|
||||
private static final int DIALOG_EULA_ID = 0;
|
||||
private static final int DIALOG_CHECK_UNITS_ID = 1;
|
||||
private static final String CHECK_UNITS_PREFERENCE_FILE = "checkunits";
|
||||
private static final String CHECK_UNITS_PREFERENCE_KEY = "checkunits.checked";
|
||||
|
||||
private TrackDataHub dataHub;
|
||||
|
||||
/**
|
||||
* Menu manager.
|
||||
*/
|
||||
private MenuManager menuManager;
|
||||
|
||||
/**
|
||||
* Preferences.
|
||||
*/
|
||||
private SharedPreferences preferences;
|
||||
|
||||
/**
|
||||
* True if a new track should be created after the track recording service
|
||||
* binds.
|
||||
*/
|
||||
private boolean startNewTrackRequested = false;
|
||||
|
||||
/**
|
||||
* Utilities to deal with the database.
|
||||
*/
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
|
||||
/*
|
||||
* Tabs/View navigation:
|
||||
*/
|
||||
|
||||
private NavControls navControls;
|
||||
|
||||
private final Runnable changeTab = new Runnable() {
|
||||
public void run() {
|
||||
getTabHost().setCurrentTab(navControls.getCurrentIcons());
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Recording service interaction:
|
||||
*/
|
||||
|
||||
private final Runnable serviceBindCallback = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (serviceConnection) {
|
||||
ITrackRecordingService service = serviceConnection.getServiceIfBound();
|
||||
if (startNewTrackRequested && service != null) {
|
||||
Log.i(TAG, "Starting recording");
|
||||
startNewTrackRequested = false;
|
||||
startRecordingNewTrack(service);
|
||||
} else if (startNewTrackRequested) {
|
||||
Log.w(TAG, "Not yet starting recording");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private TrackRecordingServiceConnection serviceConnection;
|
||||
|
||||
/*
|
||||
* Application lifetime events:
|
||||
* ============================
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
Log.d(TAG, "MyTracks.onCreate");
|
||||
super.onCreate(savedInstanceState);
|
||||
if (BuildConfig.DEBUG) {
|
||||
ApiAdapterFactory.getApiAdapter().enableStrictMode();
|
||||
}
|
||||
|
||||
AnalyticsUtils.sendPageViews(this, "/appstart");
|
||||
|
||||
providerUtils = MyTracksProviderUtils.Factory.get(this);
|
||||
preferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
dataHub = ((MyTracksApplication) getApplication()).getTrackDataHub();
|
||||
menuManager = new MenuManager(this);
|
||||
serviceConnection = new TrackRecordingServiceConnection(this, serviceBindCallback);
|
||||
|
||||
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
|
||||
|
||||
// Show the action bar (or nothing at all).
|
||||
ApiAdapterFactory.getApiAdapter().showActionBar(this);
|
||||
|
||||
// If the user just starts typing (on a device with a keyboard), we start a search.
|
||||
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
|
||||
|
||||
final Resources res = getResources();
|
||||
final TabHost tabHost = getTabHost();
|
||||
tabHost.addTab(tabHost.newTabSpec(MAP_TAB_TAG)
|
||||
.setIndicator("Map", res.getDrawable(
|
||||
android.R.drawable.ic_menu_mapmode))
|
||||
.setContent(new Intent(this, MapActivity.class)));
|
||||
tabHost.addTab(tabHost.newTabSpec(STATS_TAB_TAG)
|
||||
.setIndicator("Stats", res.getDrawable(R.drawable.ic_menu_statistics))
|
||||
.setContent(new Intent(this, StatsActivity.class)));
|
||||
tabHost.addTab(tabHost.newTabSpec(CHART_TAB_TAG)
|
||||
.setIndicator("Chart", res.getDrawable(R.drawable.menu_elevation))
|
||||
.setContent(new Intent(this, ChartActivity.class)));
|
||||
|
||||
// Hide the tab widget itself. We'll use overlayed prev/next buttons to
|
||||
// switch between the tabs:
|
||||
tabHost.getTabWidget().setVisibility(View.GONE);
|
||||
|
||||
RelativeLayout layout = new RelativeLayout(this);
|
||||
LayoutParams params =
|
||||
new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
|
||||
layout.setLayoutParams(params);
|
||||
navControls =
|
||||
new NavControls(this, layout,
|
||||
getResources().obtainTypedArray(R.array.left_icons),
|
||||
getResources().obtainTypedArray(R.array.right_icons),
|
||||
changeTab);
|
||||
navControls.show();
|
||||
tabHost.addView(layout);
|
||||
layout.setOnTouchListener(this);
|
||||
|
||||
if (!EulaUtils.getEulaValue(this)) {
|
||||
showDialog(DIALOG_EULA_ID);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
Log.d(TAG, "MyTracks.onStart");
|
||||
super.onStart();
|
||||
dataHub.start();
|
||||
|
||||
// Ensure that service is running and bound if we're supposed to be recording
|
||||
if (ServiceUtils.isRecording(this, null, preferences)) {
|
||||
serviceConnection.startAndBind();
|
||||
}
|
||||
|
||||
Intent intent = getIntent();
|
||||
String action = intent.getAction();
|
||||
Uri data = intent.getData();
|
||||
if ((Intent.ACTION_VIEW.equals(action) || Intent.ACTION_EDIT.equals(action))
|
||||
&& TracksColumns.CONTENT_ITEMTYPE.equals(intent.getType())
|
||||
&& UriUtils.matchesContentUri(data, TracksColumns.CONTENT_URI)) {
|
||||
long trackId = ContentUris.parseId(data);
|
||||
dataHub.loadTrack(trackId);
|
||||
} else if (Intent.ACTION_VIEW.equals(action)
|
||||
&& WaypointsColumns.CONTENT_ITEMTYPE.equals(intent.getType())
|
||||
&& UriUtils.matchesContentUri(data, WaypointsColumns.CONTENT_URI)) {
|
||||
// TODO(rdamazio): Waypoint URIs should be base/trackid/waypointid
|
||||
long waypointId = ContentUris.parseId(data);
|
||||
Waypoint waypoint = providerUtils.getWaypoint(waypointId);
|
||||
long trackId = waypoint.getTrackId();
|
||||
|
||||
// Request that the waypoint is shown (now or when the right track is loaded).
|
||||
showWaypoint(trackId, waypointId);
|
||||
|
||||
// Load the right track, if not loaded already.
|
||||
dataHub.loadTrack(trackId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
// Called when the current activity is being displayed or re-displayed
|
||||
// to the user.
|
||||
Log.d(TAG, "MyTracks.onResume");
|
||||
serviceConnection.bindIfRunning();
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
// Called when activity is going into the background, but has not (yet) been
|
||||
// killed. Shouldn't block longer than approx. 2 seconds.
|
||||
Log.d(TAG, "MyTracks.onPause");
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
Log.d(TAG, "MyTracks.onStop");
|
||||
dataHub.stop();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
Log.d(TAG, "MyTracks.onDestroy");
|
||||
serviceConnection.unbind();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
switch (id) {
|
||||
case DIALOG_EULA_ID:
|
||||
return new AlertDialog.Builder(this)
|
||||
.setCancelable(true)
|
||||
.setMessage(EulaUtils.getEulaMessage(this))
|
||||
.setNegativeButton(R.string.eula_decline, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
finish();
|
||||
}
|
||||
})
|
||||
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
finish();
|
||||
}
|
||||
})
|
||||
.setPositiveButton(R.string.eula_accept, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
EulaUtils.setEulaValue(MyTracks.this);
|
||||
startActivityForResult(
|
||||
new Intent(MyTracks.this, WelcomeActivity.class), Constants.WELCOME);
|
||||
}
|
||||
})
|
||||
.setTitle(R.string.eula_title)
|
||||
.create();
|
||||
case DIALOG_CHECK_UNITS_ID:
|
||||
return new AlertDialog.Builder(this)
|
||||
.setCancelable(true)
|
||||
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
SharedPreferences sharedPreferences = getSharedPreferences(
|
||||
CHECK_UNITS_PREFERENCE_FILE, Context.MODE_PRIVATE);
|
||||
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(
|
||||
sharedPreferences.edit().putBoolean(CHECK_UNITS_PREFERENCE_KEY, true));
|
||||
}
|
||||
})
|
||||
.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
SharedPreferences sharedPreferences = getSharedPreferences(
|
||||
CHECK_UNITS_PREFERENCE_FILE, Context.MODE_PRIVATE);
|
||||
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(
|
||||
sharedPreferences.edit().putBoolean(CHECK_UNITS_PREFERENCE_KEY, true));
|
||||
|
||||
int position = ((AlertDialog) dialog).getListView().getSelectedItemPosition();
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(
|
||||
editor.putBoolean(getString(R.string.metric_units_key), position == 0));
|
||||
}
|
||||
})
|
||||
.setSingleChoiceItems(new CharSequence[] { getString(R.string.preferred_units_metric),
|
||||
getString(R.string.preferred_units_imperial) }, 0, null)
|
||||
.setTitle(R.string.preferred_units_title)
|
||||
.create();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
super.onCreateOptionsMenu(menu);
|
||||
return menuManager.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
MapActivity map = getMapTab();
|
||||
boolean isSatelliteView = map != null ? map.isSatelliteView() : false;
|
||||
|
||||
menuManager.onPrepareOptionsMenu(menu, providerUtils.getLastTrack() != null,
|
||||
ServiceUtils.isRecording(this, serviceConnection.getServiceIfBound(), preferences),
|
||||
dataHub.isATrackSelected(),
|
||||
isSatelliteView,
|
||||
getTabHost().getCurrentTabTag());
|
||||
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
return menuManager.onOptionsItemSelected(item)
|
||||
? true
|
||||
: super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
/*
|
||||
* Key events:
|
||||
* ===========
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean onTrackballEvent(MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
if (ServiceUtils.isRecording(this, serviceConnection.getServiceIfBound(), preferences)) {
|
||||
try {
|
||||
insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Cannot insert statistics marker.", e);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.e(TAG, "Cannot insert statistics marker.", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.onTrackballEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode,
|
||||
final Intent results) {
|
||||
Log.d(TAG, "MyTracks.onActivityResult");
|
||||
long trackId = dataHub.getSelectedTrackId();
|
||||
if (results != null) {
|
||||
trackId = results.getLongExtra("trackid", trackId);
|
||||
}
|
||||
|
||||
switch (requestCode) {
|
||||
case Constants.SHOW_TRACK: {
|
||||
if (results != null) {
|
||||
if (trackId >= 0) {
|
||||
dataHub.loadTrack(trackId);
|
||||
|
||||
// The track list passed the requested action as result code. Hand
|
||||
// it off to the onActivityResult for further processing:
|
||||
if (resultCode != Constants.SHOW_TRACK) {
|
||||
onActivityResult(resultCode, Activity.RESULT_OK, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Constants.SHOW_WAYPOINT: {
|
||||
if (results != null) {
|
||||
final long waypointId = results.getLongExtra(WaypointDetails.WAYPOINT_ID_EXTRA, -1);
|
||||
if (waypointId >= 0) {
|
||||
MapActivity map = getMapTab();
|
||||
if (map != null) {
|
||||
getTabHost().setCurrentTab(0);
|
||||
map.showWaypoint(waypointId);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Constants.WELCOME: {
|
||||
SharedPreferences sharedPreferences = getSharedPreferences(
|
||||
CHECK_UNITS_PREFERENCE_FILE, Context.MODE_PRIVATE);
|
||||
if (!sharedPreferences.getBoolean(CHECK_UNITS_PREFERENCE_KEY, false)) {
|
||||
showDialog(DIALOG_CHECK_UNITS_ID);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
Log.w(TAG, "Warning unhandled request code: " + requestCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showWaypoint(long trackId, long waypointId) {
|
||||
MapActivity map =
|
||||
(MapActivity) getLocalActivityManager().getActivity("tab1");
|
||||
if (map != null) {
|
||||
getTabHost().setCurrentTab(0);
|
||||
map.showWaypoint(trackId, waypointId);
|
||||
} else {
|
||||
Log.e(TAG, "Couldnt' get map tab");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
navControls.show();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a waypoint marker.
|
||||
*
|
||||
* TODO: Merge with WaypointsList#insertWaypoint.
|
||||
*
|
||||
* @return Id of the inserted statistics marker.
|
||||
* @throws RemoteException If the call on the service failed.
|
||||
*/
|
||||
private long insertWaypoint(WaypointCreationRequest request) throws RemoteException {
|
||||
ITrackRecordingService trackRecordingService = serviceConnection.getServiceIfBound();
|
||||
if (trackRecordingService == null) {
|
||||
throw new IllegalStateException("The recording service is not bound.");
|
||||
}
|
||||
try {
|
||||
long waypointId = trackRecordingService.insertWaypoint(request);
|
||||
if (waypointId >= 0) {
|
||||
Toast.makeText(this, R.string.marker_insert_success, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
return waypointId;
|
||||
} catch (RemoteException e) {
|
||||
Toast.makeText(this, R.string.marker_insert_error, Toast.LENGTH_LONG).show();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void startRecordingNewTrack(
|
||||
ITrackRecordingService trackRecordingService) {
|
||||
try {
|
||||
long recordingTrackId = trackRecordingService.startNewTrack();
|
||||
// Select the recording track.
|
||||
dataHub.loadTrack(recordingTrackId);
|
||||
Toast.makeText(this, getString(R.string.track_record_success), Toast.LENGTH_SHORT).show();
|
||||
// TODO: We catch Exception, because after eliminating the service process
|
||||
// all exceptions it may throw are no longer wrapped in a RemoteException.
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(this, getString(R.string.track_record_error), Toast.LENGTH_SHORT).show();
|
||||
Log.w(TAG, "Unable to start recording.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the track recording service (if not already running) and binds to
|
||||
* it. Starts recording a new track.
|
||||
*/
|
||||
void startRecording() {
|
||||
synchronized (serviceConnection) {
|
||||
startNewTrackRequested = true;
|
||||
serviceConnection.startAndBind();
|
||||
|
||||
// Binding was already requested before, it either already happened
|
||||
// (in which case running the callback manually triggers the actual recording start)
|
||||
// or it will happen in the future
|
||||
// (in which case running the callback now will have no effect).
|
||||
serviceBindCallback.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the track recording service and unbinds from it. Will display a toast
|
||||
* "Stopped recording" and pop up the Track Details activity.
|
||||
*/
|
||||
void stopRecording() {
|
||||
// Save the track id as the shared preference will overwrite the recording track id.
|
||||
SharedPreferences sharedPreferences = getSharedPreferences(
|
||||
Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
long currentTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1);
|
||||
|
||||
ITrackRecordingService trackRecordingService = serviceConnection.getServiceIfBound();
|
||||
if (trackRecordingService != null) {
|
||||
try {
|
||||
trackRecordingService.endCurrentTrack();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unable to stop recording.", e);
|
||||
}
|
||||
}
|
||||
|
||||
serviceConnection.stop();
|
||||
|
||||
if (currentTrackId > 0) {
|
||||
Intent intent = new Intent(MyTracks.this, TrackDetail.class);
|
||||
intent.putExtra(TrackDetail.TRACK_ID, currentTrackId);
|
||||
intent.putExtra(TrackDetail.SHOW_CANCEL, false);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
long getSelectedTrackId() {
|
||||
return dataHub.getSelectedTrackId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the chart tab to show its settings.
|
||||
*/
|
||||
public void showChartSettings() {
|
||||
ChartActivity chart = getChartTab();
|
||||
if (chart != null) {
|
||||
chart.showChartSettingsDialog();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the map tab to show the map in satellite mode.
|
||||
*/
|
||||
public void toggleSatelliteView() {
|
||||
MapActivity mapTab = getMapTab();
|
||||
if (mapTab != null) {
|
||||
mapTab.setSatelliteView(!mapTab.isSatelliteView());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks the map tab to jump to the current location.
|
||||
*/
|
||||
public void showMyLocation() {
|
||||
MapActivity mapTab = getMapTab();
|
||||
if (mapTab != null) {
|
||||
mapTab.showMyLocation();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the map tab instance if available, or null otherwise.
|
||||
*/
|
||||
private MapActivity getMapTab() {
|
||||
return (MapActivity) getLocalActivityManager().getActivity(MAP_TAB_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the chart tab instance if available, or null otherwise.
|
||||
*/
|
||||
private ChartActivity getChartTab() {
|
||||
return (ChartActivity) getLocalActivityManager().getActivity(CHART_TAB_TAG);
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,9 @@ package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.content.TrackDataHub;
|
||||
import com.google.android.apps.mytracks.services.RemoveTempFilesService;
|
||||
import com.google.android.apps.mytracks.util.AnalyticsUtils;
|
||||
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
|
||||
import com.google.android.maps.mytracks.BuildConfig;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Intent;
|
||||
@@ -32,6 +35,10 @@ public class MyTracksApplication extends Application {
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
if (BuildConfig.DEBUG) {
|
||||
ApiAdapterFactory.getApiAdapter().enableStrictMode();
|
||||
}
|
||||
AnalyticsUtils.sendPageViews(this, "/appstart");
|
||||
startService(new Intent(this, RemoveTempFilesService.class));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,22 +23,18 @@ import com.google.android.apps.mytracks.content.SearchEngine.ScoredResult;
|
||||
import com.google.android.apps.mytracks.content.SearchEngine.SearchQuery;
|
||||
import com.google.android.apps.mytracks.content.SearchEngineProvider;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.WaypointsColumns;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.apps.mytracks.util.StringUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.ListActivity;
|
||||
import android.app.SearchManager;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.provider.SearchRecentSuggestions;
|
||||
import android.util.Log;
|
||||
@@ -193,7 +189,7 @@ public class SearchActivity extends ListActivity {
|
||||
resultMap.put(DESCRIPTION_FIELD, waypoint.getDescription());
|
||||
resultMap.put(CATEGORY_FIELD, waypoint.getCategory());
|
||||
// In the same place as we show time for tracks, show the track name for waypoints.
|
||||
resultMap.put(TIME_FIELD, getString(R.string.track_list_track_name, trackName));
|
||||
resultMap.put(TIME_FIELD, getString(R.string.search_track_location, trackName));
|
||||
resultMap.put(STATS_FIELD, StringUtils.formatDateTime(this, waypoint.getLocation().getTime()));
|
||||
resultMap.put(TRACK_ID_FIELD, waypoint.getTrackId());
|
||||
resultMap.put(WAYPOINT_ID_FIELD, waypoint.getId());
|
||||
@@ -251,15 +247,12 @@ public class SearchActivity extends ListActivity {
|
||||
}
|
||||
|
||||
private Intent createViewDataIntent(Map<String, Object> clickedData) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
Intent intent = new Intent(this, TrackDetailActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
if (clickedData.containsKey(WAYPOINT_ID_FIELD)) {
|
||||
long waypointId = (Long) clickedData.get(WAYPOINT_ID_FIELD);
|
||||
Uri uri = ContentUris.withAppendedId(WaypointsColumns.CONTENT_URI, waypointId);
|
||||
intent.setDataAndType(uri, WaypointsColumns.CONTENT_ITEMTYPE);
|
||||
intent.putExtra(TrackDetailActivity.WAYPOINT_ID, (Long) clickedData.get(WAYPOINT_ID_FIELD));
|
||||
} else {
|
||||
long trackId = (Long) clickedData.get(TRACK_ID_FIELD);
|
||||
Uri uri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, trackId);
|
||||
intent.setDataAndType(uri, TracksColumns.CONTENT_ITEMTYPE);
|
||||
intent.putExtra(TrackDetailActivity.TRACK_ID, (Long) clickedData.get(TRACK_ID_FIELD));
|
||||
}
|
||||
return intent;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,550 @@
|
||||
/*
|
||||
* 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 static com.google.android.apps.mytracks.Constants.CHART_TAB_TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.MAP_TAB_TAG;
|
||||
import static com.google.android.apps.mytracks.Constants.STATS_TAB_TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.TrackDataHub;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
|
||||
import com.google.android.apps.mytracks.io.file.SaveActivity;
|
||||
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.SendRequest;
|
||||
import com.google.android.apps.mytracks.io.sendtogoogle.UploadServiceChooserActivity;
|
||||
import com.google.android.apps.mytracks.services.ITrackRecordingService;
|
||||
import com.google.android.apps.mytracks.services.ServiceUtils;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
|
||||
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
|
||||
import com.google.android.apps.mytracks.util.DialogUtils;
|
||||
import com.google.android.apps.mytracks.util.PlayTrackUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.TabActivity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* An activity to show the track detail.
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
* @author Rodrigo Damazio
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class TrackDetailActivity extends TabActivity implements OnTouchListener {
|
||||
|
||||
public static final String TRACK_ID = "track_id";
|
||||
public static final String WAYPOINT_ID = "waypoint_id";
|
||||
|
||||
private static final String TAG = TrackDetailActivity.class.getSimpleName();
|
||||
private static final int DIALOG_INSTALL_EARTH_ID = 0;
|
||||
private static final int DIALOG_DELETE_CURRENT_ID = 1;
|
||||
|
||||
private SharedPreferences sharedPreferences;
|
||||
private TrackDataHub trackDataHub;
|
||||
private TrackRecordingServiceConnection trackRecordingServiceConnection;
|
||||
private NavControls navControls;
|
||||
|
||||
private MenuItem stopRecordingMenuItem;
|
||||
private MenuItem insertMarkerMenuItem;
|
||||
private MenuItem playMenuItem;
|
||||
private MenuItem shareMenuItem;
|
||||
private MenuItem sendGoogleMenuItem;
|
||||
private MenuItem saveMenuItem;
|
||||
private MenuItem editMenuItem;
|
||||
private MenuItem deleteMenuItem;
|
||||
|
||||
private final Runnable changeTab = new Runnable() {
|
||||
public void run() {
|
||||
getTabHost().setCurrentTab(navControls.getCurrentIcons());
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Note that sharedPreferenceChangeListener cannot be an anonymous inner
|
||||
* class. Anonymous inner class will get garbage collected.
|
||||
*/
|
||||
private final OnSharedPreferenceChangeListener sharedPreferenceChangeListener =
|
||||
new OnSharedPreferenceChangeListener() {
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
// Note that key can be null
|
||||
if (getString(R.string.recording_track_key).equals(key)) {
|
||||
if (isRecording()) {
|
||||
trackRecordingServiceConnection.startAndBind();
|
||||
}
|
||||
updateMenu();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||
trackDataHub = ((MyTracksApplication) getApplication()).getTrackDataHub();
|
||||
trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, null);
|
||||
|
||||
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
|
||||
|
||||
// Show the action bar (or nothing at all).
|
||||
ApiAdapterFactory.getApiAdapter().showActionBar(this);
|
||||
|
||||
final Resources res = getResources();
|
||||
final TabHost tabHost = getTabHost();
|
||||
tabHost.addTab(tabHost.newTabSpec(MAP_TAB_TAG)
|
||||
.setIndicator("Map", res.getDrawable(android.R.drawable.ic_menu_mapmode))
|
||||
.setContent(new Intent(this, MapActivity.class)));
|
||||
tabHost.addTab(tabHost.newTabSpec(STATS_TAB_TAG)
|
||||
.setIndicator("Stats", res.getDrawable(R.drawable.ic_menu_statistics))
|
||||
.setContent(new Intent(this, StatsActivity.class)));
|
||||
tabHost.addTab(tabHost.newTabSpec(CHART_TAB_TAG)
|
||||
.setIndicator("Chart", res.getDrawable(R.drawable.menu_elevation))
|
||||
.setContent(new Intent(this, ChartActivity.class)));
|
||||
|
||||
// Hide the tab widget itself. We'll use overlayed prev/next buttons to
|
||||
// switch between the tabs:
|
||||
tabHost.getTabWidget().setVisibility(View.GONE);
|
||||
|
||||
RelativeLayout layout = new RelativeLayout(this);
|
||||
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
|
||||
layout.setLayoutParams(params);
|
||||
navControls = new NavControls(this, layout, getResources().obtainTypedArray(R.array.left_icons),
|
||||
getResources().obtainTypedArray(R.array.right_icons), changeTab);
|
||||
navControls.show();
|
||||
tabHost.addView(layout);
|
||||
layout.setOnTouchListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
trackDataHub.start();
|
||||
|
||||
if (isRecording()) {
|
||||
trackRecordingServiceConnection.startAndBind();
|
||||
}
|
||||
|
||||
Intent intent = getIntent();
|
||||
long trackId = intent.getLongExtra(TRACK_ID, -1L);
|
||||
if (trackId != -1L) {
|
||||
trackDataHub.loadTrack(trackId);
|
||||
return;
|
||||
}
|
||||
|
||||
long waypointId = intent.getLongExtra(WAYPOINT_ID, -1L);
|
||||
if (waypointId != -1L) {
|
||||
Waypoint waypoint = MyTracksProviderUtils.Factory.get(this).getWaypoint(waypointId);
|
||||
if (waypoint != null) {
|
||||
trackId = waypoint.getTrackId();
|
||||
trackDataHub.loadTrack(trackId);
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
getTabHost().setCurrentTab(0);
|
||||
mapActivity.showWaypoint(trackId, waypointId);
|
||||
} else {
|
||||
Log.e(TAG, "MapActivity is null");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// No track id or waypoint id, return to the track list activity.
|
||||
startTrackListActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
trackRecordingServiceConnection.bindIfRunning();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
trackDataHub.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
trackRecordingServiceConnection.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
switch (id) {
|
||||
case DIALOG_INSTALL_EARTH_ID:
|
||||
return PlayTrackUtils.createInstallEarthDialog(this);
|
||||
case DIALOG_DELETE_CURRENT_ID:
|
||||
return DialogUtils.createConfirmationDialog(this,
|
||||
R.string.track_detail_delete_confirm_message, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
deleteCurrentTrack();
|
||||
startTrackListActivity();
|
||||
}
|
||||
});
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.track_detail, menu);
|
||||
String fileTypes[] = getResources().getStringArray(R.array.file_types);
|
||||
menu.findItem(R.id.menu_save_gpx).setTitle(getString(R.string.menu_save_format, fileTypes[0]));
|
||||
menu.findItem(R.id.menu_save_kml).setTitle(getString(R.string.menu_save_format, fileTypes[1]));
|
||||
menu.findItem(R.id.menu_save_csv).setTitle(getString(R.string.menu_save_format, fileTypes[2]));
|
||||
menu.findItem(R.id.menu_save_tcx).setTitle(getString(R.string.menu_save_format, fileTypes[3]));
|
||||
|
||||
menu.findItem(R.id.menu_share_gpx).setTitle(getString(R.string.menu_share_file, fileTypes[0]));
|
||||
menu.findItem(R.id.menu_share_kml).setTitle(getString(R.string.menu_share_file, fileTypes[1]));
|
||||
menu.findItem(R.id.menu_share_csv).setTitle(getString(R.string.menu_share_file, fileTypes[2]));
|
||||
menu.findItem(R.id.menu_share_tcx).setTitle(getString(R.string.menu_share_file, fileTypes[3]));
|
||||
|
||||
stopRecordingMenuItem = menu.findItem(R.id.menu_stop_recording);
|
||||
insertMarkerMenuItem = menu.findItem(R.id.menu_insert_marker);
|
||||
playMenuItem = menu.findItem(R.id.menu_play);
|
||||
shareMenuItem = menu.findItem(R.id.menu_share);
|
||||
sendGoogleMenuItem = menu.findItem(R.id.menu_send_google);
|
||||
saveMenuItem = menu.findItem(R.id.menu_save);
|
||||
editMenuItem = menu.findItem(R.id.menu_edit);
|
||||
deleteMenuItem = menu.findItem(R.id.menu_delete);
|
||||
|
||||
updateMenu();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
String currentTabTag = getTabHost().getCurrentTabTag();
|
||||
menu.findItem(R.id.menu_chart_settings).setVisible(CHART_TAB_TAG.equals(currentTabTag));
|
||||
menu.findItem(R.id.menu_my_location).setVisible(MAP_TAB_TAG.equals(currentTabTag));
|
||||
|
||||
// Set map or satellite mode
|
||||
MapActivity mapActivity = getMapActivity();
|
||||
boolean isSatelliteMode = mapActivity != null ? mapActivity.isSatelliteView() : false;
|
||||
menu.findItem(R.id.menu_satellite_mode).setVisible(MAP_TAB_TAG.equals(currentTabTag))
|
||||
.setTitle(isSatelliteMode ? R.string.menu_map_mode : R.string.menu_satellite_mode);
|
||||
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
MapActivity mapActivity;
|
||||
Intent intent;
|
||||
long trackId = trackDataHub.getSelectedTrackId();
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_stop_recording:
|
||||
updateMenuItems(false);
|
||||
stopRecording();
|
||||
return true;
|
||||
case R.id.menu_insert_marker:
|
||||
// TODO: Add insert marker when updating WaypointList to ICS
|
||||
return true;
|
||||
case R.id.menu_play:
|
||||
if (PlayTrackUtils.isEarthInstalled(this)) {
|
||||
PlayTrackUtils.playTrack(this, trackId);
|
||||
} else {
|
||||
showDialog(DIALOG_INSTALL_EARTH_ID);
|
||||
}
|
||||
return true;
|
||||
case R.id.menu_share_map:
|
||||
intent = new Intent(this, UploadServiceChooserActivity.class)
|
||||
.putExtra(SendRequest.SEND_REQUEST_KEY, new SendRequest(trackId, true, false, false));
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.menu_share_fusion_table:
|
||||
intent = new Intent(this, UploadServiceChooserActivity.class)
|
||||
.putExtra(SendRequest.SEND_REQUEST_KEY, new SendRequest(trackId, false, true, false));
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.menu_share_gpx:
|
||||
startSaveActivity(trackId, TrackFileFormat.GPX, true);
|
||||
return true;
|
||||
case R.id.menu_share_kml:
|
||||
startSaveActivity(trackId, TrackFileFormat.KML, true);
|
||||
return true;
|
||||
case R.id.menu_share_csv:
|
||||
startSaveActivity(trackId, TrackFileFormat.CSV, true);
|
||||
return true;
|
||||
case R.id.menu_share_tcx:
|
||||
startSaveActivity(trackId, TrackFileFormat.TCX, true);
|
||||
return true;
|
||||
case R.id.menu_markers:
|
||||
intent = new Intent(this, WaypointsList.class)
|
||||
.putExtra("trackid", trackDataHub.getSelectedTrackId());
|
||||
startActivityForResult(intent, Constants.SHOW_WAYPOINT);
|
||||
return true;
|
||||
case R.id.menu_send_google:
|
||||
intent = new Intent(this, UploadServiceChooserActivity.class)
|
||||
.putExtra(SendRequest.SEND_REQUEST_KEY, new SendRequest(trackId, true, true, true));
|
||||
startActivity(intent);
|
||||
return true;
|
||||
case R.id.menu_save_gpx:
|
||||
startSaveActivity(trackId, TrackFileFormat.GPX, false);
|
||||
return true;
|
||||
case R.id.menu_save_kml:
|
||||
startSaveActivity(trackId, TrackFileFormat.KML, false);
|
||||
return true;
|
||||
case R.id.menu_save_csv:
|
||||
startSaveActivity(trackId, TrackFileFormat.CSV, false);
|
||||
return true;
|
||||
case R.id.menu_save_tcx:
|
||||
startSaveActivity(trackId, TrackFileFormat.TCX, false);
|
||||
return true;
|
||||
case R.id.menu_edit:
|
||||
startActivity(new Intent(this, TrackEditActivity.class)
|
||||
.putExtra(TrackEditActivity.TRACK_ID, trackId));
|
||||
return true;
|
||||
case R.id.menu_delete:
|
||||
showDialog(DIALOG_DELETE_CURRENT_ID);
|
||||
return true;
|
||||
case R.id.menu_my_location:
|
||||
mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
mapActivity.showMyLocation();
|
||||
}
|
||||
return true;
|
||||
case R.id.menu_satellite_mode:
|
||||
mapActivity = getMapActivity();
|
||||
if (mapActivity != null) {
|
||||
mapActivity.setSatelliteView(!mapActivity.isSatelliteView());
|
||||
}
|
||||
return true;
|
||||
case R.id.menu_chart_settings:
|
||||
ChartActivity chartActivity = getChartActivity();
|
||||
if (chartActivity != null) {
|
||||
chartActivity.showChartSettingsDialog();
|
||||
}
|
||||
return true;
|
||||
case R.id.menu_sensor_state:
|
||||
startActivity(new Intent(this, SensorStateActivity.class));
|
||||
return true;
|
||||
case R.id.menu_settings:
|
||||
startActivity(new Intent(this, SettingsActivity.class));
|
||||
return true;
|
||||
case R.id.menu_help:
|
||||
startActivity(new Intent(this, WelcomeActivity.class));
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, final Intent results) {
|
||||
if (requestCode != Constants.SHOW_WAYPOINT) {
|
||||
Log.d(TAG, "Invalid request code: " + requestCode);
|
||||
return;
|
||||
}
|
||||
if (results != null) {
|
||||
long waypointId = results.getLongExtra(WaypointDetails.WAYPOINT_ID_EXTRA, -1L);
|
||||
if (waypointId != -1L) {
|
||||
MapActivity mapActivity = (MapActivity) getLocalActivityManager().getActivity(MAP_TAB_TAG);
|
||||
if (mapActivity != null) {
|
||||
getTabHost().setCurrentTab(0);
|
||||
mapActivity.showWaypoint(waypointId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTrackballEvent(MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
if (isRecording()) {
|
||||
ITrackRecordingService trackRecordingService = trackRecordingServiceConnection
|
||||
.getServiceIfBound();
|
||||
if (trackRecordingService == null) {
|
||||
Log.e(TAG, "The track recording service is null");
|
||||
return true;
|
||||
}
|
||||
boolean success = false;
|
||||
try {
|
||||
long waypointId = trackRecordingService.insertWaypoint(
|
||||
WaypointCreationRequest.DEFAULT_STATISTICS);
|
||||
if (waypointId != -1L) {
|
||||
success = true;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Unable to insert waypoint", e);
|
||||
}
|
||||
Toast.makeText(this,
|
||||
success ? R.string.marker_insert_success : R.string.marker_insert_error,
|
||||
success ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG)
|
||||
.show();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onTrackballEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
navControls.show();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the menu.
|
||||
*/
|
||||
private void updateMenu() {
|
||||
updateMenuItems(isRecording());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the menu items.
|
||||
*
|
||||
* @param isRecording true if recording
|
||||
*/
|
||||
private void updateMenuItems(boolean isRecording) {
|
||||
if (stopRecordingMenuItem != null) {
|
||||
stopRecordingMenuItem.setVisible(isRecording);
|
||||
}
|
||||
if (insertMarkerMenuItem != null) {
|
||||
insertMarkerMenuItem.setVisible(isRecording);
|
||||
}
|
||||
if (playMenuItem != null) {
|
||||
playMenuItem.setVisible(!isRecording);
|
||||
}
|
||||
if (shareMenuItem != null) {
|
||||
shareMenuItem.setVisible(!isRecording);
|
||||
}
|
||||
if (sendGoogleMenuItem != null) {
|
||||
sendGoogleMenuItem.setVisible(!isRecording);
|
||||
}
|
||||
if (saveMenuItem != null) {
|
||||
saveMenuItem.setVisible(!isRecording);
|
||||
}
|
||||
if (editMenuItem != null) {
|
||||
editMenuItem.setVisible(!isRecording);
|
||||
}
|
||||
if (deleteMenuItem != null) {
|
||||
deleteMenuItem.setVisible(!isRecording);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the current track.
|
||||
*/
|
||||
private void deleteCurrentTrack() {
|
||||
long trackId = trackDataHub.getSelectedTrackId();
|
||||
MyTracksProviderUtils.Factory.get(TrackDetailActivity.this).deleteTrack(trackId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the {@link TrackListActivity} and ends this activity.
|
||||
*/
|
||||
private void startTrackListActivity() {
|
||||
Intent intent = new Intent(this, TrackListActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the {@link SaveActivity} to save a track.
|
||||
*
|
||||
* @param trackId the track id
|
||||
* @param trackFileFormat the track file format
|
||||
* @param shareTrack true to share the track after saving
|
||||
*/
|
||||
private void startSaveActivity(
|
||||
long trackId, TrackFileFormat trackFileFormat, boolean shareTrack) {
|
||||
Intent intent = new Intent(this, SaveActivity.class)
|
||||
.putExtra(SaveActivity.EXTRA_TRACK_ID, trackId)
|
||||
.putExtra(SaveActivity.EXTRA_TRACK_FILE_FORMAT, (Parcelable) trackFileFormat)
|
||||
.putExtra(SaveActivity.EXTRA_SHARE_TRACK, shareTrack);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if recording.
|
||||
*/
|
||||
private boolean isRecording() {
|
||||
return ServiceUtils.isRecording(
|
||||
this, trackRecordingServiceConnection.getServiceIfBound(), sharedPreferences);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the recording and the track recording service connection and shows
|
||||
* {@link TrackEditActivity}.
|
||||
*/
|
||||
private void stopRecording() {
|
||||
ITrackRecordingService trackRecordingService = trackRecordingServiceConnection
|
||||
.getServiceIfBound();
|
||||
if (trackRecordingService != null) {
|
||||
try {
|
||||
trackRecordingService.endCurrentTrack();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Unable to stop recording.", e);
|
||||
}
|
||||
}
|
||||
trackRecordingServiceConnection.stop();
|
||||
|
||||
long recordingTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1L);
|
||||
if (recordingTrackId != -1L) {
|
||||
Intent intent = new Intent(this, TrackEditActivity.class)
|
||||
.putExtra(TrackEditActivity.SHOW_CANCEL, false)
|
||||
.putExtra(TrackEditActivity.TRACK_ID, recordingTrackId);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the map activity, can be null.
|
||||
*/
|
||||
private MapActivity getMapActivity() {
|
||||
return (MapActivity) getLocalActivityManager().getActivity(MAP_TAB_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chart activity, can be null.
|
||||
*/
|
||||
private ChartActivity getChartActivity() {
|
||||
return (ChartActivity) getLocalActivityManager().getActivity(CHART_TAB_TAG);
|
||||
}
|
||||
}
|
||||
@@ -35,12 +35,12 @@ import android.widget.EditText;
|
||||
*
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class TrackDetail extends Activity implements OnClickListener {
|
||||
public class TrackEditActivity extends Activity implements OnClickListener {
|
||||
|
||||
public static final String TRACK_ID = "trackId";
|
||||
public static final String SHOW_CANCEL = "showCancel";
|
||||
|
||||
private static final String TAG = TrackDetail.class.getSimpleName();
|
||||
private static final String TAG = TrackEditActivity.class.getSimpleName();
|
||||
|
||||
private Long trackId;
|
||||
private MyTracksProviderUtils myTracksProviderUtils;
|
||||
@@ -53,7 +53,7 @@ public class TrackDetail extends Activity implements OnClickListener {
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
setContentView(R.layout.track_detail);
|
||||
setContentView(R.layout.track_edit);
|
||||
|
||||
trackId = getIntent().getLongExtra(TRACK_ID, -1);
|
||||
if (trackId < 0) {
|
||||
@@ -71,22 +71,22 @@ public class TrackDetail extends Activity implements OnClickListener {
|
||||
return;
|
||||
}
|
||||
|
||||
trackName = (EditText) findViewById(R.id.track_detail_track_name);
|
||||
trackName = (EditText) findViewById(R.id.track_edit_track_name);
|
||||
trackName.setText(track.getName());
|
||||
|
||||
activityType = (AutoCompleteTextView) findViewById(R.id.track_detail_activity_type);
|
||||
activityType = (AutoCompleteTextView) findViewById(R.id.track_edit_activity_type);
|
||||
activityType.setText(track.getCategory());
|
||||
|
||||
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
|
||||
this, R.array.activity_types, android.R.layout.simple_dropdown_item_1line);
|
||||
activityType.setAdapter(adapter);
|
||||
trackDescription = (EditText) findViewById(R.id.track_detail_track_description);
|
||||
trackDescription = (EditText) findViewById(R.id.track_edit_track_description);
|
||||
trackDescription.setText(track.getDescription());
|
||||
|
||||
Button save = (Button) findViewById(R.id.track_detail_save);
|
||||
Button save = (Button) findViewById(R.id.track_edit_save);
|
||||
save.setOnClickListener(this);
|
||||
|
||||
Button cancel = (Button) findViewById(R.id.track_detail_cancel);
|
||||
Button cancel = (Button) findViewById(R.id.track_edit_cancel);
|
||||
if (getIntent().getBooleanExtra(SHOW_CANCEL, true)) {
|
||||
cancel.setOnClickListener(this);
|
||||
cancel.setVisibility(View.VISIBLE);
|
||||
@@ -98,11 +98,11 @@ public class TrackDetail extends Activity implements OnClickListener {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.track_detail_save:
|
||||
case R.id.track_edit_save:
|
||||
save();
|
||||
finish();
|
||||
break;
|
||||
case R.id.track_detail_cancel:
|
||||
case R.id.track_edit_cancel:
|
||||
finish();
|
||||
break;
|
||||
default:
|
||||
@@ -23,7 +23,9 @@ import com.google.android.apps.mytracks.services.ITrackRecordingService;
|
||||
import com.google.android.apps.mytracks.services.ServiceUtils;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
|
||||
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
|
||||
import com.google.android.apps.mytracks.util.CheckUnitsUtils;
|
||||
import com.google.android.apps.mytracks.util.DialogUtils;
|
||||
import com.google.android.apps.mytracks.util.EulaUtils;
|
||||
import com.google.android.apps.mytracks.util.StringUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
@@ -33,12 +35,14 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
@@ -62,8 +66,13 @@ import android.widget.Toast;
|
||||
public class TrackListActivity extends FragmentActivity {
|
||||
|
||||
private static final String TAG = TrackListActivity.class.getSimpleName();
|
||||
private static final String EXPORT_ALL_DIALOG_TAG = "exportAllDialog";
|
||||
private static final String CHECK_UNITS_DIALOG_TAG = "checkUnitsDialog";
|
||||
private static final String DELETE_ALL_DIALOG_TAG = "deleteAllDialog";
|
||||
private static final String EULA_DIALOG_TAG = "eulaDialog";
|
||||
private static final String EXPORT_ALL_DIALOG_TAG = "exportAllDialog";
|
||||
|
||||
private static final int WELCOME_ACTIVITY_REQUEST_CODE = 0;
|
||||
|
||||
private static final String[] PROJECTION = new String[] {
|
||||
TracksColumns._ID,
|
||||
TracksColumns.NAME,
|
||||
@@ -73,18 +82,53 @@ public class TrackListActivity extends FragmentActivity {
|
||||
TracksColumns.STARTTIME,
|
||||
TracksColumns.DESCRIPTION };
|
||||
|
||||
// Callback when the trackRecordingServiceConnection binding changes
|
||||
// Callback when the trackRecordingServiceConnection binding changes.
|
||||
private final Runnable bindChangedCallback = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (trackRecordingServiceConnection) {
|
||||
if (startNewRecording) {
|
||||
startRecording();
|
||||
} else {
|
||||
updateMenu();
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
if (!startNewRecording) {
|
||||
return;
|
||||
}
|
||||
|
||||
ITrackRecordingService service = trackRecordingServiceConnection.getServiceIfBound();
|
||||
if (service == null) {
|
||||
Log.d(TAG, "service not available to start a new recording");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
recordingTrackId = service.startNewTrack();
|
||||
startNewRecording = false;
|
||||
Toast.makeText(
|
||||
TrackListActivity.this, R.string.track_list_record_success, Toast.LENGTH_SHORT).show();
|
||||
Log.d(TAG, "Started a new recording");
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(TrackListActivity.this, R.string.track_list_record_error, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
Log.e(TAG, "Unable to start a new recording.", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Note that sharedPreferenceChangeListenr cannot be an anonymous inner class.
|
||||
* Anonymous inner class will get garbage collected.
|
||||
*/
|
||||
private final OnSharedPreferenceChangeListener sharedPreferenceChangeListener =
|
||||
new OnSharedPreferenceChangeListener() {
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
// Note that key can be null
|
||||
if (getString(R.string.metric_units_key).equals(key)) {
|
||||
metricUnits = preferences.getBoolean(getString(R.string.metric_units_key), true);
|
||||
}
|
||||
if (getString(R.string.recording_track_key).equals(key)) {
|
||||
recordingTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1L);
|
||||
if (isRecording()) {
|
||||
trackRecordingServiceConnection.startAndBind();
|
||||
}
|
||||
updateMenu();
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -95,7 +139,7 @@ public class TrackListActivity extends FragmentActivity {
|
||||
private ListView listView;
|
||||
private ResourceCursorAdapter adapter;
|
||||
|
||||
// True to start a new recording
|
||||
// True to start a new recording.
|
||||
private boolean startNewRecording = false;
|
||||
|
||||
private MenuItem recordTrack;
|
||||
@@ -108,29 +152,15 @@ public class TrackListActivity extends FragmentActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
|
||||
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
|
||||
setContentView(R.layout.track_list);
|
||||
|
||||
trackRecordingServiceConnection = new TrackRecordingServiceConnection(
|
||||
this, bindChangedCallback);
|
||||
|
||||
sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
sharedPreferences.registerOnSharedPreferenceChangeListener(
|
||||
new SharedPreferences.OnSharedPreferenceChangeListener() {
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
if (key.equals(getString(R.string.metric_units_key))) {
|
||||
metricUnits = preferences.getBoolean(getString(R.string.metric_units_key), true);
|
||||
}
|
||||
if (key.equals(getString(R.string.recording_track_key))) {
|
||||
recordingTrackId = sharedPreferences.getLong(
|
||||
getString(R.string.recording_track_key), -1L);
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||
metricUnits = sharedPreferences.getBoolean(getString(R.string.metric_units_key), true);
|
||||
recordingTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1L);
|
||||
|
||||
@@ -138,8 +168,9 @@ public class TrackListActivity extends FragmentActivity {
|
||||
listView.setOnItemClickListener(new OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
setResult(Constants.SHOW_TRACK, new Intent().putExtra("trackid", id));
|
||||
finish();
|
||||
Intent intent = new Intent(TrackListActivity.this, TrackDetailActivity.class)
|
||||
.putExtra(TrackDetailActivity.TRACK_ID, id);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
adapter = new ResourceCursorAdapter(this, R.layout.track_list_item, null, 0) {
|
||||
@@ -205,11 +236,23 @@ public class TrackListActivity extends FragmentActivity {
|
||||
adapter.swapCursor(null);
|
||||
}
|
||||
});
|
||||
|
||||
if (!EulaUtils.getEulaValue(this)) {
|
||||
new EulaDialogFragment().show(getSupportFragmentManager(), EULA_DIALOG_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
if (isRecording()) {
|
||||
trackRecordingServiceConnection.startAndBind();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
trackRecordingServiceConnection.bindIfRunning();
|
||||
}
|
||||
|
||||
@@ -219,6 +262,24 @@ public class TrackListActivity extends FragmentActivity {
|
||||
trackRecordingServiceConnection.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, final Intent results) {
|
||||
if (requestCode == WELCOME_ACTIVITY_REQUEST_CODE) {
|
||||
if (!CheckUnitsUtils.getCheckUnitsValue(this)) {
|
||||
/*
|
||||
* See bug http://code.google.com/p/android/issues/detail?id=23761.
|
||||
* Cannot use
|
||||
* CheckUnitsDialogFragment().show(getSupportFragmentManager(),
|
||||
* CHECK_UNITS_DIALOG_TAG). Need to use commitAllowingStateLoss with the
|
||||
* support package.
|
||||
*/
|
||||
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
|
||||
fragmentTransaction.add(new CheckUnitsDialogFragment(), CHECK_UNITS_DIALOG_TAG);
|
||||
fragmentTransaction.commitAllowingStateLoss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.track_list, menu);
|
||||
@@ -239,8 +300,7 @@ public class TrackListActivity extends FragmentActivity {
|
||||
* Updates the menu based on whether My Tracks is recording or not.
|
||||
*/
|
||||
private void updateMenu() {
|
||||
boolean isRecording = ServiceUtils.isRecording(
|
||||
this, trackRecordingServiceConnection.getServiceIfBound(), sharedPreferences);
|
||||
boolean isRecording = isRecording();
|
||||
updateMenuItems(isRecording);
|
||||
}
|
||||
|
||||
@@ -272,23 +332,11 @@ public class TrackListActivity extends FragmentActivity {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_record_track:
|
||||
updateMenuItems(true);
|
||||
synchronized (trackRecordingServiceConnection) {
|
||||
startNewRecording = true;
|
||||
trackRecordingServiceConnection.startAndBind();
|
||||
|
||||
/*
|
||||
* If the binding has happened, then invoke the callback to start a
|
||||
* new recording. If the binding hasn't happened, then invoking the
|
||||
* callback will have no effect. But when the binding occurs, the
|
||||
* callback will get invoked.
|
||||
*/
|
||||
bindChangedCallback.run();
|
||||
}
|
||||
startRecording();
|
||||
return true;
|
||||
case R.id.menu_stop_recording:
|
||||
updateMenuItems(false);
|
||||
stopRecording();
|
||||
trackRecordingServiceConnection.stop();
|
||||
return true;
|
||||
case R.id.menu_search:
|
||||
return ApiAdapterFactory.getApiAdapter().handleSearchMenuSelection(this);
|
||||
@@ -316,27 +364,28 @@ public class TrackListActivity extends FragmentActivity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if recording.
|
||||
*/
|
||||
private boolean isRecording() {
|
||||
return ServiceUtils.isRecording(
|
||||
this, trackRecordingServiceConnection.getServiceIfBound(), sharedPreferences);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new recording.
|
||||
*/
|
||||
private void startRecording() {
|
||||
ITrackRecordingService service = trackRecordingServiceConnection.getServiceIfBound();
|
||||
if (service != null) {
|
||||
try {
|
||||
recordingTrackId = service.startNewTrack();
|
||||
startNewRecording = false;
|
||||
adapter.notifyDataSetChanged();
|
||||
Toast.makeText(TrackListActivity.this, R.string.track_record_success, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
Log.d(TAG, "Started a new recording");
|
||||
} catch (Exception e) {
|
||||
Toast.makeText(TrackListActivity.this, R.string.track_record_error, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
Log.d(TAG, "Unable to start a new recording.", e);
|
||||
}
|
||||
} else {
|
||||
Log.d(TAG, "service not available to start a new recording");
|
||||
}
|
||||
startNewRecording = true;
|
||||
trackRecordingServiceConnection.startAndBind();
|
||||
|
||||
/*
|
||||
* If the binding has happened, then invoke the callback to start a new
|
||||
* recording. If the binding hasn't happened, then invoking the callback
|
||||
* will have no effect. But when the binding occurs, the callback will get
|
||||
* invoked.
|
||||
*/
|
||||
bindChangedCallback.run();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,31 +397,124 @@ public class TrackListActivity extends FragmentActivity {
|
||||
try {
|
||||
service.endCurrentTrack();
|
||||
if (recordingTrackId != -1L) {
|
||||
Intent intent = new Intent(this, TrackDetail.class)
|
||||
.putExtra(TrackDetail.SHOW_CANCEL, false)
|
||||
.putExtra(TrackDetail.TRACK_ID, recordingTrackId);
|
||||
Intent intent = new Intent(this, TrackEditActivity.class)
|
||||
.putExtra(TrackEditActivity.SHOW_CANCEL, false)
|
||||
.putExtra(TrackEditActivity.TRACK_ID, recordingTrackId);
|
||||
startActivity(intent);
|
||||
}
|
||||
recordingTrackId = -1L;
|
||||
adapter.notifyDataSetChanged();
|
||||
} catch (Exception e) {
|
||||
Log.d(TAG, "Unable to stop recording.", e);
|
||||
}
|
||||
}
|
||||
trackRecordingServiceConnection.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_SEARCH) {
|
||||
if (ApiAdapterFactory.getApiAdapter().handleSearchKey(search)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Units DialogFragment.
|
||||
*/
|
||||
public static class CheckUnitsDialogFragment extends DialogFragment {
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
|
||||
return new AlertDialog.Builder(getActivity()).setCancelable(true)
|
||||
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
CheckUnitsUtils.setCheckUnitsValue(getActivity());
|
||||
}
|
||||
})
|
||||
.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
CheckUnitsUtils.setCheckUnitsValue(getActivity());
|
||||
|
||||
int position = ((AlertDialog) dialog).getListView().getSelectedItemPosition();
|
||||
SharedPreferences sharedPreferences = getActivity()
|
||||
.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(sharedPreferences.edit()
|
||||
.putBoolean(getString(R.string.metric_units_key), position == 0));
|
||||
}
|
||||
})
|
||||
.setSingleChoiceItems(new CharSequence[] { getString(R.string.preferred_units_metric),
|
||||
getString(R.string.preferred_units_imperial) }, 0, null)
|
||||
.setTitle(R.string.preferred_units_title)
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete All DialogFragment.
|
||||
*/
|
||||
public static class DeleteAllDialogFragment extends DialogFragment {
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
return DialogUtils.createConfirmationDialog(getActivity(),
|
||||
R.string.track_list_delete_all_confirm_message, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
MyTracksProviderUtils.Factory.get(getActivity()).deleteAllTracks();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Eula DialogFragment.
|
||||
*/
|
||||
public static class EulaDialogFragment extends DialogFragment {
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setCancelable(true)
|
||||
.setMessage(EulaUtils.getEulaMessage(getActivity()))
|
||||
.setNegativeButton(R.string.eula_decline, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
getActivity().finish();
|
||||
}
|
||||
})
|
||||
.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
getActivity().finish();
|
||||
}
|
||||
})
|
||||
.setPositiveButton(R.string.eula_accept, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
EulaUtils.setEulaValue(getActivity());
|
||||
getActivity().startActivityForResult(
|
||||
new Intent(getActivity(), WelcomeActivity.class), WELCOME_ACTIVITY_REQUEST_CODE);
|
||||
}
|
||||
})
|
||||
.setTitle(R.string.eula_title)
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Export All DialogFragment.
|
||||
*/
|
||||
private static class ExportAllDialogFragment extends DialogFragment {
|
||||
public static class ExportAllDialogFragment extends DialogFragment {
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
String exportFileFormat = getString(R.string.track_list_export_file);
|
||||
String fileTypes[] = getResources().getStringArray(R.array.file_types);
|
||||
String[] choices = new String[fileTypes.length];
|
||||
for (int i = 0; i < fileTypes.length; i++) {
|
||||
choices[i] = String.format(exportFileFormat, fileTypes[i]);
|
||||
choices[i] = getString(R.string.menu_export_all_format, fileTypes[i]);
|
||||
}
|
||||
return new AlertDialog.Builder(getActivity()).setNegativeButton(R.string.generic_cancel, null)
|
||||
.setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() {
|
||||
@@ -389,42 +531,5 @@ public class TrackListActivity extends FragmentActivity {
|
||||
.setTitle(R.string.menu_export_all)
|
||||
.create();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete All DialogFragment.
|
||||
*/
|
||||
private static class DeleteAllDialogFragment extends DialogFragment {
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
return DialogUtils.createConfirmationDialog(getActivity(),
|
||||
R.string.track_list_delete_all_confirm_message, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
MyTracksProviderUtils.Factory.get(getActivity()).deleteAllTracks();
|
||||
/*
|
||||
* TODO Verify that selected_track_key is still needed with the
|
||||
* ICS navigation design
|
||||
*/
|
||||
SharedPreferences sharedPreferences = getActivity()
|
||||
.getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||
Editor editor = sharedPreferences.edit();
|
||||
// TODO: Go through data manager
|
||||
editor.putLong(getString(R.string.selected_track_key), -1L);
|
||||
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
if (keyCode == KeyEvent.KEYCODE_SEARCH) {
|
||||
if (ApiAdapterFactory.getApiAdapter().handleSearchKey(search)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.google.android.apps.mytracks.io.backup;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracks;
|
||||
import com.google.android.apps.mytracks.TrackListActivity;
|
||||
import com.google.android.apps.mytracks.util.DialogUtils;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
@@ -92,7 +92,8 @@ public class RestoreActivity extends Activity {
|
||||
public void onAsyncTaskCompleted(boolean success, int messageId) {
|
||||
removeDialog(DIALOG_PROGRESS_ID);
|
||||
Toast.makeText(this, messageId, success ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG).show();
|
||||
startActivity(new Intent(this, MyTracks.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
|
||||
startActivity(
|
||||
new Intent(this, TrackListActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
|
||||
finish();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.google.android.apps.mytracks.io.sendtogoogle;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.stats.TripStatistics;
|
||||
import com.google.android.apps.mytracks.util.LocationUtils;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import android.location.Location;
|
||||
import android.util.Log;
|
||||
@@ -109,11 +110,12 @@ public class SendToGoogleUtils {
|
||||
* @param segment the track segment
|
||||
* @param splitTracks an array of track segments
|
||||
*/
|
||||
private static void prepareTrackSegment(Track segment, ArrayList<Track> splitTracks) {
|
||||
@VisibleForTesting
|
||||
static boolean prepareTrackSegment(Track segment, ArrayList<Track> splitTracks) {
|
||||
// Make sure the segment has at least 2 points
|
||||
if (segment.getLocations().size() < 2) {
|
||||
Log.d(TAG, "segment has less than 2 points");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// For a new segment, sets it stop time
|
||||
@@ -128,5 +130,6 @@ public class SendToGoogleUtils {
|
||||
LocationUtils.decimate(segment, 2.0);
|
||||
|
||||
splitTracks.add(segment);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import static com.google.android.apps.mytracks.Constants.RESUME_TRACK_EXTRA_NAME
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.Constants;
|
||||
import com.google.android.apps.mytracks.MyTracks;
|
||||
import com.google.android.apps.mytracks.TrackDetailActivity;
|
||||
import com.google.android.apps.mytracks.content.DescriptionGenerator;
|
||||
import com.google.android.apps.mytracks.content.DescriptionGeneratorImpl;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
@@ -484,9 +484,10 @@ public class TrackRecordingService extends Service {
|
||||
Notification notification = new Notification(
|
||||
R.drawable.arrow_320, null /* tickerText */,
|
||||
System.currentTimeMillis());
|
||||
Intent intent = new Intent(this, TrackDetailActivity.class)
|
||||
.putExtra(TrackDetailActivity.TRACK_ID, recordingTrackId);
|
||||
PendingIntent contentIntent = PendingIntent.getActivity(
|
||||
this, 0 /* requestCode */, new Intent(this, MyTracks.class),
|
||||
0 /* flags */);
|
||||
this, 0 /* requestCode */, intent, 0 /* flags */);
|
||||
notification.setLatestEventInfo(this, getString(R.string.my_tracks_app_name),
|
||||
getString(R.string.track_record_notification), contentIntent);
|
||||
notification.flags += Notification.FLAG_NO_CLEAR;
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
package com.google.android.apps.mytracks.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
|
||||
/**
|
||||
* Utilities for checking units.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public class CheckUnitsUtils {
|
||||
|
||||
private static final String CHECK_UNITS_PREFERENCE_FILE = "checkunits";
|
||||
private static final String CHECK_UNITS_PREFERENCE_KEY = "checkunits.checked";
|
||||
|
||||
private CheckUnitsUtils() {}
|
||||
|
||||
public static boolean getCheckUnitsValue(Context context) {
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(
|
||||
CHECK_UNITS_PREFERENCE_FILE, Context.MODE_PRIVATE);
|
||||
return sharedPreferences.getBoolean(CHECK_UNITS_PREFERENCE_KEY, false);
|
||||
}
|
||||
|
||||
public static void setCheckUnitsValue(Context context) {
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(
|
||||
CHECK_UNITS_PREFERENCE_FILE, Context.MODE_PRIVATE);
|
||||
Editor editor = sharedPreferences.edit().putBoolean(CHECK_UNITS_PREFERENCE_KEY, true);
|
||||
ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor);
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,7 @@ public class PlayTrackUtils {
|
||||
public static Dialog createInstallEarthDialog(final Context context) {
|
||||
return new AlertDialog.Builder(context)
|
||||
.setCancelable(true)
|
||||
.setMessage(R.string.track_list_play_install_earth_message)
|
||||
.setMessage(R.string.track_detail_install_earth_message)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
|
||||
@@ -19,7 +19,7 @@ package com.google.android.apps.mytracks.widgets;
|
||||
import static com.google.android.apps.mytracks.Constants.SETTINGS_NAME;
|
||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
||||
|
||||
import com.google.android.apps.mytracks.MyTracks;
|
||||
import com.google.android.apps.mytracks.TrackDetailActivity;
|
||||
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
import com.google.android.apps.mytracks.content.TracksColumns;
|
||||
@@ -145,7 +145,10 @@ public class TrackWidgetProvider
|
||||
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.track_widget);
|
||||
|
||||
// Make all of the stats open the mytracks activity.
|
||||
Intent intent = new Intent(context, MyTracks.class);
|
||||
Intent intent = new Intent(context, TrackDetailActivity.class);
|
||||
if (track != null) {
|
||||
intent.putExtra(TrackDetailActivity.TRACK_ID, track.getId());
|
||||
}
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
|
||||
views.setOnClickPendingIntent(R.id.appwidget_track_statistics, pendingIntent);
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="gen"/>
|
||||
<classpathentry exported="true" kind="lib" path="libs/protobuf-java-2.3.0-lite.jar"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/MyTracks"/>
|
||||
<classpathentry kind="lib" path="libs/AndroidMockGenerator.jar"/>
|
||||
<classpathentry kind="lib" path="libs/robotium-solo-3.1.jar"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
|
||||
@@ -19,31 +19,28 @@ import com.google.android.apps.mytracks.services.ServiceUtils;
|
||||
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Instrumentation.ActivityMonitor;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.net.Uri;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.widget.Button;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* A unit test for {@link MyTracks} activity.
|
||||
* A unit test for {@link TrackDetailActivity}.
|
||||
*
|
||||
* @author Bartlomiej Niechwiej
|
||||
*/
|
||||
public class MyTracksTest extends ActivityInstrumentationTestCase2<MyTracks>{
|
||||
public class TrackDetailActivityTest extends ActivityInstrumentationTestCase2<TrackDetailActivity>{
|
||||
private SharedPreferences sharedPreferences;
|
||||
private TrackRecordingServiceConnection serviceConnection;
|
||||
|
||||
public MyTracksTest() {
|
||||
super(MyTracks.class);
|
||||
public TrackDetailActivityTest() {
|
||||
super(TrackDetailActivity.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,10 +56,7 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2<MyTracks>{
|
||||
|
||||
// Check if not recording.
|
||||
assertFalse(isRecording());
|
||||
assertEquals(-1, getRecordingTrackId());
|
||||
long selectedTrackId = getSharedPreferences().getLong(
|
||||
getActivity().getString(R.string.selected_track_key), -1);
|
||||
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
|
||||
assertEquals(-1, getRecordingTrackId());
|
||||
}
|
||||
|
||||
public void testInitialization_viewActionWithNoData() {
|
||||
@@ -75,10 +69,7 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2<MyTracks>{
|
||||
|
||||
// Check if not recording.
|
||||
assertFalse(isRecording());
|
||||
assertEquals(-1, getRecordingTrackId());
|
||||
long selectedTrackId = getSharedPreferences().getLong(
|
||||
getActivity().getString(R.string.selected_track_key), -1);
|
||||
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
|
||||
assertEquals(-1, getRecordingTrackId());
|
||||
}
|
||||
|
||||
public void testInitialization_viewActionWithValidData() throws Exception {
|
||||
@@ -97,10 +88,7 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2<MyTracks>{
|
||||
// Check if not recording.
|
||||
assertFalse(isRecording());
|
||||
assertEquals(-1, getRecordingTrackId());
|
||||
long selectedTrackId = getSharedPreferences().getLong(
|
||||
getActivity().getString(R.string.selected_track_key), -1);
|
||||
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
|
||||
|
||||
|
||||
// TODO: Finish this test.
|
||||
}
|
||||
|
||||
@@ -117,75 +105,10 @@ public class MyTracksTest extends ActivityInstrumentationTestCase2<MyTracks>{
|
||||
// Check if not recording.
|
||||
assertFalse(isRecording());
|
||||
assertEquals(-1, getRecordingTrackId());
|
||||
long selectedTrackId = getSharedPreferences().getLong(
|
||||
getActivity().getString(R.string.selected_track_key), -1);
|
||||
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
|
||||
|
||||
|
||||
// TODO: Finish this test.
|
||||
}
|
||||
|
||||
public void testRecording_startAndStop() throws Exception {
|
||||
assertInitialized();
|
||||
|
||||
// Check if not recording.
|
||||
clearSelectedAndRecordingTracks();
|
||||
waitForIdle();
|
||||
|
||||
assertFalse(isRecording());
|
||||
assertEquals(-1, getRecordingTrackId());
|
||||
long selectedTrackId = getSharedPreferences().getLong(
|
||||
getActivity().getString(R.string.selected_track_key), -1);
|
||||
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
|
||||
|
||||
// Start a new track.
|
||||
getActivity().startRecording();
|
||||
serviceConnection.bindIfRunning();
|
||||
long recordingTrackId = awaitRecordingStatus(5000, true);
|
||||
assertTrue(recordingTrackId >= 0);
|
||||
|
||||
// Wait until we are done and make sure that selectedTrack = recordingTrack.
|
||||
waitForIdle();
|
||||
assertEquals(recordingTrackId, getSharedPreferences().getLong(
|
||||
getActivity().getString(R.string.recording_track_key), -1));
|
||||
selectedTrackId = getSharedPreferences().getLong(
|
||||
getActivity().getString(R.string.selected_track_key), -1);
|
||||
assertEquals(recordingTrackId, selectedTrackId);
|
||||
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
|
||||
|
||||
// Watch for MyTracksDetails activity.
|
||||
ActivityMonitor monitor = getInstrumentation().addMonitor(
|
||||
TrackDetail.class.getName(), null, false);
|
||||
|
||||
// Now, stop the track and make sure that it is still selected, but
|
||||
// no longer recording.
|
||||
getActivity().stopRecording();
|
||||
|
||||
// Check if we got back MyTracksDetails activity.
|
||||
Activity activity = getInstrumentation().waitForMonitor(monitor);
|
||||
assertTrue(activity instanceof TrackDetail);
|
||||
|
||||
// TODO: Update track name and other properties and test if they were
|
||||
// properly saved.
|
||||
|
||||
// Simulate a click on Save button.
|
||||
final Button save = (Button) activity.findViewById(R.id.track_detail_save);
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
save.performClick();
|
||||
}
|
||||
});
|
||||
|
||||
// Check the remaining properties.
|
||||
recordingTrackId = awaitRecordingStatus(5000, false);
|
||||
assertEquals(-1, recordingTrackId);
|
||||
assertEquals(recordingTrackId, getRecordingTrackId());
|
||||
assertEquals(recordingTrackId, getSharedPreferences().getLong(
|
||||
getActivity().getString(R.string.recording_track_key), -1));
|
||||
// Make sure this is the same track as the last recording track ID.
|
||||
assertEquals(selectedTrackId, getActivity().getSelectedTrackId());
|
||||
}
|
||||
|
||||
private void assertInitialized() {
|
||||
assertNotNull(getActivity());
|
||||
|
||||
@@ -31,9 +31,9 @@ import android.location.Location;
|
||||
public class TrackStubUtils {
|
||||
|
||||
static final String LOCATION_PROVIDER = "gps";
|
||||
static final double INITIAL_LATITUDE = 22;
|
||||
static final double INITIAL_LONGITUDE = 22;
|
||||
static final double INITIAL_ALTITUDE = 22;
|
||||
public static final double INITIAL_LATITUDE = 22;
|
||||
public static final double INITIAL_LONGITUDE = 22;
|
||||
public static final double INITIAL_ALTITUDE = 22;
|
||||
static final float INITIAL_ACCURACY = 5;
|
||||
static final float INITIAL_SPEED = 10;
|
||||
static final float INITIAL_BEARING = 3.0f;
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.sendtogoogle;
|
||||
|
||||
/**
|
||||
* Tests the {@link SendToGoogleUtils}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
import com.google.android.apps.mytracks.TrackStubUtils;
|
||||
import com.google.android.apps.mytracks.content.MyTracksLocation;
|
||||
import com.google.android.apps.mytracks.content.Track;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SendToGoogleUtilsTest extends TestCase {
|
||||
|
||||
private final static long TRACK_ID = 1L;
|
||||
private final static String TRACK_CATEGORY = "trackCategory";
|
||||
private final static String TRACK_NAME = "trackName";
|
||||
private final static double DIFFERENCE = 0.02;
|
||||
private final static double INVALID_LATITUDE = 91;
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendToGoogleUtils#prepareTrackSegment(Track, java.util.ArrayList)}
|
||||
* when there is only one location in a segment.
|
||||
*/
|
||||
public void testPrepareTrackSegment_onlyOneLocation() {
|
||||
Track trackStub = TrackStubUtils.createTrack(1);
|
||||
assertFalse(SendToGoogleUtils.prepareTrackSegment(trackStub, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendToGoogleUtils#prepareTrackSegment(Track, ArrayList)} when there
|
||||
* is no stop time.
|
||||
*/
|
||||
public void testPrepareTrackSegment_noStopTime() {
|
||||
Track trackStub = TrackStubUtils.createTrack(2);
|
||||
assertEquals(-1L, trackStub.getStatistics().getStopTime());
|
||||
|
||||
ArrayList<Track> tracksArray = new ArrayList<Track>();
|
||||
assertTrue(SendToGoogleUtils.prepareTrackSegment(trackStub, tracksArray));
|
||||
assertEquals(trackStub, tracksArray.get(0));
|
||||
// The stop time should be the time of last location
|
||||
assertEquals(trackStub.getLocations().get(1).getTime(), trackStub.getStatistics().getStopTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendToGoogleUtils#prepareTrackSegment(Track, java.util.ArrayList)}
|
||||
* when there is stop time.
|
||||
*/
|
||||
public void testPrepareTrackSegment_hasStopTime() {
|
||||
Track trackStub = TrackStubUtils.createTrack(2);
|
||||
// Gives a margin to make sure the this time will be not same with the last
|
||||
// location in the track.
|
||||
long stopTime = System.currentTimeMillis() + 1000;
|
||||
trackStub.getStatistics().setStopTime(stopTime);
|
||||
|
||||
ArrayList<Track> tracksArray = new ArrayList<Track>();
|
||||
SendToGoogleUtils.prepareTrackSegment(trackStub, tracksArray);
|
||||
assertEquals(trackStub, tracksArray.get(0));
|
||||
assertEquals(stopTime, trackStub.getStatistics().getStopTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the method
|
||||
* {@link SendToGoogleUtils#prepareLocations(Track, java.util.List)} .
|
||||
*/
|
||||
public void testPrepareLocations() {
|
||||
Track trackStub = TrackStubUtils.createTrack(2);
|
||||
trackStub.setId(TRACK_ID);
|
||||
trackStub.setName(TRACK_NAME);
|
||||
trackStub.setCategory(TRACK_CATEGORY);
|
||||
|
||||
List<Location> locationsArray = new ArrayList<Location>();
|
||||
// Adds 100 location to List.
|
||||
for (int i = 0; i < 100; i++) {
|
||||
// Use this variable as a flag to make all points in the track can be kept
|
||||
// after run the LocationUtils#decimate(Track, double) with
|
||||
// Ramer–Douglas–Peucker algorithm.
|
||||
double latitude = TrackStubUtils.INITIAL_LATITUDE;
|
||||
if (i % 2 == 0) {
|
||||
latitude -= DIFFERENCE * (i % 10);
|
||||
}
|
||||
// Inserts 9 points which have wrong latitude, so would have 10 segments.
|
||||
if (i % 10 == 0 && i > 0) {
|
||||
MyTracksLocation location = TrackStubUtils.createMyTracksLocation();
|
||||
location.setLatitude(INVALID_LATITUDE);
|
||||
locationsArray.add(location);
|
||||
} else {
|
||||
locationsArray.add(TrackStubUtils.createMyTracksLocation(latitude,
|
||||
TrackStubUtils.INITIAL_LONGITUDE + DIFFERENCE * (i % 10),
|
||||
TrackStubUtils.INITIAL_ALTITUDE + DIFFERENCE * (i % 10)));
|
||||
}
|
||||
}
|
||||
ArrayList<Track> result = SendToGoogleUtils.prepareLocations(trackStub, locationsArray);
|
||||
assertEquals(10, result.size());
|
||||
// Checks all segments.
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Track segmentOne = result.get(i);
|
||||
assertEquals(TRACK_ID, segmentOne.getId());
|
||||
assertEquals(TRACK_NAME, segmentOne.getName());
|
||||
assertEquals(TRACK_CATEGORY, segmentOne.getCategory());
|
||||
}
|
||||
// Checks all locations in the first segment.
|
||||
for (int j = 0; j < 9; j++) {
|
||||
double latitude = TrackStubUtils.INITIAL_LATITUDE;
|
||||
if (j % 2 == 0) {
|
||||
latitude -= DIFFERENCE * (j % 10);
|
||||
}
|
||||
Location oneLocation = result.get(0).getLocations().get(j);
|
||||
assertEquals(TrackStubUtils.createMyTracksLocation().getAltitude() + DIFFERENCE * (j % 10),
|
||||
oneLocation.getAltitude());
|
||||
assertEquals(latitude, oneLocation.getLatitude());
|
||||
assertEquals(TrackStubUtils.createMyTracksLocation().getLongitude() + DIFFERENCE * (j % 10),
|
||||
oneLocation.getLongitude());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
package com.google.android.apps.mytracks.io.sendtogoogle;
|
||||
|
||||
import com.google.android.maps.mytracks.R;
|
||||
import com.jayway.android.robotium.solo.Solo;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
import android.content.Intent;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Tests the {@link UploadResultActivity}.
|
||||
*
|
||||
* @author Youtao Liu
|
||||
*/
|
||||
public class UploadResultActivityTest extends
|
||||
ActivityInstrumentationTestCase2<UploadResultActivity> {
|
||||
|
||||
private Instrumentation instrumentation;
|
||||
private UploadResultActivity uploadResultActivity;
|
||||
private Solo solo;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
instrumentation = getInstrumentation();
|
||||
solo = new Solo(instrumentation);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is necessary for ActivityInstrumentationTestCase2.
|
||||
*/
|
||||
public UploadResultActivityTest() {
|
||||
super(UploadResultActivity.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the display of dialog when send to all and all sends are successful.
|
||||
*/
|
||||
public void testAllSuccess() {
|
||||
initialActivity(true, true, true, true, true, true);
|
||||
|
||||
HashSet<String> stringHashSet = new HashSet<String>();
|
||||
ArrayList<View> view = solo.getViews();
|
||||
for (View oneView : view) {
|
||||
if (oneView instanceof TextView && oneView.isShown()) {
|
||||
stringHashSet.add((String) ((TextView) oneView).getText());
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity
|
||||
.getString(R.string.generic_success_title)));
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_maps)));
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity
|
||||
.getString(R.string.send_google_fusion_tables)));
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_docs)));
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity
|
||||
.getString(R.string.send_google_success_footer)));
|
||||
|
||||
assertFalse(stringHashSet
|
||||
.contains(uploadResultActivity.getString(R.string.generic_error_title)));
|
||||
assertFalse(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_error)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the display of dialog when send to all and all sends are failed.
|
||||
*/
|
||||
public void testAllFailed() {
|
||||
// Send all kinds but all failed.
|
||||
initialActivity(true, true, true, false, false, false);
|
||||
HashSet<String> stringHashSet = new HashSet<String>();
|
||||
ArrayList<View> view = solo.getViews();
|
||||
for (View oneView : view) {
|
||||
if (oneView instanceof TextView && oneView.isShown()) {
|
||||
stringHashSet.add((String) ((TextView) oneView).getText());
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(stringHashSet.contains((Object) uploadResultActivity
|
||||
.getString(R.string.generic_error_title)));
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_maps)));
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity
|
||||
.getString(R.string.send_google_fusion_tables)));
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_docs)));
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_error)));
|
||||
|
||||
assertFalse(stringHashSet.contains(uploadResultActivity
|
||||
.getString(R.string.generic_success_title)));
|
||||
assertFalse(stringHashSet.contains(uploadResultActivity
|
||||
.getString(R.string.send_google_success_footer)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the display of dialog when match following items:
|
||||
* <ul>
|
||||
* <li>Only send to Maps and Docs.</li>
|
||||
* <li>Send to Maps successful.</li>
|
||||
* <li>Send to Docs failed.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public void testPartialSuccess() {
|
||||
initialActivity(true, false, true, true, false, false);
|
||||
|
||||
HashSet<String> stringHashSet = new HashSet<String>();
|
||||
ArrayList<View> view = solo.getViews();
|
||||
for (View oneView : view) {
|
||||
if (oneView instanceof TextView && oneView.isShown()) {
|
||||
stringHashSet.add((String) ((TextView) oneView).getText());
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.generic_error_title)));
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_maps)));
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_docs)));
|
||||
assertTrue(stringHashSet.contains(uploadResultActivity.getString(R.string.send_google_error)));
|
||||
|
||||
assertFalse(stringHashSet.contains(uploadResultActivity
|
||||
.getString(R.string.send_google_fusion_tables)));
|
||||
assertFalse(stringHashSet.contains(uploadResultActivity
|
||||
.getString(R.string.generic_success_title)));
|
||||
assertFalse(stringHashSet.contains(uploadResultActivity
|
||||
.getString(R.string.send_google_success_footer)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial a {@link SendRequest} and then initials a activity to be tested.
|
||||
*
|
||||
* @param isSendMaps
|
||||
* @param isSendFusionTables
|
||||
* @param isSendDocs
|
||||
* @param isMapsSuccess
|
||||
* @param isFusionTablesSuccess
|
||||
* @param isDocsSuccess
|
||||
*/
|
||||
private void initialActivity(boolean isSendMaps, boolean isSendFusionTables, boolean isSendDocs,
|
||||
boolean isMapsSuccess, boolean isFusionTablesSuccess, boolean isDocsSuccess) {
|
||||
Intent intent = new Intent();
|
||||
SendRequest sendRequest = new SendRequest(1L, true, true, true);
|
||||
sendRequest.setSendMaps(isSendMaps);
|
||||
sendRequest.setSendFusionTables(isSendFusionTables);
|
||||
sendRequest.setSendDocs(isSendDocs);
|
||||
sendRequest.setMapsSuccess(isMapsSuccess);
|
||||
sendRequest.setFusionTablesSuccess(isFusionTablesSuccess);
|
||||
sendRequest.setDocsSuccess(isDocsSuccess);
|
||||
intent.putExtra(SendRequest.SEND_REQUEST_KEY, sendRequest);
|
||||
setActivityIntent(intent);
|
||||
uploadResultActivity = this.getActivity();
|
||||
}
|
||||
|
||||
}
|
||||