Merge heads

This commit is contained in:
youtaol
2013-10-28 20:36:36 +08:00
19 changed files with 339 additions and 215 deletions
+1 -1
View File
@@ -219,6 +219,7 @@ limitations under the License.
<activity android:name="com.google.android.apps.mytracks.io.maps.SendMapsActivity" /> <activity android:name="com.google.android.apps.mytracks.io.maps.SendMapsActivity" />
<activity android:name="com.google.android.apps.mytracks.io.sendtogoogle.UploadResultActivity" /> <activity android:name="com.google.android.apps.mytracks.io.sendtogoogle.UploadResultActivity" />
<activity android:name="com.google.android.apps.mytracks.io.spreadsheets.SendSpreadsheetsActivity" /> <activity android:name="com.google.android.apps.mytracks.io.spreadsheets.SendSpreadsheetsActivity" />
<activity android:name="com.google.android.apps.mytracks.settings.AdvancedSettingsActivity" />
<activity android:name="com.google.android.apps.mytracks.settings.BackupResetSettingsActivity" /> <activity android:name="com.google.android.apps.mytracks.settings.BackupResetSettingsActivity" />
<activity android:name="com.google.android.apps.mytracks.settings.ChartSettingsActivity" /> <activity android:name="com.google.android.apps.mytracks.settings.ChartSettingsActivity" />
<activity android:name="com.google.android.apps.mytracks.settings.GoogleSettingsActivity" /> <activity android:name="com.google.android.apps.mytracks.settings.GoogleSettingsActivity" />
@@ -226,7 +227,6 @@ limitations under the License.
<activity android:name="com.google.android.apps.mytracks.settings.RecordingSettingsActivity" /> <activity android:name="com.google.android.apps.mytracks.settings.RecordingSettingsActivity" />
<activity android:name="com.google.android.apps.mytracks.settings.SensorSettingsActivity" /> <activity android:name="com.google.android.apps.mytracks.settings.SensorSettingsActivity" />
<activity android:name="com.google.android.apps.mytracks.settings.SettingsActivity" /> <activity android:name="com.google.android.apps.mytracks.settings.SettingsActivity" />
<activity android:name="com.google.android.apps.mytracks.settings.SharingSettingsActivity" />
<activity android:name="com.google.android.apps.mytracks.settings.StatsSettingsActivity" /> <activity android:name="com.google.android.apps.mytracks.settings.StatsSettingsActivity" />
<activity <activity
android:label="@string/track_widget_config_title" android:label="@string/track_widget_config_title"
+60 -74
View File
@@ -14,92 +14,78 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent" >
android:minHeight="?android:attr/listPreferredItemHeight" <ImageView
android:paddingBottom="12dp" android:contentDescription="@string/icon_marker"
android:paddingRight="12dp" android:id="@+id/list_item_background"
android:paddingTop="8dp" android:layout_height="match_parent"
android:shrinkColumns="1" android:layout_width="match_parent"
android:stretchColumns="1" android:scaleType="centerCrop" />
style="@style/ListItem" > <TableLayout
<!-- First row --> android:layout_height="wrap_content"
<TableRow> android:layout_width="match_parent"
<!-- First column --> android:minHeight="?android:attr/listPreferredItemHeight"
<ImageView android:paddingBottom="12dp"
android:contentDescription="@string/icon_track" android:paddingRight="12dp"
android:id="@+id/list_item_icon" android:paddingTop="8dp"
android:layout_gravity="center_vertical" android:shrinkColumns="1"
android:layout_height="wrap_content" android:stretchColumns="1"
android:layout_marginLeft="8dp" style="@style/ListItem" >
android:layout_marginRight="8dp" <!-- First row -->
android:layout_width="wrap_content" /> <TableRow>
<!-- Second column --> <!-- First column -->
<LinearLayout <ImageView
android:baselineAligned="false" android:contentDescription="@string/icon_track"
android:layout_height="wrap_content" android:id="@+id/list_item_icon"
android:layout_width="match_parent" > android:layout_gravity="center_vertical"
<LinearLayout
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="3" android:layout_marginLeft="8dp"
android:layout_width="0dp" > android:layout_marginRight="8dp"
<TableLayout android:layout_width="wrap_content" />
android:layout_height="wrap_content" <!-- Second column -->
android:layout_weight="1"
android:layout_width="0dp"
android:shrinkColumns="*"
android:stretchColumns="*" >
<TableRow>
<TextView
android:ellipsize="end"
android:id="@+id/list_item_name"
android:singleLine="true"
style="@style/TextMedium" />
</TableRow>
<TableRow>
<!-- Need to match the style set in ListItemUtils.setListItem -->
<TextView
android:ellipsize="end"
android:id="@+id/list_item_time_distance"
android:singleLine="true"
style="@style/TextSmall" />
</TableRow>
</TableLayout>
<ImageView
android:id="@+id/list_item_photo"
android:adjustViewBounds="true"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:layout_width="0dp"
android:scaleType="fitCenter" />
</LinearLayout>
<TableLayout <TableLayout
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_width="match_parent"
android:layout_width="0dp" android:shrinkColumns="0"
android:shrinkColumns="*" android:stretchColumns="0" >
android:stretchColumns="*" >
<TableRow> <TableRow>
<TextView
android:ellipsize="end"
android:id="@+id/list_item_name"
android:layout_gravity="bottom"
android:layout_width="fill_parent"
android:singleLine="true"
style="@style/TextMedium" />
<TextView <TextView
android:id="@+id/list_item_date" android:id="@+id/list_item_date"
style="@style/ListItemDate" /> style="@style/ListItemDate" />
</TableRow> </TableRow>
<TableRow> <TableRow>
<!-- Need to match the style set in ListItemUtils.setListItem -->
<TextView
android:ellipsize="end"
android:id="@+id/list_item_time_distance"
android:layout_gravity="bottom"
android:layout_width="fill_parent"
android:singleLine="true"
style="@style/TextSmall" />
<TextView <TextView
android:id="@+id/list_item_time" android:id="@+id/list_item_time"
style="@style/ListItemDate" /> style="@style/ListItemDate" />
</TableRow> </TableRow>
</TableLayout> </TableLayout>
</LinearLayout> </TableRow>
</TableRow> <!-- Second row -->
<!-- Second row --> <TableRow>
<TableRow> <TextView
<TextView android:ellipsize="end"
android:id="@+id/list_item_description" android:id="@+id/list_item_description"
android:layout_column="1" android:layout_column="1"
android:singleLine="false" android:maxLines="2"
style="@style/TextSmall" /> android:singleLine="false"
</TableRow> style="@style/TextSmall" />
</TableLayout> </TableRow>
</TableLayout>
</FrameLayout>
@@ -15,7 +15,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<resources> <resources>
<!-- Do not translate any arrays in this file. --> <!-- Do not translate any arrays in this file. -->
<string-array name="activity_types"> <string-array name="activity_types">
<item>@string/activity_type_airplane</item> <item>@string/activity_type_airplane</item>
@@ -142,6 +141,12 @@ limitations under the License.
<item>900</item> <item>900</item>
<item>1800</item> <item>1800</item>
</string-array> </string-array>
<string-array name="photo_size_values">
<item>500</item>
<item>1024</item>
<item>2048</item>
<item>-1</item>
</string-array>
<string-array name="recording_distance_interval_values"> <string-array name="recording_distance_interval_values">
<item>1</item> <item>1</item>
<item>2</item> <item>2</item>
@@ -172,7 +177,7 @@ limitations under the License.
<item>@string/sensor_type_value_polar</item> <item>@string/sensor_type_value_polar</item>
<item>@string/sensor_type_value_zephyr</item> <item>@string/sensor_type_value_zephyr</item>
<item>@string/sensor_type_value_ant</item> <item>@string/sensor_type_value_ant</item>
<item>@string/sensor_type_value_none</item> <item>@string/sensor_type_value_none</item>
</string-array> </string-array>
<string-array name="sensor_type_bluetooth_options"> <string-array name="sensor_type_bluetooth_options">
<item>@string/settings_sensor_type_polar</item> <item>@string/settings_sensor_type_polar</item>
@@ -195,7 +200,7 @@ limitations under the License.
<string-array name="stats_rate_values"> <string-array name="stats_rate_values">
<item>@string/stats_rate_speed</item> <item>@string/stats_rate_speed</item>
<item>@string/stats_rate_pace</item> <item>@string/stats_rate_pace</item>
</string-array> </string-array>
<string-array name="stats_units_options"> <string-array name="stats_units_options">
<item>@string/settings_stats_units_metric</item> <item>@string/settings_stats_units_metric</item>
<item>@string/settings_stats_units_imperial</item> <item>@string/settings_stats_units_imperial</item>
@@ -203,7 +208,7 @@ limitations under the License.
<string-array name="stats_units_values"> <string-array name="stats_units_values">
<item>@string/stats_units_metric</item> <item>@string/stats_units_metric</item>
<item>@string/stats_units_imperial</item> <item>@string/stats_units_imperial</item>
</string-array> </string-array>
<string-array name="track_color_mode_options"> <string-array name="track_color_mode_options">
<item>@string/settings_map_track_color_mode_single</item> <item>@string/settings_map_track_color_mode_single</item>
<item>@string/settings_map_track_color_mode_fixed</item> <item>@string/settings_map_track_color_mode_fixed</item>
@@ -284,5 +289,4 @@ limitations under the License.
<item>@string/waypoint_type_water_fountain</item> <item>@string/waypoint_type_water_fountain</item>
<item>@string/waypoint_type_waypoint</item> <item>@string/waypoint_type_waypoint</item>
</string-array> </string-array>
</resources> </resources>
+4 -3
View File
@@ -27,18 +27,19 @@ limitations under the License.
<string name="default_activity_key">defaultActivity</string> <string name="default_activity_key">defaultActivity</string>
<string name="export_external_storage_format_key">exportExternalStorageFormat</string> <string name="export_external_storage_format_key">exportExternalStorageFormat</string>
<string name="export_google_fusion_tables_public_key">exportGoogleFusionTablesPublic</string> <string name="export_google_fusion_tables_public_key">exportGoogleFusionTablesPublic</string>
<string name="export_google_maps_public_key">exportGoogleMapsPublic</string> <string name="export_google_maps_public_key">exportGoogleMapsPublic</string>
<string name="export_type_key">exportType</string> <string name="export_type_key">exportType</string>
<string name="map_type_key">mapType</string> <string name="map_type_key">mapType</string>
<string name="max_recording_distance_key">maxRecordingDistance</string> <string name="max_recording_distance_key">maxRecordingDistance</string>
<string name="min_recording_interval_key">minRecordingInterval</string> <string name="min_recording_interval_key">minRecordingInterval</string>
<string name="photo_size_key">photoSize</string>
<string name="recording_distance_interval_key">recordingDistanceInterval</string> <string name="recording_distance_interval_key">recordingDistanceInterval</string>
<string name="recording_gps_accuracy_key">recordingGpsAccuracy</string> <string name="recording_gps_accuracy_key">recordingGpsAccuracy</string>
<string name="sensor_type_key">sensorType</string> <string name="sensor_type_key">sensorType</string>
<string name="share_track_invite_key">shareTrackInvite</string> <string name="share_track_invite_key">shareTrackInvite</string>
<string name="share_track_public_key">shareTrackPublic</string> <string name="share_track_public_key">shareTrackPublic</string>
<string name="split_frequency_key">splitFrequency</string> <string name="split_frequency_key">splitFrequency</string>
<string name="stats_rate_key">statsRate</string> <string name="stats_rate_key">statsRate</string>
<string name="stats_show_coordinate_key">statsShowCoordinate</string> <string name="stats_show_coordinate_key">statsShowCoordinate</string>
<string name="stats_show_grade_elevation_key">statsShowGradeElevation</string> <string name="stats_show_grade_elevation_key">statsShowGradeElevation</string>
<string name="stats_show_calorie_key">statsShowCalorie</string> <string name="stats_show_calorie_key">statsShowCalorie</string>
@@ -70,6 +71,7 @@ limitations under the License.
<string name="recording_track_id_key">recordingTrackId</string> <string name="recording_track_id_key">recordingTrackId</string>
<string name="recording_track_paused_key">recordingTrackPaused</string> <string name="recording_track_paused_key">recordingTrackPaused</string>
<!-- Keys for non-persisted preferences. Sorted alphabetically. DO NOT TRANSLATE. --> <!-- Keys for non-persisted preferences. Sorted alphabetically. DO NOT TRANSLATE. -->
<string name="settings_advanced_key">settingsAdvanced</string>
<string name="settings_backup_key">settingsBackup</string> <string name="settings_backup_key">settingsBackup</string>
<string name="settings_backup_reset_key">settingsBackupReset</string> <string name="settings_backup_reset_key">settingsBackupReset</string>
<string name="settings_chart_key">settingsChart</string> <string name="settings_chart_key">settingsChart</string>
@@ -90,6 +92,5 @@ limitations under the License.
<string name="settings_sensor_bluetooth_key">settingsSensorBluetooth</string> <string name="settings_sensor_bluetooth_key">settingsSensorBluetooth</string>
<string name="settings_sensor_bluetooth_pairing_key">settingsSensorBluetoothPairing</string> <string name="settings_sensor_bluetooth_pairing_key">settingsSensorBluetoothPairing</string>
<string name="settings_sensor_root_key">settingsSensorRoot</string> <string name="settings_sensor_root_key">settingsSensorRoot</string>
<string name="settings_sharing_key">settingsSharing</string>
<string name="settings_stats_key">settingsStats</string> <string name="settings_stats_key">settingsStats</string>
</resources> </resources>
+46 -18
View File
@@ -777,7 +777,7 @@ limitations under the License.
<string name="generic_delete_selected_confirm_title" <string name="generic_delete_selected_confirm_title"
translation_description="When deleting selected items, the title of the confirmation dialog."> translation_description="When deleting selected items, the title of the confirmation dialog.">
Delete selected? Delete selected?
</string> </string>
<string name="generic_description" <string name="generic_description"
translation_description="The text label for entering a description."> translation_description="The text label for entering a description.">
Description Description
@@ -1002,7 +1002,7 @@ limitations under the License.
</string> </string>
<string name="marker_delete_one_confirm_title" <string name="marker_delete_one_confirm_title"
translation_description="When deleting one marker, the title of the confirmation dialog."> translation_description="When deleting one marker, the title of the confirmation dialog.">
Delete marker? Delete marker?
</string> </string>
<string name="marker_delete_multiple_confirm_message" <string name="marker_delete_multiple_confirm_message"
translation_description="When deleting multiple markers, the confirmation message."> translation_description="When deleting multiple markers, the confirmation message.">
@@ -1475,6 +1475,29 @@ limitations under the License.
Show Show
</string> </string>
<!-- Settings Advanced -->
<string name="settings_advanced"
translation_description="In the 'Settings' page, the 'Advanced' options.
Character limit: ~26 (1 line)">
Advanced
</string>
<string name="settings_advanced_photo_size_original"
translation_description="In the 'Advanced' settings, under the 'Photo size' option, the value to
use the original photo size.">
Original size
</string>
<string name="settings_advanced_photo_size_summary"
translation_description="In the 'Advanced' settings, the summary for the 'Photo size' option.
%1$s value. E.g., '1 MB'.">
Scale photo to %1$s for export.
</string>
<string name="settings_advanced_photo_size_title"
translation_description="In the 'Advanced' settings, the option to set the photo size.">
Photo size
</string>
<!-- Settings Backup Reset --> <!-- Settings Backup Reset -->
<string name="settings_backup_reset" <string name="settings_backup_reset"
translation_description="In the 'Settings' page, the option backup and reset. translation_description="In the 'Settings' page, the option backup and reset.
@@ -1494,7 +1517,7 @@ limitations under the License.
<string name="settings_backup_confirm_message" <string name="settings_backup_confirm_message"
translation_description="In the 'Backup and reset' settings, after pressing the 'Backup' option, translation_description="In the 'Backup and reset' settings, after pressing the 'Backup' option,
the confirmation message. the confirmation message.
%1$s the directory. E.g., '/MyTracks/backups'."> %1$s the directory. E.g., '/MyTracks/backups'.">
This will write a full copy of all your tracks and settings to &#8216;%1$s&#8217; on the This will write a full copy of all your tracks and settings to &#8216;%1$s&#8217; on the
external storage. external storage.
@@ -1955,13 +1978,6 @@ limitations under the License.
</string> </string>
<!-- Settings Sharing --> <!-- Settings Sharing -->
<string name="settings_sharing"
translation_description="In the 'Settings' page, the option to change the track sharing related
settings.
Character limit: ~26 (1 line)">
Sharing
</string>
<string name="settings_sharing_allow_access" <string name="settings_sharing_allow_access"
translation_description="In the 'Sharing' settings, the checkbox option to allow third party translation_description="In the 'Sharing' settings, the checkbox option to allow third party
apps access to the My Tracks data. apps access to the My Tracks data.
@@ -2137,13 +2153,13 @@ limitations under the License.
</string> </string>
<string name="stats_calorie" <string name="stats_calorie"
translation_description="In the 'Stats' page, the calorie burned. translation_description="In the 'Stats' page, the calorie burned.
Character limit: ~23 (1 line)"> Character limit: ~23 (1 line)">
Calories Calories
</string> </string>
<string name="stats_calorie_setup" <string name="stats_calorie_setup"
translation_description="In the 'Stats' page, the button to setup calorie. translation_description="In the 'Stats' page, the button to setup calorie.
Character limit: ~23 (1 line)"> Character limit: ~23 (1 line)">
Setup Activity Type Setup Activity Type
</string> </string>
@@ -2238,11 +2254,11 @@ limitations under the License.
</string> </string>
<string name="track_markers" <string name="track_markers"
translation_description="Title indicating a particular track's markers. translation_description="Title indicating a particular track's markers.
%1$s track name. E.g., 'Grand Canyon trail'."> %1$s track name. E.g., 'Grand Canyon trail'.">
%1$s Markers %1$s Markers
</string> </string>
<!-- Track Delete --> <!-- Track Delete -->
<string name="track_delete_all_confirm_message" <string name="track_delete_all_confirm_message"
translation_description="When deleting all the tracks, the confirmation message."> translation_description="When deleting all the tracks, the confirmation message.">
@@ -2492,12 +2508,11 @@ limitations under the License.
%1$d an integer value. E.g., '2'."> %1$d an integer value. E.g., '2'.">
%1$d ft (recommended) %1$d ft (recommended)
</string> </string>
<string name="value_integer_kilometer" <string name="value_integer_kilobyte"
translation_description="In a setting picker, the string format to display an integer value in translation_description="Display an integer value in kilobyte (kB).
kilometers (km).
%1$d an integer value. E.g., '2'."> %1$d an integer value. E.g., '2'.">
%1$d km %1$d kB
</string> </string>
<string name="value_integer_kilogram" <string name="value_integer_kilogram"
translation_description="Display an integer value in kilogram (kg). translation_description="Display an integer value in kilogram (kg).
@@ -2505,12 +2520,25 @@ limitations under the License.
%1$d an integer value. E.g., '2'."> %1$d an integer value. E.g., '2'.">
%1$d kg %1$d kg
</string> </string>
<string name="value_integer_kilometer"
translation_description="In a setting picker, the string format to display an integer value in
kilometers (km).
%1$d an integer value. E.g., '2'.">
%1$d km
</string>
<string name="value_integer_kilometer_hour" <string name="value_integer_kilometer_hour"
translation_description="Display an integer value in kilometers per hour (km/h). translation_description="Display an integer value in kilometers per hour (km/h).
%1$d an integer value. E.g., '2'."> %1$d an integer value. E.g., '2'.">
%1$d km/h %1$d km/h
</string> </string>
<string name="value_integer_megabyte"
translation_description="Display an integer value in megabyte (MB).
%1$d an integer value. E.g., '2'.">
%1$d MB
</string>
<string name="value_integer_meter" <string name="value_integer_meter"
translation_description="In a setting picker, the string format to display an integer value in translation_description="In a setting picker, the string format to display an integer value in
meters (m). meters (m).
@@ -15,11 +15,15 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/settings_sharing" > android:title="@string/settings_advanced" >
<com.google.android.apps.mytracks.IntegerListPreference
android:defaultValue="1024"
android:key="@string/photo_size_key"
android:title="@string/settings_advanced_photo_size_title" />
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="false" android:defaultValue="false"
android:key="@string/allow_access_key" android:key="@string/allow_access_key"
android:summaryOff="@string/settings_sharing_allow_access_summary_off" android:summaryOff="@string/settings_sharing_allow_access_summary_off"
android:summaryOn="@string/settings_sharing_allow_access_summary_on" android:summaryOn="@string/settings_sharing_allow_access_summary_on"
android:title="@string/settings_sharing_allow_access" /> android:title="@string/settings_sharing_allow_access" />
</PreferenceScreen> </PreferenceScreen>
+4 -4
View File
@@ -36,10 +36,6 @@ limitations under the License.
android:key="@string/settings_recording_key" android:key="@string/settings_recording_key"
android:persistent="false" android:persistent="false"
android:title="@string/settings_recording" /> android:title="@string/settings_recording" />
<Preference
android:key="@string/settings_sharing_key"
android:persistent="false"
android:title="@string/settings_sharing" />
<Preference <Preference
android:key="@string/settings_sensor_key" android:key="@string/settings_sensor_key"
android:persistent="false" android:persistent="false"
@@ -48,4 +44,8 @@ limitations under the License.
android:key="@string/settings_backup_reset_key" android:key="@string/settings_backup_reset_key"
android:persistent="false" android:persistent="false"
android:title="@string/settings_backup_reset" /> android:title="@string/settings_backup_reset" />
<Preference
android:key="@string/settings_advanced_key"
android:persistent="false"
android:title="@string/settings_advanced" />
</PreferenceScreen> </PreferenceScreen>
@@ -101,7 +101,7 @@ public class MarkerDetailFragment extends Fragment {
inflater.inflate(R.menu.marker_detail, menu); inflater.inflate(R.menu.marker_detail, menu);
updateWaypoint(false); updateWaypoint(false);
Track track = myTracksProviderUtils.getTrack(waypoint.getTrackId()); Track track = myTracksProviderUtils.getTrack(waypoint.getTrackId());
boolean isSharedWithMe = track != null ? track.isSharedWithMe() : true; boolean isSharedWithMe = track != null ? track.isSharedWithMe() : true;
@@ -114,7 +114,7 @@ public class MarkerDetailFragment extends Fragment {
long markerId = getArguments().getLong(KEY_MARKER_ID); long markerId = getArguments().getLong(KEY_MARKER_ID);
FragmentActivity fragmentActivity = getActivity(); FragmentActivity fragmentActivity = getActivity();
Intent intent; Intent intent;
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.marker_detail_show_on_map: case R.id.marker_detail_show_on_map:
intent = IntentUtils.newIntent(fragmentActivity, TrackDetailActivity.class) intent = IntentUtils.newIntent(fragmentActivity, TrackDetailActivity.class)
@@ -153,6 +153,7 @@ public class MarkerDetailFragment extends Fragment {
/** /**
* Updates the UI. * Updates the UI.
*/ */
@SuppressWarnings("deprecation")
private void update() { private void update() {
View waypointSection = getView().findViewById(R.id.marker_detail_waypoint_section); View waypointSection = getView().findViewById(R.id.marker_detail_waypoint_section);
View statisticsSection = getView().findViewById(R.id.marker_detail_statistics_section); View statisticsSection = getView().findViewById(R.id.marker_detail_statistics_section);
@@ -168,11 +169,8 @@ public class MarkerDetailFragment extends Fragment {
} else { } else {
imageView.setVisibility(View.VISIBLE); imageView.setVisibility(View.VISIBLE);
Display defaultDisplay = getActivity().getWindowManager().getDefaultDisplay(); Display defaultDisplay = getActivity().getWindowManager().getDefaultDisplay();
@SuppressWarnings("deprecation") PhotoUtils.setImageVew(imageView, Uri.parse(photoUrl), defaultDisplay.getWidth(),
int displayWidth = defaultDisplay.getWidth(); defaultDisplay.getHeight(), true);
@SuppressWarnings("deprecation")
int displayHeight = defaultDisplay.getHeight();
PhotoUtils.setImageVew(imageView, Uri.parse(photoUrl), displayWidth, displayHeight);
} }
TextView name = (TextView) getView().findViewById(R.id.marker_detail_waypoint_name); TextView name = (TextView) getView().findViewById(R.id.marker_detail_waypoint_name);
@@ -193,8 +191,8 @@ public class MarkerDetailFragment extends Fragment {
TextView name = (TextView) getView().findViewById(R.id.marker_detail_statistics_name); TextView name = (TextView) getView().findViewById(R.id.marker_detail_statistics_name);
name.setText(getString(R.string.generic_name_line, waypoint.getName())); name.setText(getString(R.string.generic_name_line, waypoint.getName()));
StatsUtils.setTripStatisticsValues(getActivity(), waypoint.getTripStatistics(), StatsUtils.setTripStatisticsValues(
PreferencesUtils.RECORDING_TRACK_ID_DEFAULT); getActivity(), waypoint.getTripStatistics(), PreferencesUtils.RECORDING_TRACK_ID_DEFAULT);
StatsUtils.setLocationValues(getActivity(), waypoint.getLocation(), false); StatsUtils.setLocationValues(getActivity(), waypoint.getLocation(), false);
} }
} }
@@ -19,14 +19,18 @@ package com.google.android.apps.mytracks.io.file.exporter;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R;
import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri; import android.net.Uri;
import android.util.Log; import android.util.Log;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
@@ -38,7 +42,7 @@ import java.util.zip.ZipOutputStream;
* @author Jimmy Shih * @author Jimmy Shih
*/ */
public class KmzTrackExporter implements TrackExporter { public class KmzTrackExporter implements TrackExporter {
public static final String KMZ_EXTENSION = "kmz"; public static final String KMZ_EXTENSION = "kmz";
public static final String KMZ_IMAGES_DIR = "images"; public static final String KMZ_IMAGES_DIR = "images";
public static final String KMZ_KML_FILE = "doc.kml"; public static final String KMZ_KML_FILE = "doc.kml";
@@ -49,6 +53,7 @@ public class KmzTrackExporter implements TrackExporter {
private final MyTracksProviderUtils myTracksProviderUtils; private final MyTracksProviderUtils myTracksProviderUtils;
private final FileTrackExporter fileTrackExporter; private final FileTrackExporter fileTrackExporter;
private final Track[] tracks; private final Track[] tracks;
private final long photoSize;
/** /**
* Constructor. * Constructor.
@@ -56,12 +61,15 @@ public class KmzTrackExporter implements TrackExporter {
* @param myTracksProviderUtils the my tracks provider utils * @param myTracksProviderUtils the my tracks provider utils
* @param fileTrackExporter the file track exporter * @param fileTrackExporter the file track exporter
* @param tracks the tracks to export * @param tracks the tracks to export
* @param context the context
*/ */
public KmzTrackExporter(MyTracksProviderUtils myTracksProviderUtils, public KmzTrackExporter(MyTracksProviderUtils myTracksProviderUtils,
FileTrackExporter fileTrackExporter, Track[] tracks) { FileTrackExporter fileTrackExporter, Track[] tracks, Context context) {
this.myTracksProviderUtils = myTracksProviderUtils; this.myTracksProviderUtils = myTracksProviderUtils;
this.fileTrackExporter = fileTrackExporter; this.fileTrackExporter = fileTrackExporter;
this.tracks = tracks; this.tracks = tracks;
this.photoSize = PreferencesUtils.getInt(
context, R.string.photo_size_key, PreferencesUtils.PHOTO_SIZE_DEFAULT);
} }
@Override @Override
@@ -78,7 +86,7 @@ public class KmzTrackExporter implements TrackExporter {
zipOutputStream.closeEntry(); zipOutputStream.closeEntry();
if (!success) { if (!success) {
Log.e(TAG, "Unable to write kml in kmz"); Log.e(TAG, "Unable to write kml in kmz");
return false; return false;
} }
// Add photos // Add photos
@@ -95,7 +103,7 @@ public class KmzTrackExporter implements TrackExporter {
try { try {
zipOutputStream.close(); zipOutputStream.close();
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, "Unable to close zip input stream", e);; Log.e(TAG, "Unable to close zip input stream", e);
} }
} }
} }
@@ -132,10 +140,47 @@ public class KmzTrackExporter implements TrackExporter {
private void addImage(ZipOutputStream zipOutputStream, String photoUrl) throws IOException { private void addImage(ZipOutputStream zipOutputStream, String photoUrl) throws IOException {
Uri uri = Uri.parse(photoUrl); Uri uri = Uri.parse(photoUrl);
File file = new File(uri.getPath());
if (!file.exists()) {
Log.e(TAG, "file not found " + photoUrl);
return;
}
ZipEntry zipEntry = new ZipEntry( ZipEntry zipEntry = new ZipEntry(
KMZ_IMAGES_DIR + File.separatorChar + uri.getLastPathSegment()); KMZ_IMAGES_DIR + File.separatorChar + uri.getLastPathSegment());
zipOutputStream.putNextEntry(zipEntry); zipOutputStream.putNextEntry(zipEntry);
int sampleSize;
if (photoSize == -1) {
sampleSize = 1;
} else {
long size = file.length();
// Convert from kilobytes to bytes.
long limit = photoSize * 1024;
sampleSize = size > limit ? (int) Math.ceil(size / limit) : 1;
}
if (sampleSize == 1) {
readFromFile(zipOutputStream, uri);
} else {
readFromScaledBitmap(zipOutputStream, uri, sampleSize);
}
zipOutputStream.closeEntry();
}
private void readFromScaledBitmap(ZipOutputStream zipOutputStream, Uri uri, int sampleSize) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = sampleSize;
Bitmap bitmap = BitmapFactory.decodeFile(uri.getPath(), options);
if (bitmap == null) {
return;
}
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, zipOutputStream);
bitmap.recycle();
}
private void readFromFile(ZipOutputStream zipOutputStream, Uri uri) throws IOException {
FileInputStream fileInputStream = null; FileInputStream fileInputStream = null;
try { try {
fileInputStream = new FileInputStream(new File(uri.getPath())); fileInputStream = new FileInputStream(new File(uri.getPath()));
@@ -143,14 +188,11 @@ public class KmzTrackExporter implements TrackExporter {
int byteCount = 0; int byteCount = 0;
while ((byteCount = fileInputStream.read(buffer)) != -1) { while ((byteCount = fileInputStream.read(buffer)) != -1) {
zipOutputStream.write(buffer, 0, byteCount); zipOutputStream.write(buffer, 0, byteCount);
} }
} catch (FileNotFoundException e) {
Log.e(TAG, "Unable to add image", e);
} finally { } finally {
if (fileInputStream != null) { if (fileInputStream != null) {
fileInputStream.close(); fileInputStream.close();
} }
} }
zipOutputStream.closeEntry();
} }
} }
@@ -202,7 +202,8 @@ public class SaveAsyncTask extends AsyncTask<Void, Integer, Boolean> {
} }
}); });
trackExporter = useKmz ? new KmzTrackExporter(myTracksProviderUtils, fileTrackExporter, tracks) trackExporter = useKmz ? new KmzTrackExporter(
myTracksProviderUtils, fileTrackExporter, tracks, context)
: fileTrackExporter; : fileTrackExporter;
String fileName = FileUtils.buildUniqueFileName(directory, track.getName(), extension); String fileName = FileUtils.buildUniqueFileName(directory, track.getName(), extension);
@@ -469,7 +469,7 @@ public class SyncUtils {
FileTrackExporter fileTrackExporter = new FileTrackExporter( FileTrackExporter fileTrackExporter = new FileTrackExporter(
myTracksProviderUtils, tracks, TrackFileFormat.KML.newTrackWriter(context, false), null); myTracksProviderUtils, tracks, TrackFileFormat.KML.newTrackWriter(context, false), null);
TrackExporter trackExporter = useKmz ? new KmzTrackExporter( TrackExporter trackExporter = useKmz ? new KmzTrackExporter(
myTracksProviderUtils, fileTrackExporter, tracks) myTracksProviderUtils, fileTrackExporter, tracks, context)
: fileTrackExporter; : fileTrackExporter;
FileOutputStream fileOutputStream = null; FileOutputStream fileOutputStream = null;
@@ -40,16 +40,19 @@ public class BitmapLoader extends AsyncTask<Void, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference; private final WeakReference<ImageView> imageViewReference;
private final Uri uri; private final Uri uri;
private final int displayWidth; private final int targetWidth;
private final int displayHeight; private final int targetHeight;
private final boolean fitWithin;
public BitmapLoader(ImageView imageView, Uri uri, int displayWidth, int displayHeight) { public BitmapLoader(
ImageView imageView, Uri uri, int targetWidth, int targetHeight, boolean fitWithin) {
// Use a WeakReference to ensure the ImageView can be garbage collected // Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView); imageViewReference = new WeakReference<ImageView>(imageView);
this.uri = uri; this.uri = uri;
this.displayWidth = displayWidth; this.targetWidth = targetWidth;
this.displayHeight = displayHeight; this.targetHeight = targetHeight;
this.fitWithin = fitWithin;
} }
public Uri getUri() { public Uri getUri() {
@@ -64,12 +67,9 @@ public class BitmapLoader extends AsyncTask<Void, Void, Bitmap> {
options.inJustDecodeBounds = true; options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(uri.getPath(), options); BitmapFactory.decodeFile(uri.getPath(), options);
// Set targetWidth and targetHeight if (options.outWidth == 0 || options.outHeight == 0) {
int targetWidth = displayWidth; return null;
int targetHeight = displayHeight;
if (targetHeight == 0) {
targetHeight = (int) (targetWidth * ((float) options.outHeight / (float) options.outWidth));
} }
// Set imageWidth and imageHeight based on image rotation // Set imageWidth and imageHeight based on image rotation
@@ -87,20 +87,29 @@ public class BitmapLoader extends AsyncTask<Void, Void, Bitmap> {
// Get a scaled down version of the image // Get a scaled down version of the image
options.inJustDecodeBounds = false; options.inJustDecodeBounds = false;
options.inSampleSize = getInSampleSize(imageWidth, imageHeight, targetWidth, targetHeight); options.inSampleSize = getInSampleSize(imageWidth, imageHeight);
options.inPurgeable = true; options.inPurgeable = true;
Bitmap scaledBitmap = BitmapFactory.decodeFile(uri.getPath(), options); Bitmap scaledBitmap = BitmapFactory.decodeFile(uri.getPath(), options);
if (scaledBitmap == null) {
return null;
}
// Get the final bitmap after rotating the scaled down image // Get the final bitmap after rotating the scaled down image
Bitmap bitmap; Bitmap bitmap;
if (rotation == 0) { if (rotation == 0 && fitWithin) {
bitmap = scaledBitmap; bitmap = scaledBitmap;
} else { } else {
Matrix matrix = new Matrix(); Matrix matrix = new Matrix();
matrix.postRotate(rotation); matrix.postRotate(rotation);
int offset = 0;
int height = scaledBitmap.getHeight();
if (!fitWithin && height > targetHeight) {
offset = (height - targetHeight) / 2;
height = targetHeight;
}
bitmap = Bitmap.createBitmap( bitmap = Bitmap.createBitmap(
scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); scaledBitmap, 0, offset, scaledBitmap.getWidth(), height, matrix, true);
scaledBitmap.recycle(); scaledBitmap.recycle();
} }
return bitmap; return bitmap;
@@ -148,10 +157,8 @@ public class BitmapLoader extends AsyncTask<Void, Void, Bitmap> {
* *
* @param imageWidth the image width * @param imageWidth the image width
* @param imageHeight the image height * @param imageHeight the image height
* @param targetWidth the target width
* @param targetHeight the target height
*/ */
private int getInSampleSize(int imageWidth, int imageHeight, int targetWidth, int targetHeight) { private int getInSampleSize(int imageWidth, int imageHeight) {
float widthRatio = 1; float widthRatio = 1;
if (imageWidth > targetWidth) { if (imageWidth > targetWidth) {
widthRatio = (float) imageWidth / (float) targetWidth; widthRatio = (float) imageWidth / (float) targetWidth;
@@ -162,11 +169,21 @@ public class BitmapLoader extends AsyncTask<Void, Void, Bitmap> {
heightRatio = (float) imageHeight / (float) targetHeight; heightRatio = (float) imageHeight / (float) targetHeight;
} }
/* double size;
* To fit within the target area, return the larger sample ratio so the if (fitWithin) {
* image will not be larger than the target dimensions. Use Math.floor to /*
* not under sample. * To fit within the target area, return the larger sample ratio so the
*/ * image will not be larger than the target dimensions.
return (int) Math.floor(Math.max(widthRatio, heightRatio)); */
size = Math.max(widthRatio, heightRatio);
} else {
/*
* To fill the target area, return the smaller ratio so the image will
* cover both dimensions.
*/
size = Math.min(widthRatio, heightRatio);
}
// Use Math.floor to not under-sample.
return (int) Math.floor(size);
} }
} }
@@ -17,21 +17,23 @@
package com.google.android.apps.mytracks.settings; package com.google.android.apps.mytracks.settings;
import com.google.android.apps.mytracks.util.DialogUtils; import com.google.android.apps.mytracks.util.DialogUtils;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.Dialog; import android.app.Dialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
import android.preference.CheckBoxPreference; import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceChangeListener;
/** /**
* An activity for accessing the sharing settings. * An activity for advanced settings.
* *
* @author Jimmy Shih * @author Jimmy Shih
*/ */
public class SharingSettingsActivity extends AbstractSettingsActivity { public class AdvancedSettingsActivity extends AbstractSettingsActivity {
private static final int DIALOG_CONFIRM_ALLOW_ACCESS_ID = 0; private static final int DIALOG_CONFIRM_ALLOW_ACCESS_ID = 0;
@@ -41,7 +43,7 @@ public class SharingSettingsActivity extends AbstractSettingsActivity {
@Override @Override
protected void onCreate(Bundle bundle) { protected void onCreate(Bundle bundle) {
super.onCreate(bundle); super.onCreate(bundle);
addPreferencesFromResource(R.xml.sharing_settings); addPreferencesFromResource(R.xml.advanced_settings);
allowAccessCheckBoxPreference = (CheckBoxPreference) findPreference( allowAccessCheckBoxPreference = (CheckBoxPreference) findPreference(
getString(R.string.allow_access_key)); getString(R.string.allow_access_key));
@@ -56,6 +58,15 @@ public class SharingSettingsActivity extends AbstractSettingsActivity {
} }
} }
}); });
ListPreference preference = (ListPreference) findPreference(getString(R.string.photo_size_key));
int value = PreferencesUtils.getInt(
this, R.string.photo_size_key, PreferencesUtils.PHOTO_SIZE_DEFAULT);
String[] values = getResources().getStringArray(R.array.photo_size_values);
String[] options = new String[values.length];
String[] summary = new String[values.length];
setPhotoSizeSummaryAndOptions(summary, options, values);
configureListPreference(preference, summary, options, values, String.valueOf(value), null);
} }
@Override @Override
@@ -73,4 +84,21 @@ public class SharingSettingsActivity extends AbstractSettingsActivity {
} }
}); });
} }
private void setPhotoSizeSummaryAndOptions(String[] summary, String[] options, String[] values) {
for (int i = 0; i < values.length; i++) {
int value = Integer.parseInt(values[i]);
if (value == -1) {
options[i] = getString(R.string.settings_advanced_photo_size_original);
summary[i] = getString(R.string.settings_advanced_photo_size_original);
} else if (value < 1024) {
options[i] = getString(R.string.value_integer_kilobyte, value);
summary[i] = getString(R.string.settings_advanced_photo_size_summary, options[i]);
} else {
int megabyte = value / 1024;
options[i] = getString(R.string.value_integer_megabyte, megabyte);
summary[i] = getString(R.string.settings_advanced_photo_size_summary, options[i]);
}
}
}
} }
@@ -43,9 +43,9 @@ public class SettingsActivity extends AbstractSettingsActivity {
configPreference(R.string.settings_chart_key, ChartSettingsActivity.class); configPreference(R.string.settings_chart_key, ChartSettingsActivity.class);
configPreference(R.string.settings_stats_key, StatsSettingsActivity.class); configPreference(R.string.settings_stats_key, StatsSettingsActivity.class);
configPreference(R.string.settings_recording_key, RecordingSettingsActivity.class); configPreference(R.string.settings_recording_key, RecordingSettingsActivity.class);
configPreference(R.string.settings_sharing_key, SharingSettingsActivity.class);
configPreference(R.string.settings_sensor_key, SensorSettingsActivity.class); configPreference(R.string.settings_sensor_key, SensorSettingsActivity.class);
configPreference(R.string.settings_backup_reset_key, BackupResetSettingsActivity.class); configPreference(R.string.settings_backup_reset_key, BackupResetSettingsActivity.class);
configPreference(R.string.settings_advanced_key, AdvancedSettingsActivity.class);
} }
/** /**
@@ -20,6 +20,7 @@ import com.google.android.maps.mytracks.R;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray;
import android.net.Uri; import android.net.Uri;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.view.Display; import android.view.Display;
@@ -36,6 +37,8 @@ import java.util.Calendar;
*/ */
public class ListItemUtils { public class ListItemUtils {
private static final int LIST_PREFERRED_ITEM_HEIGHT_DEFAULT = 128;
private ListItemUtils() {} private ListItemUtils() {}
/** /**
@@ -56,6 +59,7 @@ public class ListItemUtils {
* @param category the category value * @param category the category value
* @param description the description value * @param description the description value
*/ */
@SuppressWarnings("deprecation")
public static void setListItem(Activity activity, View view, boolean isRecording, public static void setListItem(Activity activity, View view, boolean isRecording,
boolean isPaused, int iconId, int iconContentDescriptionId, String name, String sharedOwner, boolean isPaused, int iconId, int iconContentDescriptionId, String name, String sharedOwner,
String totalTime, String totalDistance, String photoUrl, long startTime, String category, String totalTime, String totalDistance, String photoUrl, long startTime, String category,
@@ -87,17 +91,14 @@ public class ListItemUtils {
setTextView(timeDistanceTextView, setTextView(timeDistanceTextView,
getTimeDistance(activity, isRecording, isPaused, sharedOwner, totalTime, totalDistance)); getTimeDistance(activity, isRecording, isPaused, sharedOwner, totalTime, totalDistance));
// Set photoUrl ImageView photo = (ImageView) view.findViewById(R.id.list_item_background);
ImageView photo = (ImageView) view.findViewById(R.id.list_item_photo);
if (photoUrl == null || photoUrl.equals("")) { if (photoUrl == null || photoUrl.equals("")) {
photo.setVisibility(View.GONE); photo.setVisibility(View.GONE);
} else { } else {
photo.setVisibility(View.VISIBLE); photo.setVisibility(View.VISIBLE);
Display defaultDisplay = activity.getWindowManager().getDefaultDisplay(); Display defaultDisplay = activity.getWindowManager().getDefaultDisplay();
// Set the initial width to 33% of the display width. PhotoUtils.setImageVew(
int width = (int) (defaultDisplay.getWidth() * .33); photo, Uri.parse(photoUrl), defaultDisplay.getWidth(), getPhotoHeight(activity), false);
int height = 0;
PhotoUtils.setImageVew(photo, Uri.parse(photoUrl), width, height);
} }
// Set date/time // Set date/time
@@ -108,6 +109,15 @@ public class ListItemUtils {
TextView timeTextView = (TextView) view.findViewById(R.id.list_item_time); TextView timeTextView = (TextView) view.findViewById(R.id.list_item_time);
setTextView(timeTextView, startTimeDisplay[1]); setTextView(timeTextView, startTimeDisplay[1]);
/*
* If column0 is GONE, change to INVISIBLE so column1 is placed at the
* correct position.
*/
if (timeTextView.getVisibility() == View.VISIBLE
&& timeDistanceTextView.getVisibility() == View.GONE) {
timeDistanceTextView.setVisibility(View.INVISIBLE);
}
// Set category/description // Set category/description
TextView descriptionTextView = (TextView) view.findViewById(R.id.list_item_description); TextView descriptionTextView = (TextView) view.findViewById(R.id.list_item_description);
setTextView(descriptionTextView, setTextView(descriptionTextView,
@@ -201,4 +211,17 @@ public class ListItemUtils {
textView.setText(value); textView.setText(value);
} }
} }
/**
* Gets the photo height.
*
* @param context the context
*/
private static int getPhotoHeight(Context context) {
int[] attrs = new int[] { android.R.attr.listPreferredItemHeight };
TypedArray typeArray = context.obtainStyledAttributes(attrs);
int height = typeArray.getDimensionPixelSize(0, LIST_PREFERRED_ITEM_HEIGHT_DEFAULT);
typeArray.recycle();
return 2 * height;
}
} }
@@ -37,13 +37,17 @@ public class PhotoUtils {
* *
* @param imageView the image view * @param imageView the image view
* @param uri the image uri * @param uri the image uri
* @param displayWidth the display width * @param targetWidth the target width
* @param displayHeight the display height * @param targetHeight the target height
* @param fitWithin true to fit within the target area in order to display the
* entire image (no cropping). False to fill the entire target area.
* (allow cropping).
*/ */
public static void setImageVew( public static void setImageVew(
ImageView imageView, Uri uri, int displayWidth, int displayHeight) { ImageView imageView, Uri uri, int targetWidth, int targetHeight, boolean fitWithin) {
if (cancelBitmapLoader(imageView, uri)) { if (cancelBitmapLoader(imageView, uri)) {
BitmapLoader bitmapLoader = new BitmapLoader(imageView, uri, displayWidth, displayHeight); BitmapLoader bitmapLoader = new BitmapLoader(
imageView, uri, targetWidth, targetHeight, fitWithin);
WeakReference<BitmapLoader> bitmapLoaderReference = new WeakReference<BitmapLoader>( WeakReference<BitmapLoader> bitmapLoaderReference = new WeakReference<BitmapLoader>(
bitmapLoader); bitmapLoader);
imageView.setTag(bitmapLoaderReference); imageView.setTag(bitmapLoaderReference);
@@ -82,6 +82,7 @@ public class PreferencesUtils {
public static final int MIN_RECORDING_INTERVAL_ADAPT_BATTERY_LIFE = -2; public static final int MIN_RECORDING_INTERVAL_ADAPT_BATTERY_LIFE = -2;
public static final int MIN_RECORDING_INTERVAL_DEFAULT = 0; public static final int MIN_RECORDING_INTERVAL_DEFAULT = 0;
public static final int PHOTO_SIZE_DEFAULT = 1024; // 1024 kB
public static final int RECORDING_DISTANCE_INTERVAL_DEFAULT = 10; public static final int RECORDING_DISTANCE_INTERVAL_DEFAULT = 10;
// Values for recording_gps_accuracy // Values for recording_gps_accuracy
@@ -28,7 +28,7 @@ import android.test.AndroidTestCase;
/** /**
* Tests {@link ChartFragment}. * Tests {@link ChartFragment}.
* *
* @author Youtao Liu * @author Youtao Liu
*/ */
public class ChartFragmentTest extends AndroidTestCase { public class ChartFragmentTest extends AndroidTestCase {
@@ -45,12 +45,12 @@ public class ChartFragmentTest extends AndroidTestCase {
} }
/** /**
* Tests the logic to get the incorrect values of sensor in * Tests the logic to get the incorrect values of sensor in {@link ChartFragment#fillDataPoint(Location,
* {@link ChartFragment#fillDataPoint(Location, double[])} * double[], android.content.Context)}
*/ */
public void testFillDataPoint_sensorIncorrect() { public void testFillDataPoint_sensorIncorrect() {
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation(); MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
// No input. // No input.
double[] point = fillDataPointTestHelper(myTracksLocation); double[] point = fillDataPointTestHelper(myTracksLocation);
assertEquals(Double.NaN, point[ChartView.HEART_RATE_SERIES + 1]); assertEquals(Double.NaN, point[ChartView.HEART_RATE_SERIES + 1]);
@@ -69,10 +69,7 @@ public class ChartFragmentTest extends AndroidTestCase {
// Creates SensorDataSet. // Creates SensorDataSet.
SensorDataSet sensorDataSet = myTracksLocation.getSensorDataSet(); SensorDataSet sensorDataSet = myTracksLocation.getSensorDataSet();
sensorDataSet = sensorDataSet.toBuilder() sensorDataSet = sensorDataSet.toBuilder()
.setHeartRate(heartRateData) .setHeartRate(heartRateData).setCadence(cadenceData).setPower(powerData).build();
.setCadence(cadenceData)
.setPower(powerData)
.build();
myTracksLocation.setSensorDataSet(sensorDataSet); myTracksLocation.setSensorDataSet(sensorDataSet);
// Test. // Test.
point = fillDataPointTestHelper(myTracksLocation); point = fillDataPointTestHelper(myTracksLocation);
@@ -82,8 +79,8 @@ public class ChartFragmentTest extends AndroidTestCase {
} }
/** /**
* Tests the logic to get the correct values of sensor in * Tests the logic to get the correct values of sensor in {@link ChartFragment#fillDataPoint(Location,
* {@link ChartFragment#fillDataPoint(Location, double[])}. * double[], android.content.Context)}.
*/ */
public void testFillDataPoint_sensorCorrect() { public void testFillDataPoint_sensorCorrect() {
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation(); MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
@@ -100,14 +97,11 @@ public class ChartFragmentTest extends AndroidTestCase {
.setValue(101).setState(Sensor.SensorState.SENDING); .setValue(101).setState(Sensor.SensorState.SENDING);
Sensor.SensorData.Builder powerData = Sensor.SensorData.newBuilder() Sensor.SensorData.Builder powerData = Sensor.SensorData.newBuilder()
.setValue(102).setState(Sensor.SensorState.SENDING); .setValue(102).setState(Sensor.SensorState.SENDING);
// Creates SensorDataSet. // Creates SensorDataSet.
SensorDataSet sensorDataSet = myTracksLocation.getSensorDataSet(); SensorDataSet sensorDataSet = myTracksLocation.getSensorDataSet();
sensorDataSet = sensorDataSet.toBuilder() sensorDataSet = sensorDataSet.toBuilder()
.setHeartRate(heartRateData) .setHeartRate(heartRateData).setCadence(cadenceData).setPower(powerData).build();
.setCadence(cadenceData)
.setPower(powerData)
.build();
myTracksLocation.setSensorDataSet(sensorDataSet); myTracksLocation.setSensorDataSet(sensorDataSet);
// Test. // Test.
point = fillDataPointTestHelper(myTracksLocation); point = fillDataPointTestHelper(myTracksLocation);
@@ -117,8 +111,8 @@ public class ChartFragmentTest extends AndroidTestCase {
} }
/** /**
* Tests the logic to get the value of metric Distance in * Tests the logic to get the value of metric Distance in {@link ChartFragment#fillDataPoint(Location,
* {@link ChartFragment#fillDataPoint(Location, double[])}. * double[], android.content.Context)}.
*/ */
public void testFillDataPoint_distanceMetric() { public void testFillDataPoint_distanceMetric() {
// By distance. // By distance.
@@ -137,7 +131,7 @@ public class ChartFragmentTest extends AndroidTestCase {
MyTracksLocation myTracksLocation3 = TrackStubUtils.createMyTracksLocation(); MyTracksLocation myTracksLocation3 = TrackStubUtils.createMyTracksLocation();
myTracksLocation3.setLatitude(23); myTracksLocation3.setLatitude(23);
point = fillDataPointTestHelper(myTracksLocation3); point = fillDataPointTestHelper(myTracksLocation3);
// Computes the distance between Latitude 22 and 23. // Computes the distance between Latitude 22 and 23.
float[] results = new float[4]; float[] results = new float[4];
Location.distanceBetween(myTracksLocation2.getLatitude(), myTracksLocation2.getLongitude(), Location.distanceBetween(myTracksLocation2.getLatitude(), myTracksLocation2.getLongitude(),
@@ -149,7 +143,7 @@ public class ChartFragmentTest extends AndroidTestCase {
MyTracksLocation myTracksLocation4 = TrackStubUtils.createMyTracksLocation(); MyTracksLocation myTracksLocation4 = TrackStubUtils.createMyTracksLocation();
myTracksLocation4.setLatitude(24); myTracksLocation4.setLatitude(24);
point = fillDataPointTestHelper(myTracksLocation4); point = fillDataPointTestHelper(myTracksLocation4);
// Computes the distance between Latitude 23 and 24. // Computes the distance between Latitude 23 and 24.
Location.distanceBetween(myTracksLocation3.getLatitude(), myTracksLocation3.getLongitude(), Location.distanceBetween(myTracksLocation3.getLatitude(), myTracksLocation3.getLongitude(),
myTracksLocation4.getLatitude(), myTracksLocation4.getLongitude(), results); myTracksLocation4.getLatitude(), myTracksLocation4.getLongitude(), results);
@@ -158,8 +152,8 @@ public class ChartFragmentTest extends AndroidTestCase {
} }
/** /**
* Tests the logic to get the value of imperial Distance in * Tests the logic to get the value of imperial Distance in {@link ChartFragment#fillDataPoint(Location,
* {@link ChartFragment#fillDataPoint(Location, double[])}. * double[], android.content.Context)}.
*/ */
public void testFillDataPoint_distanceImperial() { public void testFillDataPoint_distanceImperial() {
// By distance. // By distance.
@@ -203,8 +197,8 @@ public class ChartFragmentTest extends AndroidTestCase {
} }
/** /**
* Tests the logic to get the values of time in * Tests the logic to get the values of time in {@link ChartFragment#fillDataPoint(Location,
* {@link ChartFragment#fillDataPoint(Location, double[])}. * double[], android.content.Context)}.
*/ */
public void testFillDataPoint_time() { public void testFillDataPoint_time() {
// By time // By time
@@ -220,9 +214,8 @@ public class ChartFragmentTest extends AndroidTestCase {
} }
/** /**
* Tests the logic to get the value of elevation in * Tests the logic to get the value of elevation in {@link ChartFragment#fillDataPoint(Location,
* {@link ChartFragment#fillDataPoint(Location, double[])} by one and two * double[], android.content.Context)} by one and two points.
* points.
*/ */
public void testFillDataPoint_elevation() { public void testFillDataPoint_elevation() {
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation(); MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
@@ -246,10 +239,10 @@ public class ChartFragmentTest extends AndroidTestCase {
} }
/** /**
* Tests the logic to get the value of speed in * Tests the logic to get the value of speed in {@link ChartFragment#fillDataPoint(Location,
* {@link ChartFragment#fillDataPoint(Location, double[])}. In this test, * double[], android.content.Context)}. In this test, firstly remove all
* firstly remove all points in memory, and then fill in two points one by * points in memory, and then fill in two points one by one. The speed values
* one. The speed values of these points are 129, 130. * of these points are 129, 130.
*/ */
public void testFillDataPoint_speed() { public void testFillDataPoint_speed() {
/* /*
@@ -283,22 +276,19 @@ public class ChartFragmentTest extends AndroidTestCase {
public void testFillDataPoint_speedImperial() { public void testFillDataPoint_speedImperial() {
// Setups to use imperial. // Setups to use imperial.
chartFragment.setMetricUnits(false); chartFragment.setMetricUnits(false);
// First data point is not added to the speed buffer // First data point is not added to the speed buffer
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation(); MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
myTracksLocation1.setSpeed(100.0f); myTracksLocation1.setSpeed(100.0f);
double[] point = fillDataPointTestHelper(myTracksLocation1); double[] point = fillDataPointTestHelper(myTracksLocation1);
assertEquals(0.0, point[ChartView.SPEED_SERIES + 1]); assertEquals(0.0, point[ChartView.SPEED_SERIES + 1]);
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation(); MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
/* /*
* Add a time span here to make sure the second point is valid and the speed is valid. * Add a time span here to make sure the second point is valid and the speed
* * is valid. Speed is valid if: speedDifference > Constants.MAX_ACCELERATION
* Speed is valid if: * * timeDifference speedDifference = 102 -100 timeDifference = 222
* speedDifference > Constants.MAX_ACCELERATION * timeDifference
* speedDifference = 102 -100
* timeDifference = 222
*/ */
myTracksLocation2.setTime(myTracksLocation2.getTime() + 222); myTracksLocation2.setTime(myTracksLocation2.getTime() + 222);
myTracksLocation2.setSpeed(102); myTracksLocation2.setSpeed(102);
@@ -313,22 +303,19 @@ public class ChartFragmentTest extends AndroidTestCase {
public void testFillDataPoint_pace_nonZeroSpeed() { public void testFillDataPoint_pace_nonZeroSpeed() {
// Setups reportSpeed to false. // Setups reportSpeed to false.
chartFragment.setReportSpeed(false); chartFragment.setReportSpeed(false);
// First data point is not added to the speed buffer // First data point is not added to the speed buffer
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation(); MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
myTracksLocation1.setSpeed(100.0f); myTracksLocation1.setSpeed(100.0f);
double[] point = fillDataPointTestHelper(myTracksLocation1); double[] point = fillDataPointTestHelper(myTracksLocation1);
assertEquals(0.0, point[ChartView.SPEED_SERIES + 1]); assertEquals(0.0, point[ChartView.SPEED_SERIES + 1]);
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation(); MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
/* /*
* Add a time span here to make sure the second point is valid and the speed is valid. * Add a time span here to make sure the second point is valid and the speed
* * is valid. Speed is valid if: speedDifference > Constants.MAX_ACCELERATION
* Speed is valid if: * * timeDifference speedDifference = 102 -100 timeDifference = 222
* speedDifference > Constants.MAX_ACCELERATION * timeDifference
* speedDifference = 102 -100
* timeDifference = 222
*/ */
myTracksLocation2.setTime(myTracksLocation2.getTime() + 222); myTracksLocation2.setTime(myTracksLocation2.getTime() + 222);
myTracksLocation2.setSpeed(102); myTracksLocation2.setSpeed(102);
@@ -352,7 +339,7 @@ public class ChartFragmentTest extends AndroidTestCase {
/** /**
* Helper method to test fillDataPoint. * Helper method to test fillDataPoint.
* *
* @param location location to fill * @param location location to fill
* @return data of this location * @return data of this location
*/ */
@@ -80,7 +80,7 @@ public class SettingTest extends ActivityInstrumentationTestCase2<TrackListActiv
EndToEndTestUtils.SOLO.goBack(); EndToEndTestUtils.SOLO.goBack();
// Change a setting of sharing. // Change a setting of sharing.
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_sharing)); EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_advanced));
assertTrue(EndToEndTestUtils.SOLO.waitForText( assertTrue(EndToEndTestUtils.SOLO.waitForText(
activityMyTracks.getString(R.string.settings_sharing_allow_access), 1, activityMyTracks.getString(R.string.settings_sharing_allow_access), 1,
EndToEndTestUtils.NORMAL_WAIT_TIME)); EndToEndTestUtils.NORMAL_WAIT_TIME));
@@ -121,7 +121,7 @@ public class SettingTest extends ActivityInstrumentationTestCase2<TrackListActiv
assertEquals(useMetric, displayCheckBoxs.get(0).isChecked()); assertEquals(useMetric, displayCheckBoxs.get(0).isChecked());
EndToEndTestUtils.SOLO.goBack(); EndToEndTestUtils.SOLO.goBack();
EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_sharing)); EndToEndTestUtils.SOLO.clickOnText(activityMyTracks.getString(R.string.settings_advanced));
EndToEndTestUtils.SOLO.waitForText(activityMyTracks EndToEndTestUtils.SOLO.waitForText(activityMyTracks
.getString(R.string.settings_sharing_allow_access)); .getString(R.string.settings_sharing_allow_access));
sharingCheckBoxs = EndToEndTestUtils.SOLO.getCurrentViews(CheckBox.class); sharingCheckBoxs = EndToEndTestUtils.SOLO.getCurrentViews(CheckBox.class);