Add a widget configuration screen

This commit is contained in:
Jimmy Shih
2012-10-05 11:26:57 -07:00
parent 5db20b48ca
commit 1983b63ce8
14 changed files with 593 additions and 200 deletions
+11 -19
View File
@@ -19,7 +19,6 @@ limitations under the License.
android:versionCode="56"
android:versionName="2.0.2"
package="com.google.android.maps.mytracks" >
<!-- Permission to initialize services -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Permissions to record locations -->
@@ -79,7 +78,6 @@ limitations under the License.
android:name="com.google.android.apps.mytracks.WRITE_TRACK_DATA"
android:permissionGroup="android.permission-group.LOCATION"
android:protectionLevel="dangerous" />
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="16" />
@@ -115,22 +113,19 @@ limitations under the License.
<uses-feature
android:name="android.hardware.touchscreen.multitouch"
android:required="false" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true" />
<application
android:backupAgent="com.google.android.apps.mytracks.io.backup.MyTracksBackupAgent"
android:icon="@drawable/my_tracks_icon"
android:hardwareAccelerated="true"
android:icon="@drawable/my_tracks_icon"
android:label="@string/my_tracks_app_name"
android:name="com.google.android.apps.mytracks.MyTracksApplication"
android:theme="@style/ThemeSelector" >
<!-- For data backup -->
<meta-data
android:name="com.google.android.backup.api_key"
@@ -142,15 +137,12 @@ limitations under the License.
<activity
android:label="@string/menu_help"
android:name="com.google.android.apps.mytracks.HelpActivity" />
<activity
android:name="com.google.android.apps.mytracks.ImportActivity" >
<activity android:name="com.google.android.apps.mytracks.ImportActivity" >
<intent-filter>
<action android:name="android.intent.action.ATTACH_DATA" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/gpx" />
<data android:mimeType="application/gpx+xml" />
<data android:mimeType="application/vnd.google-earth.gpx" />
@@ -158,8 +150,7 @@ limitations under the License.
<data android:scheme="file" />
</intent-filter>
</activity>
<activity
android:name="com.google.android.apps.mytracks.MarkerEditActivity" />
<activity android:name="com.google.android.apps.mytracks.MarkerEditActivity" />
<activity android:name="com.google.android.apps.mytracks.MarkerDetailActivity" />
<activity android:name="com.google.android.apps.mytracks.MarkerListActivity" >
<meta-data
@@ -172,7 +163,6 @@ limitations under the License.
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/search" />
@@ -181,15 +171,12 @@ limitations under the License.
android:label="@string/menu_sensor_state"
android:name="com.google.android.apps.mytracks.SensorStateActivity" />
<activity android:name="com.google.android.apps.mytracks.TrackDetailActivity" />
<activity
android:name="com.google.android.apps.mytracks.TrackEditActivity" />
<activity android:name="com.google.android.apps.mytracks.TrackEditActivity" />
<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.SearchListActivity" />
@@ -215,6 +202,13 @@ limitations under the License.
<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:label="@string/track_widget_config_title"
android:name="com.google.android.apps.mytracks.widgets.TrackWidgetConfigActivity" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<!-- Services -->
<service
android:exported="false"
@@ -259,8 +253,6 @@ limitations under the License.
android:authorities="com.google.android.maps.mytracks.search"
android:exported="false"
android:name="com.google.android.apps.mytracks.content.SearchEngineProvider" />
<uses-library android:name="com.google.android.maps" />
</application>
</manifest>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<Button
android:id="@+id/bottom_buttons_cancel"
android:layout_gravity="left"
android:text="@string/generic_cancel"
style="@style/BottomButton" />
<Button
android:id="@+id/bottom_buttons_add"
android:layout_gravity="right"
android:text="@string/generic_add"
style="@style/BottomButton" />
</merge>
+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<Button
android:id="@+id/bottom_buttons_add"
android:layout_gravity="left"
android:text="@string/generic_add"
style="@style/BottomButton" />
<Button
android:id="@+id/bottom_buttons_cancel"
android:layout_gravity="right"
android:text="@string/generic_cancel"
style="@style/BottomButton" />
</merge>
+1 -1
View File
@@ -52,7 +52,7 @@ limitations under the License.
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:singleLine="true"
style="@style/TextTiny" />
style="@style/TextMicro" />
</RelativeLayout>
<ImageButton
android:background="@android:color/transparent"
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="vertical" >
<ScrollView style="@style/ScrollView.WithBottomButtons" >
<TableLayout
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:padding="8dp" >
<TableRow style="@style/TrackWidgetConfigRow" >
<Spinner
android:id="@+id/track_widget_config_item1"
style="@style/TrackWidgetConfigSpinner" />
<LinearLayout style="@style/TrackWidgetConfigSpacer" />
<Spinner
android:id="@+id/track_widget_config_item3"
style="@style/TrackWidgetConfigSpinner" />
</TableRow>
<TableRow style="@style/TrackWidgetConfigRow" >
<Spinner
android:id="@+id/track_widget_config_item2"
style="@style/TrackWidgetConfigSpinner" />
<LinearLayout style="@style/TrackWidgetConfigSpacer" />
<Spinner
android:id="@+id/track_widget_config_item4"
style="@style/TrackWidgetConfigSpinner" />
</TableRow>
</TableLayout>
</ScrollView>
<LinearLayout style="@style/BottomButtonBar" >
<include layout="@layout/bottom_buttons" />
</LinearLayout>
</LinearLayout>
+100 -89
View File
@@ -20,106 +20,117 @@ limitations under the License.
android:layout_width="fill_parent"
android:padding="@dimen/widget_margin" >
<LinearLayout
android:clickable="true"
android:id="@+id/track_widget_statistics"
android:layout_alignParentTop="true"
android:layout_height="wrap_content"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="vertical"
android:padding="4dp" >
<LinearLayout style="@style/LinearLayoutHorizontal" >
<!-- average moving speed -->
<LinearLayout style="@style/TrackWidgetItemContainer" >
<TextView
android:id="@+id/track_widget_average_moving_speed_label"
style="@style/TrackWidgetLabel" />
<LinearLayout style="@style/TrackWidgetValueContainer" >
android:orientation="vertical" >
<LinearLayout
android:clickable="true"
android:gravity="center_vertical"
android:id="@+id/track_widget_statistics"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_width="fill_parent"
android:orientation="vertical"
android:padding="4dp" >
<LinearLayout style="@style/LinearLayoutHorizontal" >
<!-- item1 -->
<LinearLayout style="@style/TrackWidgetItemContainer" >
<TextView
android:id="@+id/track_widget_average_moving_speed_value"
style="@style/TrackWidgetValue" />
android:id="@+id/track_widget_item1_label"
style="@style/TrackWidgetLabel" />
<LinearLayout style="@style/TrackWidgetValueContainer" >
<TextView
android:id="@+id/track_widget_item1_value"
style="@style/TrackWidgetValue" />
<TextView
android:id="@+id/track_widget_item1_unit"
style="@style/TrackWidgetUnit" />
</LinearLayout>
</LinearLayout>
<!-- vertical separator -->
<LinearLayout style="@style/LinearLayoutVertifcal" >
<LinearLayout style="@style/TrackWidgetVerticalSpacer" />
<LinearLayout style="@style/TrackWidgetVerticalSeparator" />
</LinearLayout>
<!-- item3 -->
<LinearLayout style="@style/TrackWidgetItemContainer" >
<TextView
android:id="@+id/track_widget_average_moving_speed_unit"
style="@style/TrackWidgetUnit" />
android:id="@+id/track_widget_item3_label"
style="@style/TrackWidgetLabel" />
<LinearLayout style="@style/TrackWidgetValueContainer" >
<TextView
android:id="@+id/track_widget_item3_value"
style="@style/TrackWidgetValue" />
<TextView
android:id="@+id/track_widget_item3_unit"
style="@style/TrackWidgetUnit" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- vertical separator -->
<LinearLayout style="@style/LinearLayoutVertifcal" >
<LinearLayout style="@style/TrackWidgetVerticalSpacer" />
<LinearLayout style="@style/TrackWidgetVerticalSeparator" />
</LinearLayout>
<!-- moving time -->
<LinearLayout style="@style/TrackWidgetItemContainer" >
<TextView
android:text="@string/stats_moving_time"
style="@style/TrackWidgetLabel" />
<LinearLayout style="@style/TrackWidgetValueContainer" >
<!-- horizontal separator -->
<LinearLayout style="@style/TrackWidgetHorizontalSeparator" />
<LinearLayout style="@style/LinearLayoutHorizontal" >
<!-- item2 -->
<LinearLayout style="@style/TrackWidgetItemContainer" >
<TextView
android:id="@+id/track_widget_moving_time_value"
style="@style/TrackWidgetValue" />
android:id="@+id/track_widget_item2_label"
style="@style/TrackWidgetLabel" />
<LinearLayout style="@style/TrackWidgetValueContainer" >
<TextView
android:id="@+id/track_widget_item2_value"
style="@style/TrackWidgetValue" />
<TextView
android:id="@+id/track_widget_item2_unit"
style="@style/TrackWidgetUnit" />
</LinearLayout>
</LinearLayout>
<!-- vertical separator -->
<LinearLayout style="@style/LinearLayoutVertifcal" >
<LinearLayout style="@style/TrackWidgetVerticalSeparator" />
<LinearLayout style="@style/TrackWidgetVerticalSpacer" />
</LinearLayout>
<!-- item4 -->
<LinearLayout style="@style/TrackWidgetItemContainer" >
<TextView
android:id="@+id/track_widget_item4_label"
style="@style/TrackWidgetLabel" />
<LinearLayout style="@style/TrackWidgetValueContainer" >
<TextView
android:id="@+id/track_widget_item4_value"
style="@style/TrackWidgetValue" />
<TextView
android:id="@+id/track_widget_item4_unit"
style="@style/TrackWidgetUnit" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- horizontal separator -->
<LinearLayout style="@style/TrackWidgetHorizontalSeparator" />
<LinearLayout style="@style/LinearLayoutHorizontal" >
<!-- average speed -->
<LinearLayout style="@style/TrackWidgetItemContainer" >
<TextView
android:id="@+id/track_widget_average_speed_label"
style="@style/TrackWidgetLabel" />
<LinearLayout style="@style/TrackWidgetValueContainer" >
<TextView
android:id="@+id/track_widget_average_speed_value"
style="@style/TrackWidgetValue" />
<TextView
android:id="@+id/track_widget_average_speed_unit"
style="@style/TrackWidgetUnit" />
</LinearLayout>
</LinearLayout>
<!-- vertical separator -->
<LinearLayout style="@style/LinearLayoutVertifcal" >
<LinearLayout style="@style/TrackWidgetVerticalSeparator" />
<LinearLayout style="@style/TrackWidgetVerticalSpacer" />
</LinearLayout>
<!-- total distance -->
<LinearLayout style="@style/TrackWidgetItemContainer" >
<TextView
android:text="@string/stats_total_distance"
style="@style/TrackWidgetLabel" />
<LinearLayout style="@style/TrackWidgetValueContainer" >
<TextView
android:id="@+id/track_widget_total_distance_value"
style="@style/TrackWidgetValue" />
<TextView
android:id="@+id/track_widget_total_distance_unit"
style="@style/TrackWidgetUnit" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:gravity="center_vertical"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_width="fill_parent"
android:orientation="horizontal"
android:paddingBottom="4dp"
android:paddingTop="4dp" >
<LinearLayout style="@style/TrackWidgetVerticalSpacer" />
<ImageButton
android:id="@+id/track_widget_record_button"
style="@style/TrackWidgetRecordButton" />
<TextView
android:id="@+id/track_widget_record_status"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:layout_weight="4"
android:layout_width="0dp"
android:singleLine="true"
style="@style/TextSmall" />
<ImageButton
android:id="@+id/track_widget_stop_button"
style="@style/TrackWidgetStopButton" />
<LinearLayout style="@style/TrackWidgetVerticalSpacer" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_below="@id/track_widget_statistics"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="horizontal"
android:paddingBottom="4dp"
android:paddingTop="4dp" >
<LinearLayout style="@style/TrackWidgetVerticalSpacer" />
<ImageButton
android:id="@+id/track_widget_record_button"
style="@style/TrackWidgetRecordButton" />
<TextView
android:id="@+id/track_widget_record_status"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:layout_weight="4"
android:layout_width="0dp"
android:singleLine="true"
style="@style/TextSmall" />
<ImageButton
android:id="@+id/track_widget_stop_button"
style="@style/TrackWidgetStopButton" />
<LinearLayout style="@style/TrackWidgetVerticalSpacer" />
</LinearLayout>
<ImageView style="@style/TrackWidgetLogo" />
</RelativeLayout>
+10 -5
View File
@@ -45,13 +45,17 @@ limitations under the License.
android:layout_weight="1"
android:layout_width="fill_parent"
android:orientation="vertical" >
<!-- item1 -->
<TextView
android:text="@string/stats_moving_time"
android:id="@+id/track_widget_item1_label"
style="@style/TrackWidgetLabel" />
<LinearLayout style="@style/TrackWidgetValueContainer" >
<TextView
android:id="@+id/track_widget_moving_time_value"
android:id="@+id/track_widget_item1_value"
style="@style/TrackWidgetValue" />
<TextView
android:id="@+id/track_widget_item1_unit"
style="@style/TrackWidgetUnit" />
</LinearLayout>
</LinearLayout>
<LinearLayout style="@style/TrackWidgetHorizontalSeparator" />
@@ -60,15 +64,16 @@ limitations under the License.
android:layout_weight="1"
android:layout_width="fill_parent"
android:orientation="vertical" >
<!-- item2 -->
<TextView
android:text="@string/stats_total_distance"
android:id="@+id/track_widget_item2_label"
style="@style/TrackWidgetLabel" />
<LinearLayout style="@style/TrackWidgetValueContainer" >
<TextView
android:id="@+id/track_widget_total_distance_value"
android:id="@+id/track_widget_item2_value"
style="@style/TrackWidgetValue" />
<TextView
android:id="@+id/track_widget_total_distance_unit"
android:id="@+id/track_widget_item2_unit"
style="@style/TrackWidgetUnit" />
</LinearLayout>
</LinearLayout>
+5 -1
View File
@@ -54,8 +54,12 @@ limitations under the License.
<string name="track_color_mode_slow_key">trackColorModeSlow</string>
<string name="track_color_mode_key">trackColorMode</string>
<string name="track_name_key">trackName</string>
<string name="track_widget_item1">trackWidgetItem1</string>
<string name="track_widget_item2">trackWidgetItem2</string>
<string name="track_widget_item3">trackWidgetItem3</string>
<string name="track_widget_item4">trackWidgetItem4</string>
<string name="voice_frequency_key">voiceFrequency</string>
<!-- Keys for persistend preferences. But they should not get backed up or restored. -->
<string name="auto_resume_track_current_retry_key">autoResumeTrackCurrentRetry</string>
<string name="recording_track_id_key">recordingTrackId</string>
+6
View File
@@ -2293,6 +2293,12 @@ limitations under the License.
Recording your track&#8230;
</string>
<!-- Track Widget -->
<string name="track_widget_config_title"
translation_description="Title of the page to configure the My Tracks widget items.">
Configure Widget Items
</string>
<!-- Unit -->
<string name="unit_feet"
translation_description="Abbreviation for feet. E.g., '2 ft'.">
+31 -7
View File
@@ -192,11 +192,11 @@ limitations under the License.
<item name="android:layout_width">wrap_content</item>
<item name="android:textSize">14sp</item>
</style>
<!-- The style for tiny size text -->
<style name="TextTiny">
<!-- The style for micro size text -->
<style name="TextMicro">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:textSize">10sp</item>
<item name="android:textSize">12sp</item>
</style>
<!-- Theme selector -->
<style name="ThemeSelector" parent="android:Theme" />
@@ -212,6 +212,26 @@ limitations under the License.
<item name="android:layout_gravity">center_vertical</item>
<item name="android:scaleType">fitXY</item>
</style>
<!-- The style for the track widget config row -->
<style name="TrackWidgetConfigRow">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:paddingTop">16dp</item>
<item name="android:paddingBottom">16dp</item>
</style>
<!-- The style for the track widget config spacer -->
<style name="TrackWidgetConfigSpacer">
<item name="android:layout_height">fill_parent</item>
<item name="android:layout_weight">2</item>
<item name="android:layout_width">0dp</item>
</style>
<!-- The style for the track widget config spiner -->
<style name="TrackWidgetConfigSpinner">
<item name="android:gravity">left</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">9</item>
<item name="android:layout_width">0dp</item>
</style>
<!-- The style for the track widget horizontal separator -->
<style name="TrackWidgetHorizontalSeparator">
<item name="android:background">@color/track_widget_line</item>
@@ -229,20 +249,22 @@ limitations under the License.
<item name="android:paddingTop">2dp</item>
</style>
<!-- The style for the track widget label -->
<style name="TrackWidgetLabel" parent="@style/TextSmall">
<style name="TrackWidgetLabel">
<item name="android:layout_gravity">center_horizontal</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:singleLine">true</item>
<item name="android:textAllCaps">true</item>
<item name="android:textColor">@color/orange</item>
<item name="android:textSize">10dp</item>
<item name="android:textStyle">bold</item>
</style>
<style name="TrackWidgetLogo">
<item name="android:contentDescription">@string/my_tracks_app_name</item>
<item name="android:layout_alignParentRight">true</item>
<item name="android:layout_alignParentTop">true</item>
<item name="android:layout_height">24dp</item>
<item name="android:layout_width">20dp</item>
<item name="android:layout_width">24dp</item>
<item name="android:padding">4dp</item>
<item name="android:scaleType">fitXY</item>
<item name="android:src">@drawable/my_tracks_icon</item>
@@ -262,15 +284,16 @@ limitations under the License.
<item name="android:src">@drawable/btn_stop_0</item>
</style>
<!-- The style for the track widget unit -->
<style name="TrackWidgetUnit" parent="@style/TextSmall">
<style name="TrackWidgetUnit">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1</item>
<item name="android:layout_width">0dp</item>
<item name="android:paddingLeft">4dp</item>
<item name="android:singleLine">true</item>
<item name="android:textSize">10dp</item>
</style>
<!-- The style for the track widget value -->
<style name="TrackWidgetValue" parent="@style/TextSmall">
<style name="TrackWidgetValue" parent="@style/TextMedium">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">2</item>
<item name="android:layout_width">0dp</item>
@@ -282,6 +305,7 @@ limitations under the License.
<style name="TrackWidgetValueContainer">
<item name="android:layout_gravity">center_horizontal</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginTop">-4dp</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:orientation">horizontal</item>
</style>
+1
View File
@@ -15,6 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:configure="com.google.android.apps.mytracks.widgets.TrackWidgetConfigActivity"
android:initialLayout="@layout/track_widget_large"
android:minHeight="110dp"
android:minResizeHeight="40dp"
@@ -91,6 +91,11 @@ public class PreferencesUtils {
public static final String TRACK_NAME_DEFAULT = "LOCATION";
public static final int TRACK_WIDGET_ITEM1_DEFAULT = 3; // moving time
public static final int TRACK_WIDGET_ITEM2_DEFAULT = 0; // distance
public static final int TRACK_WIDGET_ITEM3_DEFAULT = 1; // total time
public static final int TRACK_WIDGET_ITEM4_DEFAULT = 2; // average speed
public static final int VOICE_FREQUENCY_DEFAULT = 0;
private PreferencesUtils() {}
@@ -0,0 +1,137 @@
/*
* 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.widgets;
import com.google.android.apps.mytracks.util.PreferencesUtils;
import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import java.util.ArrayList;
import java.util.List;
/**
* Activity to configure the track widget.
*
* @author Jimmy Shih
*/
public class TrackWidgetConfigActivity extends Activity {
private int appWidgetId;
private Spinner item1;
private Spinner item2;
private Spinner item3;
private Spinner item4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
* Set the result to CANCELED. This will cause the widget host to cancel out
* of the widget placement if they press the back button.
*/
setResult(RESULT_CANCELED);
setContentView(R.layout.track_widget_config);
item1 = (Spinner) findViewById(R.id.track_widget_config_item1);
item2 = (Spinner) findViewById(R.id.track_widget_config_item2);
item3 = (Spinner) findViewById(R.id.track_widget_config_item3);
item4 = (Spinner) findViewById(R.id.track_widget_config_item4);
boolean reportSpeed = PreferencesUtils.getBoolean(
this, R.string.report_speed_key, PreferencesUtils.REPORT_SPEED_DEFAULT);
List<CharSequence> list = new ArrayList<CharSequence>();
addItem(list, R.string.stats_total_distance);
addItem(list, R.string.stats_total_time);
addItem(list, reportSpeed ? R.string.stats_average_speed : R.string.stats_average_pace);
addItem(list, R.string.stats_moving_time);
addItem(list,
reportSpeed ? R.string.stats_average_moving_speed : R.string.stats_average_moving_pace);
configSpinner(item1, list, PreferencesUtils.getInt(
this, R.string.track_widget_item1, PreferencesUtils.TRACK_WIDGET_ITEM1_DEFAULT));
configSpinner(item2, list, PreferencesUtils.getInt(
this, R.string.track_widget_item2, PreferencesUtils.TRACK_WIDGET_ITEM2_DEFAULT));
configSpinner(item3, list, PreferencesUtils.getInt(
this, R.string.track_widget_item3, PreferencesUtils.TRACK_WIDGET_ITEM3_DEFAULT));
configSpinner(item4, list, PreferencesUtils.getInt(
this, R.string.track_widget_item4, PreferencesUtils.TRACK_WIDGET_ITEM4_DEFAULT));
findViewById(R.id.bottom_buttons_add).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Push widget update to surface with newly set prefix
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(
TrackWidgetConfigActivity.this);
TrackWidgetProvider.updateAppWidget(
TrackWidgetConfigActivity.this, appWidgetManager, appWidgetId);
PreferencesUtils.setInt(TrackWidgetConfigActivity.this, R.string.track_widget_item1,
item1.getSelectedItemPosition());
PreferencesUtils.setInt(TrackWidgetConfigActivity.this, R.string.track_widget_item2,
item2.getSelectedItemPosition());
PreferencesUtils.setInt(TrackWidgetConfigActivity.this, R.string.track_widget_item3,
item3.getSelectedItemPosition());
PreferencesUtils.setInt(TrackWidgetConfigActivity.this, R.string.track_widget_item4,
item4.getSelectedItemPosition());
// Make sure we pass back the original appWidgetId
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
});
findViewById(R.id.bottom_buttons_cancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
// Find the app widget id from the intent.
Intent intent = getIntent();
Bundle extras = intent.getExtras();
appWidgetId = extras != null ? extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)
: AppWidgetManager.INVALID_APPWIDGET_ID;
// If they gave us an intent without the widget id, just bail.
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
}
}
private void addItem(List<CharSequence> list, int id) {
list.add(getString(id).toUpperCase());
}
private void configSpinner(Spinner spinner, List<CharSequence> list, int position) {
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<CharSequence>(
this, android.R.layout.simple_spinner_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setSelection(position);
}
}
@@ -37,6 +37,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.TaskStackBuilder;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.RemoteViews;
/**
@@ -57,8 +58,7 @@ public class TrackWidgetProvider extends AppWidgetProvider {
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
|| context.getString(R.string.track_paused_broadcast_action).equals(action)
if (context.getString(R.string.track_paused_broadcast_action).equals(action)
|| context.getString(R.string.track_resumed_broadcast_action).equals(action)
|| context.getString(R.string.track_started_broadcast_action).equals(action)
|| context.getString(R.string.track_stopped_broadcast_action).equals(action)
@@ -69,7 +69,8 @@ public class TrackWidgetProvider extends AppWidgetProvider {
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(
new ComponentName(context, TrackWidgetProvider.class));
for (int appWidgetId : appWidgetIds) {
RemoteViews remoteViews = getRemoteViews(context, trackId, useLargeSize.get(appWidgetId));
RemoteViews remoteViews = getRemoteViews(
context, trackId, useLargeSize.get(appWidgetId, true));
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
@@ -87,13 +88,26 @@ public class TrackWidgetProvider extends AppWidgetProvider {
}
/**
* Updates the widget.
* Updates an app widget.
*
* @param context the context
* @param appWidgetManager the app widget manager
* @param appWidgetId the app widget id
*/
public static void updateAppWidget(
Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
RemoteViews remoteViews = getRemoteViews(context, -1L, useLargeSize.get(appWidgetId, true));
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
/**
* Gets the remote views.
*
* @param context the context
* @param trackId the track id
* @param large true to use the large layout
*/
private RemoteViews getRemoteViews(Context context, long trackId, boolean large) {
private static RemoteViews getRemoteViews(Context context, long trackId, boolean large) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
large ? R.layout.track_widget_large : R.layout.track_widget_small);
@@ -104,6 +118,12 @@ public class TrackWidgetProvider extends AppWidgetProvider {
R.string.recording_track_paused_key, PreferencesUtils.RECORDING_TRACK_PAUSED_DEFAULT);
boolean metricUnits = PreferencesUtils.getBoolean(
context, R.string.metric_units_key, PreferencesUtils.METRIC_UNITS_DEFAULT);
boolean reportSpeed = PreferencesUtils.getBoolean(
context, R.string.report_speed_key, PreferencesUtils.REPORT_SPEED_DEFAULT);
int item1 = PreferencesUtils.getInt(
context, R.string.track_widget_item1, PreferencesUtils.TRACK_WIDGET_ITEM1_DEFAULT);
int item2 = PreferencesUtils.getInt(
context, R.string.track_widget_item2, PreferencesUtils.TRACK_WIDGET_ITEM2_DEFAULT);
// Get track and trip statistics
MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context);
@@ -115,20 +135,66 @@ public class TrackWidgetProvider extends AppWidgetProvider {
TripStatistics tripStatistics = track == null ? null : track.getTripStatistics();
updateStatisticsContainer(context, remoteViews, track);
updateMovingTime(context, remoteViews, tripStatistics);
updateTotalDistance(context, remoteViews, tripStatistics, metricUnits);
setItem(context, remoteViews, R.id.track_widget_item1_label, R.id.track_widget_item1_value,
R.id.track_widget_item1_unit, item1, tripStatistics, metricUnits, reportSpeed);
setItem(context, remoteViews, R.id.track_widget_item2_label, R.id.track_widget_item2_value,
R.id.track_widget_item2_unit, item2, tripStatistics, metricUnits, reportSpeed);
updateRecordButton(context, remoteViews, isRecording, recordingTrackPaused);
updateStopButton(context, remoteViews, isRecording);
if (large) {
boolean reportSpeed = PreferencesUtils.getBoolean(
context, R.string.report_speed_key, PreferencesUtils.REPORT_SPEED_DEFAULT);
updateAverageMovingSpeed(context, remoteViews, tripStatistics, metricUnits, reportSpeed);
updateAverageSpeed(context, remoteViews, tripStatistics, metricUnits, reportSpeed);
int item3 = PreferencesUtils.getInt(
context, R.string.track_widget_item3, PreferencesUtils.TRACK_WIDGET_ITEM3_DEFAULT);
int item4 = PreferencesUtils.getInt(
context, R.string.track_widget_item4, PreferencesUtils.TRACK_WIDGET_ITEM4_DEFAULT);
setItem(context, remoteViews, R.id.track_widget_item3_label, R.id.track_widget_item3_value,
R.id.track_widget_item3_unit, item3, tripStatistics, metricUnits, reportSpeed);
setItem(context, remoteViews, R.id.track_widget_item4_label, R.id.track_widget_item4_value,
R.id.track_widget_item4_unit, item4, tripStatistics, metricUnits, reportSpeed);
updateRecordStatus(context, remoteViews, isRecording, recordingTrackPaused);
}
return remoteViews;
}
/**
* Sets a widget item.
*
* @param context the context
* @param remoteViews the remote view
* @param labelId the label id
* @param valueId the value id
* @param unitId the unit id
* @param itemValue the item value
* @param tripStatistics the trip statistics
* @param metricUnits true to use metric units
* @param reportSpeed try to report speed
*/
private static void setItem(Context context, RemoteViews remoteViews, int labelId, int valueId,
int unitId, int itemValue, TripStatistics tripStatistics, boolean metricUnits,
boolean reportSpeed) {
switch (itemValue) {
case 1:
updateTotalTime(context, remoteViews, labelId, valueId, unitId, tripStatistics);
break;
case 2:
updateAverageSpeed(context, remoteViews, labelId, valueId, unitId, tripStatistics,
metricUnits, reportSpeed);
break;
case 3:
updateMovingTime(context, remoteViews, labelId, valueId, unitId, tripStatistics);
break;
case 4:
updateAverageMovingSpeed(context, remoteViews, labelId, valueId, unitId, tripStatistics,
metricUnits, reportSpeed);
break;
case 0:
default:
updateTotalDistance(
context, remoteViews, labelId, valueId, unitId, tripStatistics, metricUnits);
break;
}
}
/**
* Updates the statistics container.
*
@@ -136,7 +202,8 @@ public class TrackWidgetProvider extends AppWidgetProvider {
* @param remoteViews the remote views
* @param track the track
*/
private void updateStatisticsContainer(Context context, RemoteViews remoteViews, Track track) {
private static void updateStatisticsContainer(
Context context, RemoteViews remoteViews, Track track) {
Intent intent;
if (track != null) {
intent = IntentUtils.newIntent(context, TrackDetailActivity.class)
@@ -150,34 +217,112 @@ public class TrackWidgetProvider extends AppWidgetProvider {
remoteViews.setOnClickPendingIntent(R.id.track_widget_statistics, pendingIntent);
}
/**
* Updates moving time.
*
* @param context the context
* @param remoteViews the remote views
* @param tripStatistics the trip statistics
*/
private void updateMovingTime(
Context context, RemoteViews remoteViews, TripStatistics tripStatistics) {
String movingTimeValue = tripStatistics == null ? context.getString(R.string.value_unknown)
: StringUtils.formatElapsedTime(tripStatistics.getMovingTime());
remoteViews.setTextViewText(R.id.track_widget_moving_time_value, movingTimeValue);
}
/**
* Updates total distance.
*
* @param context the context
* @param remoteViews the remote views
* @param labelId the label id
* @param valueId the value id
* @param unitId the unit id
* @param tripStatistics the trip statistics
* @param metricUnits true to use metric units
*/
private void updateTotalDistance(Context context, RemoteViews remoteViews,
TripStatistics tripStatistics, boolean metricUnits) {
double distance = tripStatistics == null ? Double.NaN : tripStatistics.getTotalDistance();
String[] distanceParts = StringUtils.getDistanceParts(context, distance, metricUnits);
remoteViews.setTextViewText(R.id.track_widget_total_distance_value, distanceParts[0]);
remoteViews.setTextViewText(R.id.track_widget_total_distance_unit, distanceParts[1]);
private static void updateTotalDistance(Context context, RemoteViews remoteViews, int labelId,
int valueId, int unitId, TripStatistics tripStatistics, boolean metricUnits) {
double totalDistance = tripStatistics == null ? Double.NaN : tripStatistics.getTotalDistance();
String[] totalDistanceParts = StringUtils.getDistanceParts(context, totalDistance, metricUnits);
remoteViews.setTextViewText(labelId, context.getString(R.string.stats_total_distance));
remoteViews.setTextViewText(valueId, totalDistanceParts[0]);
remoteViews.setTextViewText(unitId, totalDistanceParts[1]);
}
/**
* Updates total time.
*
* @param context the context
* @param remoteViews the remote views
* @param labelId the label id
* @param valueId the value id
* @param unitId the unit id
* @param tripStatistics the trip statistics
*/
private static void updateTotalTime(Context context, RemoteViews remoteViews, int labelId,
int valueId, int unitId, TripStatistics tripStatistics) {
String totalTime = tripStatistics == null ? context.getString(R.string.value_unknown)
: StringUtils.formatElapsedTime(tripStatistics.getTotalTime());
remoteViews.setTextViewText(labelId, context.getString(R.string.stats_total_time));
remoteViews.setTextViewText(valueId, totalTime);
remoteViews.setViewVisibility(unitId, View.GONE);
}
/**
* Updates average speed.
*
* @param context the context
* @param remoteViews the remote views
* @param labelId the label id
* @param valueId the value id
* @param unitId the unit id
* @param tripStatistics the trip statistics
* @param metricUnits true to use metric units
* @param reportSpeed true to report speed
*/
private static void updateAverageSpeed(Context context, RemoteViews remoteViews, int labelId,
int valueId, int unitId, TripStatistics tripStatistics, boolean metricUnits,
boolean reportSpeed) {
String averageSpeedLabel = context.getString(
reportSpeed ? R.string.stats_average_speed : R.string.stats_average_pace);
remoteViews.setTextViewText(labelId, averageSpeedLabel);
Double speed = tripStatistics == null ? Double.NaN : tripStatistics.getAverageSpeed();
String[] speedParts = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
remoteViews.setTextViewText(valueId, speedParts[0]);
remoteViews.setTextViewText(unitId, speedParts[1]);
}
/**
* Updates moving time.
*
* @param context the context
* @param remoteViews the remote views
* @param labelId the label id
* @param valueId the value id
* @param unitId the unit id
* @param tripStatistics the trip statistics
*/
private static void updateMovingTime(Context context, RemoteViews remoteViews, int labelId,
int valueId, int unitId, TripStatistics tripStatistics) {
String movingTime = tripStatistics == null ? context.getString(R.string.value_unknown)
: StringUtils.formatElapsedTime(tripStatistics.getMovingTime());
remoteViews.setTextViewText(labelId, context.getString(R.string.stats_moving_time));
remoteViews.setTextViewText(valueId, movingTime);
remoteViews.setViewVisibility(unitId, View.GONE);
}
/**
* Updates average moving speed.
*
* @param context the context
* @param remoteViews the remote views
* @param labelId the label id
* @param valueId the value id
* @param unitId the unit id
* @param tripStatistics the trip statistics
* @param metricUnits true to use metric units
* @param reportSpeed true to report speed
*/
private static void updateAverageMovingSpeed(Context context, RemoteViews remoteViews,
int labelId, int valueId, int unitId, TripStatistics tripStatistics, boolean metricUnits,
boolean reportSpeed) {
String averageMovingSpeedLabel = context.getString(
reportSpeed ? R.string.stats_average_moving_speed : R.string.stats_average_moving_pace);
remoteViews.setTextViewText(labelId, averageMovingSpeedLabel);
Double speed = tripStatistics == null ? Double.NaN : tripStatistics.getAverageMovingSpeed();
String[] speedParts = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
remoteViews.setTextViewText(valueId, speedParts[0]);
remoteViews.setTextViewText(unitId, speedParts[1]);
}
/**
@@ -188,7 +333,7 @@ public class TrackWidgetProvider extends AppWidgetProvider {
* @param isRecording true if recording
* @param recordingTrackPaused true if recording track is paused
*/
private void updateRecordButton(
private static void updateRecordButton(
Context context, RemoteViews remoteViews, boolean isRecording, boolean recordingTrackPaused) {
remoteViews.setImageViewResource(R.id.track_widget_record_button,
isRecording && !recordingTrackPaused ? R.drawable.btn_pause : R.drawable.btn_record);
@@ -213,7 +358,8 @@ public class TrackWidgetProvider extends AppWidgetProvider {
* @param remoteViews the remote views
* @param isRecording true if recording
*/
private void updateStopButton(Context context, RemoteViews remoteViews, boolean isRecording) {
private static void updateStopButton(
Context context, RemoteViews remoteViews, boolean isRecording) {
remoteViews.setImageViewResource(
R.id.track_widget_stop_button, isRecording ? R.drawable.btn_stop_1 : R.drawable.btn_stop_0);
remoteViews.setBoolean(R.id.track_widget_stop_button, "setEnabled", isRecording);
@@ -226,49 +372,6 @@ public class TrackWidgetProvider extends AppWidgetProvider {
}
}
/**
* Updates average moving speed.
*
* @param context the context
* @param remoteViews the remote views
* @param tripStatistics the trip statistics
* @param metricUnits true to use metric units
* @param reportSpeed true to report speed
*/
private void updateAverageMovingSpeed(Context context, RemoteViews remoteViews,
TripStatistics tripStatistics, boolean metricUnits, boolean reportSpeed) {
String averageMovingSpeedLabel = context.getString(
reportSpeed ? R.string.stats_average_moving_speed : R.string.stats_average_moving_pace);
remoteViews.setTextViewText(
R.id.track_widget_average_moving_speed_label, averageMovingSpeedLabel);
Double speed = tripStatistics == null ? Double.NaN : tripStatistics.getAverageMovingSpeed();
String[] speedParts = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
remoteViews.setTextViewText(R.id.track_widget_average_moving_speed_value, speedParts[0]);
remoteViews.setTextViewText(R.id.track_widget_average_moving_speed_unit, speedParts[1]);
}
/**
* Updates average speed.
*
* @param context the context
* @param remoteViews the remote views
* @param tripStatistics the trip statistics
* @param metricUnits true to use metric units
* @param reportSpeed true to report speed
*/
private void updateAverageSpeed(Context context, RemoteViews remoteViews,
TripStatistics tripStatistics, boolean metricUnits, boolean reportSpeed) {
String averageSpeedLabel = context.getString(
reportSpeed ? R.string.stats_average_speed : R.string.stats_average_pace);
remoteViews.setTextViewText(R.id.track_widget_average_speed_label, averageSpeedLabel);
Double speed = tripStatistics == null ? Double.NaN : tripStatistics.getAverageSpeed();
String[] speedParts = StringUtils.getSpeedParts(context, speed, metricUnits, reportSpeed);
remoteViews.setTextViewText(R.id.track_widget_average_speed_value, speedParts[0]);
remoteViews.setTextViewText(R.id.track_widget_average_speed_unit, speedParts[1]);
}
/**
* Updates recording status.
*
@@ -277,7 +380,7 @@ public class TrackWidgetProvider extends AppWidgetProvider {
* @param isRecording true if recording
* @param recordingTrackPaused true if recording track is paused
*/
private void updateRecordStatus(
private static void updateRecordStatus(
Context context, RemoteViews remoteViews, boolean isRecording, boolean recordingTrackPaused) {
String status;
int colorId;