forked from upstream-mirrors/OpenTracks
merge heads
This commit is contained in:
@@ -34,6 +34,7 @@ limitations under the License.
|
|||||||
style="@style/ListEmptyTextView" >
|
style="@style/ListEmptyTextView" >
|
||||||
</TextView>
|
</TextView>
|
||||||
<ImageButton
|
<ImageButton
|
||||||
|
android:background="@color/transparent"
|
||||||
android:contentDescription="@string/menu_record_track"
|
android:contentDescription="@string/menu_record_track"
|
||||||
android:id="@+id/track_list_record_button"
|
android:id="@+id/track_list_record_button"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|||||||
@@ -14,71 +14,72 @@ 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.
|
||||||
-->
|
-->
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:background="@drawable/app_widget_background"
|
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:paddingBottom="5dp"
|
android:padding="@dimen/widget_margin" >
|
||||||
android:paddingLeft="10dp"
|
|
||||||
android:paddingRight="10dp"
|
|
||||||
android:paddingTop="5dp" >
|
|
||||||
<ImageButton
|
|
||||||
android:background="@android:color/transparent"
|
|
||||||
android:contentDescription="@string/my_tracks_app_name"
|
|
||||||
android:id="@+id/appwidget_button"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:paddingLeft="10dp"
|
|
||||||
android:paddingRight="10dp"
|
|
||||||
android:src="@drawable/app_widget_button_disabled" />
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:clickable="true"
|
android:background="@drawable/app_widget_background"
|
||||||
android:id="@+id/appwidget_track_statistics"
|
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:layout_weight="1"
|
android:layout_width="fill_parent"
|
||||||
android:layout_width="0dp"
|
android:orientation="horizontal" >
|
||||||
android:orientation="vertical"
|
<ImageButton
|
||||||
android:paddingLeft="16dp" >
|
android:background="@android:color/transparent"
|
||||||
|
android:contentDescription="@string/my_tracks_app_name"
|
||||||
|
android:id="@+id/track_widget_button"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:src="@drawable/app_widget_button_disabled" />
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_height="wrap_content"
|
android:clickable="true"
|
||||||
android:layout_width="fill_parent"
|
android:id="@+id/track_widget_statistics"
|
||||||
android:orientation="horizontal" >
|
android:layout_height="fill_parent"
|
||||||
<TextView
|
android:layout_weight="1"
|
||||||
android:id="@+id/appwidget_distance_text"
|
android:layout_width="0dp"
|
||||||
style="@style/TrackWidgetValue" />
|
android:orientation="vertical"
|
||||||
<TextView
|
android:paddingLeft="8dp" >
|
||||||
android:text="@string/stats_total_distance"
|
<LinearLayout
|
||||||
style="@style/TextSmall" />
|
android:layout_height="wrap_content"
|
||||||
</LinearLayout>
|
android:layout_width="fill_parent"
|
||||||
<LinearLayout
|
android:orientation="horizontal" >
|
||||||
android:background="@color/appwidget_hr"
|
<TextView
|
||||||
android:layout_height="1dp"
|
android:id="@+id/track_widget_distance_value"
|
||||||
android:layout_width="fill_parent" />
|
style="@style/TrackWidgetValue" />
|
||||||
<LinearLayout
|
<TextView
|
||||||
android:layout_height="wrap_content"
|
android:text="@string/stats_total_distance"
|
||||||
android:layout_width="fill_parent"
|
style="@style/TrackWidgetLabel" />
|
||||||
android:orientation="horizontal" >
|
</LinearLayout>
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/appwidget_time_text"
|
android:background="@color/track_widget_line"
|
||||||
style="@style/TrackWidgetValue" />
|
android:layout_height="1dp"
|
||||||
<TextView
|
android:layout_width="fill_parent" />
|
||||||
android:text="@string/stats_moving_time"
|
<LinearLayout
|
||||||
style="@style/TextSmall" />
|
android:layout_height="wrap_content"
|
||||||
</LinearLayout>
|
android:layout_width="fill_parent"
|
||||||
<LinearLayout
|
android:orientation="horizontal" >
|
||||||
android:background="@color/appwidget_hr"
|
<TextView
|
||||||
android:layout_height="1dp"
|
android:id="@+id/track_widget_time_value"
|
||||||
android:layout_width="fill_parent" />
|
style="@style/TrackWidgetValue" />
|
||||||
<LinearLayout
|
<TextView
|
||||||
android:layout_height="wrap_content"
|
android:id="@+id/track_widget_time_label"
|
||||||
android:layout_width="fill_parent"
|
style="@style/TrackWidgetLabel" />
|
||||||
android:orientation="horizontal" >
|
</LinearLayout>
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/appwidget_speed_text"
|
android:background="@color/track_widget_line"
|
||||||
style="@style/TrackWidgetValue" />
|
android:layout_height="1dp"
|
||||||
<TextView
|
android:layout_width="fill_parent" />
|
||||||
android:text="@string/stats_speed"
|
<LinearLayout
|
||||||
style="@style/TextSmall" />
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/track_widget_speed_value"
|
||||||
|
style="@style/TrackWidgetValue" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/track_widget_speed_label"
|
||||||
|
style="@style/TrackWidgetLabel" />
|
||||||
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</FrameLayout>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?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.
|
||||||
|
-->
|
||||||
|
<resources>
|
||||||
|
<dimen name="widget_margin">0dp</dimen>
|
||||||
|
</resources>
|
||||||
@@ -19,46 +19,45 @@ limitations under the License.
|
|||||||
<color name="blue">#FF0000FF</color>
|
<color name="blue">#FF0000FF</color>
|
||||||
<color name="gray">#FFAAAAAA</color>
|
<color name="gray">#FFAAAAAA</color>
|
||||||
<color name="red">#FFFF0000</color>
|
<color name="red">#FFFF0000</color>
|
||||||
|
<color name="transparent">#00000000</color>
|
||||||
<color name="white">#FFFFFFFF</color>
|
<color name="white">#FFFFFFFF</color>
|
||||||
|
|
||||||
<!-- holo_orange_dark -->
|
<!-- holo_orange_dark -->
|
||||||
<color name="warning_background">#FFFF8800</color>
|
<color name="warning_background">#FFFF8800</color>
|
||||||
|
|
||||||
<!-- Chart colors by series. -->
|
<!-- elevation chart colors, green and transparent green -->
|
||||||
<!-- Green and a transparent green -->
|
|
||||||
<color name="elevation_border">#FF339933</color>
|
<color name="elevation_border">#FF339933</color>
|
||||||
<color name="elevation_fill">#40B3CFB3</color>
|
<color name="elevation_fill">#40B3CFB3</color>
|
||||||
|
|
||||||
<!-- Blue and a transparent blue -->
|
<!-- speed chart colors, blue and transparent blue -->
|
||||||
<color name="speed_border">#FF0066FF</color>
|
<color name="speed_border">#FF0066FF</color>
|
||||||
<color name="speed_fill">#40C8E0FF</color>
|
<color name="speed_fill">#40C8E0FF</color>
|
||||||
|
|
||||||
<!-- Blue and a transparent blue -->
|
<!-- pace chart colors, blue and transparent blue -->
|
||||||
<color name="pace_border">#FF0066FF</color>
|
<color name="pace_border">#FF0066FF</color>
|
||||||
<color name="pace_fill">#40C8E0FF</color>
|
<color name="pace_fill">#40C8E0FF</color>
|
||||||
|
|
||||||
<!-- Red and a transparent red -->
|
|
||||||
<color name="heartrate_border">#FFCC3300</color>
|
|
||||||
<color name="heartrate_fill">#40E88A70</color>
|
|
||||||
|
|
||||||
<!-- Pink and a transparent pink -->
|
<!-- heart rate chart colors, red and transparent red -->
|
||||||
|
<color name="heart_rate_border">#FFCC3300</color>
|
||||||
|
<color name="heart_rate_fill">#40E88A70</color>
|
||||||
|
|
||||||
|
<!-- cadence chart colors, pink and transparent pink -->
|
||||||
<color name="cadence_border">#FFF128F3</color>
|
<color name="cadence_border">#FFF128F3</color>
|
||||||
<color name="cadence_fill">#40F128F3</color>
|
<color name="cadence_fill">#40F128F3</color>
|
||||||
|
|
||||||
<!-- Purple and a transparent purple -->
|
<!-- power chart colors, purple and transparent purple -->
|
||||||
<color name="power_border">#FF401465</color>
|
<color name="power_border">#FF401465</color>
|
||||||
<color name="power_fill">#40401465</color>
|
<color name="power_fill">#40401465</color>
|
||||||
|
|
||||||
<!-- AppWidget colors -->
|
<!-- track widget line -->
|
||||||
<color name="appwidget_hr">#99999999</color>
|
<color name="track_widget_line">#99999999</color>
|
||||||
|
|
||||||
<!-- Colors for dynamic track drawing -->
|
<!-- dynamic track slow path, green -->
|
||||||
<!-- Green -->
|
|
||||||
<color name="slow_path">#F774DF00</color>
|
<color name="slow_path">#F774DF00</color>
|
||||||
|
|
||||||
<!-- Blue -->
|
<!-- dynamic track normal path, blue -->
|
||||||
<color name="normal_path">#F75858FA</color>
|
<color name="normal_path">#F75858FA</color>
|
||||||
|
|
||||||
<!-- Red -->
|
<!-- dynamic track fast path, red -->
|
||||||
<color name="fast_path">#F7DF0101</color>
|
<color name="fast_path">#F7DF0101</color>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?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.
|
||||||
|
-->
|
||||||
|
<resources>
|
||||||
|
<dimen name="widget_margin">8dp</dimen>
|
||||||
|
</resources>
|
||||||
@@ -157,8 +157,13 @@ limitations under the License.
|
|||||||
</style>
|
</style>
|
||||||
<!-- Theme selector -->
|
<!-- Theme selector -->
|
||||||
<style name="ThemeSelector" parent="android:Theme" />
|
<style name="ThemeSelector" parent="android:Theme" />
|
||||||
<!-- The style for the track widget value -->
|
<!-- The style for the track widget label -->
|
||||||
<style name="TrackWidgetValue" parent="@style/TextSmall">
|
<style name="TrackWidgetLabel" parent="@style/TextSmall">
|
||||||
<item name="android:width">100dp</item>
|
<item name="android:width">100dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
<!-- The style for the track widget value -->
|
||||||
|
<style name="TrackWidgetValue" parent="@style/TextSmall">
|
||||||
|
<item name="android:layout_weight">1</item>
|
||||||
|
<item name="android:layout_width">0dp</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -29,8 +29,8 @@ limitations under the License.
|
|||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:defaultValue="true"
|
android:defaultValue="true"
|
||||||
android:key="@string/stats_use_total_time_key"
|
android:key="@string/stats_use_total_time_key"
|
||||||
android:summaryOff="@string/stats_total_time"
|
android:summaryOff="@string/stats_moving_time"
|
||||||
android:summaryOn="@string/stats_moving_time"
|
android:summaryOn="@string/stats_total_time"
|
||||||
android:title="@string/settings_stats_time_title" />
|
android:title="@string/settings_stats_time_title" />
|
||||||
<PreferenceCategory android:title="@string/settings_show" >
|
<PreferenceCategory android:title="@string/settings_show" >
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
|
|||||||
@@ -14,9 +14,8 @@ 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.
|
||||||
-->
|
-->
|
||||||
<appwidget-provider
|
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:initialLayout="@layout/track_widget"
|
android:initialLayout="@layout/track_widget"
|
||||||
android:minHeight="72dp"
|
android:minHeight="110dp"
|
||||||
android:minWidth="294dp"
|
android:minWidth="250dp"
|
||||||
android:updatePeriodMillis="0" />
|
android:updatePeriodMillis="0" />
|
||||||
|
|||||||
@@ -160,8 +160,8 @@ public class ChartView extends View {
|
|||||||
new int[] {25, 50 },
|
new int[] {25, 50 },
|
||||||
R.string.description_sensor_heart_rate,
|
R.string.description_sensor_heart_rate,
|
||||||
R.string.description_sensor_heart_rate,
|
R.string.description_sensor_heart_rate,
|
||||||
R.color.heartrate_fill,
|
R.color.heart_rate_fill,
|
||||||
R.color.heartrate_border);
|
R.color.heart_rate_border);
|
||||||
series[CADENCE_SERIES] = new ChartValueSeries(context,
|
series[CADENCE_SERIES] = new ChartValueSeries(context,
|
||||||
0,
|
0,
|
||||||
Integer.MAX_VALUE,
|
Integer.MAX_VALUE,
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ public abstract class SensorManager {
|
|||||||
|
|
||||||
private static final String TAG = SensorManager.class.getSimpleName();
|
private static final String TAG = SensorManager.class.getSimpleName();
|
||||||
private static final long MAX_SENSOR_DATE_SET_AGE = 5000;
|
private static final long MAX_SENSOR_DATE_SET_AGE = 5000;
|
||||||
private static final long MAX_SENSOR_STATE_AGE = 30000;
|
private static final long MAX_SENSOR_STATE_AGE = 20000;
|
||||||
private static final int RETRY_PERIOD = 30000;
|
private static final int RETRY_PERIOD = 20000;
|
||||||
|
|
||||||
private SensorState sensorState = SensorState.NONE;
|
private SensorState sensorState = SensorState.NONE;
|
||||||
private long sensorStateTimestamp = System.currentTimeMillis();
|
private long sensorStateTimestamp = System.currentTimeMillis();
|
||||||
|
|||||||
+26
-24
@@ -126,28 +126,39 @@ public class AntSensorManager extends SensorManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setUpChannel() {
|
protected synchronized void setUpChannel() {
|
||||||
|
tearDownChannel();
|
||||||
if (AntInterface.hasAntSupport(context)) {
|
if (AntInterface.hasAntSupport(context)) {
|
||||||
context.registerReceiver(statusReceiver, statusIntentFilter);
|
context.registerReceiver(statusReceiver, statusIntentFilter);
|
||||||
if (!antInterface.initService(context, serviceListener)) {
|
if (!antInterface.initService(context, serviceListener)) {
|
||||||
AntInterface.goToMarket(context);
|
AntInterface.goToMarket(context);
|
||||||
} else {
|
} else {
|
||||||
setSensorState(Sensor.SensorState.CONNECTING);
|
setSensorState(Sensor.SensorState.CONNECTING);
|
||||||
serviceConnected = antInterface.isServiceConnected();
|
handleServiceConnected();
|
||||||
if (serviceConnected) {
|
|
||||||
try {
|
|
||||||
hasClaimedInterface = antInterface.hasClaimedInterface();
|
|
||||||
if (hasClaimedInterface) {
|
|
||||||
enableDataMessage(true);
|
|
||||||
}
|
|
||||||
} catch (AntInterfaceException e) {
|
|
||||||
handleAntError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles service connected. Needs to be synchronized.
|
||||||
|
*/
|
||||||
|
private synchronized void handleServiceConnected() {
|
||||||
|
serviceConnected = antInterface.isServiceConnected();
|
||||||
|
if (serviceConnected) {
|
||||||
|
try {
|
||||||
|
hasClaimedInterface = antInterface.hasClaimedInterface();
|
||||||
|
if (hasClaimedInterface) {
|
||||||
|
enableDataMessage(true);
|
||||||
|
} else {
|
||||||
|
// Need to claim the ant interface if it is available
|
||||||
|
hasClaimedInterface = antInterface.claimInterface();
|
||||||
|
}
|
||||||
|
} catch (AntInterfaceException e) {
|
||||||
|
handleAntError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void tearDownChannel() {
|
protected void tearDownChannel() {
|
||||||
try {
|
try {
|
||||||
@@ -161,6 +172,7 @@ public class AntSensorManager extends SensorManager {
|
|||||||
if (hasClaimedInterface) {
|
if (hasClaimedInterface) {
|
||||||
antInterface.releaseInterface();
|
antInterface.releaseInterface();
|
||||||
}
|
}
|
||||||
|
hasClaimedInterface = false;
|
||||||
antInterface.stopRequestForceClaimInterface();
|
antInterface.stopRequestForceClaimInterface();
|
||||||
} catch (AntServiceNotConnectedException e) {
|
} catch (AntServiceNotConnectedException e) {
|
||||||
// Can safely ignore
|
// Can safely ignore
|
||||||
@@ -168,6 +180,7 @@ public class AntSensorManager extends SensorManager {
|
|||||||
Log.w(TAG, "Exception in tearDonwChannel.", e);
|
Log.w(TAG, "Exception in tearDonwChannel.", e);
|
||||||
}
|
}
|
||||||
antInterface.releaseService();
|
antInterface.releaseService();
|
||||||
|
serviceConnected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,18 +203,7 @@ public class AntSensorManager extends SensorManager {
|
|||||||
private AntInterface.ServiceListener serviceListener = new AntInterface.ServiceListener() {
|
private AntInterface.ServiceListener serviceListener = new AntInterface.ServiceListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onServiceConnected() {
|
public void onServiceConnected() {
|
||||||
serviceConnected = true;
|
handleServiceConnected();
|
||||||
try {
|
|
||||||
hasClaimedInterface = antInterface.hasClaimedInterface();
|
|
||||||
if (hasClaimedInterface) {
|
|
||||||
enableDataMessage(true);
|
|
||||||
} else {
|
|
||||||
// Need to claim the ant interface if it is available
|
|
||||||
hasClaimedInterface = antInterface.claimInterface();
|
|
||||||
}
|
|
||||||
} catch (AntInterfaceException e) {
|
|
||||||
handleAntError();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -220,31 +220,7 @@ public class StatsUtils {
|
|||||||
private static void setSpeedValue(
|
private static void setSpeedValue(
|
||||||
Activity activity, int id, double speed, boolean metricUnits, boolean reportSpeed) {
|
Activity activity, int id, double speed, boolean metricUnits, boolean reportSpeed) {
|
||||||
TextView textView = (TextView) activity.findViewById(id);
|
TextView textView = (TextView) activity.findViewById(id);
|
||||||
String value;
|
textView.setText(StringUtils.formatSpeed(activity, speed, metricUnits, reportSpeed));
|
||||||
if (Double.isNaN(speed) || Double.isInfinite(speed)) {
|
|
||||||
value = activity.getString(R.string.value_unknown);
|
|
||||||
} else {
|
|
||||||
speed *= UnitConversions.MS_TO_KMH;
|
|
||||||
if (metricUnits) {
|
|
||||||
if (reportSpeed) {
|
|
||||||
value = activity.getString(R.string.value_float_kilometer_hour, speed);
|
|
||||||
} else {
|
|
||||||
// convert from hours to minutes
|
|
||||||
double pace = speed == 0 ? 0.0 : 60.0 / speed;
|
|
||||||
value = activity.getString(R.string.value_float_minute_kilometer, pace);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
speed *= UnitConversions.KM_TO_MI;
|
|
||||||
if (reportSpeed) {
|
|
||||||
value = activity.getString(R.string.value_float_mile_hour, speed);
|
|
||||||
} else {
|
|
||||||
// convert from hours to minutes
|
|
||||||
double pace = speed == 0 ? 0.0 : 60.0 / speed;
|
|
||||||
value = activity.getString(R.string.value_float_minute_mile, pace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
textView.setText(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -258,19 +234,7 @@ public class StatsUtils {
|
|||||||
private static void setDistanceValue(
|
private static void setDistanceValue(
|
||||||
Activity activity, int id, double distance, boolean metricUnits) {
|
Activity activity, int id, double distance, boolean metricUnits) {
|
||||||
TextView textView = (TextView) activity.findViewById(id);
|
TextView textView = (TextView) activity.findViewById(id);
|
||||||
String value;
|
textView.setText(StringUtils.formatDistance(activity, distance, metricUnits));
|
||||||
if (Double.isNaN(distance) || Double.isInfinite(distance)) {
|
|
||||||
value = activity.getString(R.string.value_unknown);
|
|
||||||
} else {
|
|
||||||
distance *= UnitConversions.M_TO_KM;
|
|
||||||
if (metricUnits) {
|
|
||||||
value = activity.getString(R.string.value_float_kilometer, distance);
|
|
||||||
} else {
|
|
||||||
distance *= UnitConversions.KM_TO_MI;
|
|
||||||
value = activity.getString(R.string.value_float_mile, distance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
textView.setText(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -108,23 +108,26 @@ public class StringUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats the distance.
|
* Formats the distance.
|
||||||
*
|
*
|
||||||
* @param context the context
|
* @param context the context
|
||||||
* @param distance the distance in meters
|
* @param distance the distance in meters
|
||||||
* @param metric true to use metric. False to use imperial
|
* @param metricUnits true to use metric units. False to use imperial units
|
||||||
*/
|
*/
|
||||||
public static String formatDistance(Context context, double distance, boolean metric) {
|
public static String formatDistance(Context context, double distance, boolean metricUnits) {
|
||||||
if (metric) {
|
if (Double.isNaN(distance) || Double.isInfinite(distance)) {
|
||||||
if (distance > 2000.0) {
|
return context.getString(R.string.value_unknown);
|
||||||
|
}
|
||||||
|
if (metricUnits) {
|
||||||
|
if (distance > 1000.0) {
|
||||||
distance *= UnitConversions.M_TO_KM;
|
distance *= UnitConversions.M_TO_KM;
|
||||||
return context.getString(R.string.value_float_kilometer, distance);
|
return context.getString(R.string.value_float_kilometer, distance);
|
||||||
} else {
|
} else {
|
||||||
return context.getString(R.string.value_float_meter, distance);
|
return context.getString(R.string.value_float_meter, distance);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (distance * UnitConversions.M_TO_MI > 2) {
|
if (distance * UnitConversions.M_TO_MI > 1) {
|
||||||
distance *= UnitConversions.M_TO_MI;
|
distance *= UnitConversions.M_TO_MI;
|
||||||
return context.getString(R.string.value_float_mile, distance);
|
return context.getString(R.string.value_float_mile, distance);
|
||||||
} else {
|
} else {
|
||||||
distance *= UnitConversions.M_TO_FT;
|
distance *= UnitConversions.M_TO_FT;
|
||||||
return context.getString(R.string.value_float_feet, distance);
|
return context.getString(R.string.value_float_feet, distance);
|
||||||
@@ -137,29 +140,31 @@ public class StringUtils {
|
|||||||
*
|
*
|
||||||
* @param context the context
|
* @param context the context
|
||||||
* @param speed the speed in meters per second
|
* @param speed the speed in meters per second
|
||||||
* @param metric true to use metric. False to use imperial
|
* @param metricUnits true to use metric units. False to use imperial units
|
||||||
* @param reportSpeed true to report as speed. False to report as pace
|
* @param reportSpeed true to report as speed. False to report as pace
|
||||||
*/
|
*/
|
||||||
public static String formatSpeed(
|
public static String formatSpeed(
|
||||||
Context context, double speed, boolean metric, boolean reportSpeed) {
|
Context context, double speed, boolean metricUnits, boolean reportSpeed) {
|
||||||
if (Double.isNaN(speed) || Double.isInfinite(speed)) {
|
if (Double.isNaN(speed) || Double.isInfinite(speed)) {
|
||||||
return context.getString(R.string.value_unknown);
|
return context.getString(R.string.value_unknown);
|
||||||
}
|
}
|
||||||
if (metric) {
|
speed *= UnitConversions.MS_TO_KMH;
|
||||||
speed = speed * UnitConversions.MS_TO_KMH;
|
if (metricUnits) {
|
||||||
if (reportSpeed) {
|
if (reportSpeed) {
|
||||||
return context.getString(R.string.value_float_kilometer_hour, speed);
|
return context.getString(R.string.value_float_kilometer_hour, speed);
|
||||||
} else {
|
} else {
|
||||||
double paceInMinute = speed == 0 ? 0.0 : 60 / speed;
|
// convert from hours to minutes
|
||||||
return context.getString(R.string.value_float_minute_kilometer, paceInMinute);
|
double pace = speed == 0 ? 0.0 : 60.0 / speed;
|
||||||
|
return context.getString(R.string.value_float_minute_kilometer, pace);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
speed = speed * UnitConversions.MS_TO_KMH * UnitConversions.KM_TO_MI;
|
speed *= UnitConversions.KM_TO_MI;
|
||||||
if (reportSpeed) {
|
if (reportSpeed) {
|
||||||
return context.getString(R.string.value_float_mile_hour, speed);
|
return context.getString(R.string.value_float_mile_hour, speed);
|
||||||
} else {
|
} else {
|
||||||
double paceInMinute = speed == 0 ? 0.0 : 60 / speed;
|
// convert from hours to minutes
|
||||||
return context.getString(R.string.value_float_minute_mile, paceInMinute);
|
double pace = speed == 0 ? 0.0 : 60.0 / speed;
|
||||||
|
return context.getString(R.string.value_float_minute_mile, pace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
package com.google.android.apps.mytracks.widgets;
|
package com.google.android.apps.mytracks.widgets;
|
||||||
|
|
||||||
import static com.google.android.apps.mytracks.Constants.SETTINGS_NAME;
|
import static com.google.android.apps.mytracks.Constants.SETTINGS_NAME;
|
||||||
import static com.google.android.apps.mytracks.Constants.TAG;
|
|
||||||
|
|
||||||
import com.google.android.apps.mytracks.TrackDetailActivity;
|
import com.google.android.apps.mytracks.TrackDetailActivity;
|
||||||
import com.google.android.apps.mytracks.TrackListActivity;
|
import com.google.android.apps.mytracks.TrackListActivity;
|
||||||
@@ -41,66 +40,77 @@ import android.content.SharedPreferences;
|
|||||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An AppWidgetProvider for displaying key track statistics (distance, time,
|
* A track widget to start/stop recording, launch My Tracks, and display track
|
||||||
* speed) from the current or most recent track.
|
* statistics (distance, time, speed) for the selected track or the last track.
|
||||||
*
|
*
|
||||||
* @author Sandor Dornbush
|
* @author Sandor Dornbush
|
||||||
* @author Paul R. Saxman
|
* @author Paul R. Saxman
|
||||||
*/
|
*/
|
||||||
public class TrackWidgetProvider
|
public class TrackWidgetProvider extends AppWidgetProvider
|
||||||
extends AppWidgetProvider
|
|
||||||
implements OnSharedPreferenceChangeListener {
|
implements OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
class TrackObserver extends ContentObserver {
|
/**
|
||||||
|
* Observer for track content.
|
||||||
|
*
|
||||||
|
* @author Jimmy Shih
|
||||||
|
*/
|
||||||
|
private class TrackObserver extends ContentObserver {
|
||||||
|
|
||||||
public TrackObserver() {
|
public TrackObserver() {
|
||||||
super(contentHandler);
|
super(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void onChange(boolean selfChange) {
|
public void onChange(boolean selfChange) {
|
||||||
updateTrack(null);
|
updateTrack(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Handler contentHandler;
|
private final Handler handler;
|
||||||
private MyTracksProviderUtils providerUtils;
|
|
||||||
private Context context;
|
private Context context;
|
||||||
private String unknown;
|
|
||||||
private TrackObserver trackObserver;
|
private TrackObserver trackObserver;
|
||||||
|
private MyTracksProviderUtils myTracksProviderUtils;
|
||||||
|
|
||||||
|
private String unknown;
|
||||||
|
private String trackStartedBroadcastAction;
|
||||||
|
private String trackStoppedBroadcastAction;
|
||||||
|
|
||||||
|
private SharedPreferences sharedPreferences;
|
||||||
|
private long selectedTrackId;
|
||||||
private boolean metricUnits;
|
private boolean metricUnits;
|
||||||
private boolean reportSpeed;
|
private boolean reportSpeed;
|
||||||
private long selectedTrackId;
|
private boolean useTotalTime;
|
||||||
private SharedPreferences sharedPreferences;
|
|
||||||
private String TRACK_STARTED_ACTION;
|
|
||||||
private String TRACK_STOPPED_ACTION;
|
|
||||||
|
|
||||||
public TrackWidgetProvider() {
|
public TrackWidgetProvider() {
|
||||||
super();
|
super();
|
||||||
contentHandler = new Handler();
|
handler = new Handler();
|
||||||
selectedTrackId = PreferencesUtils.SELECTED_TRACK_ID_DEFAULT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialize(Context aContext) {
|
@Override
|
||||||
if (this.context != null) {
|
public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
|
||||||
return;
|
if (key == null || PreferencesUtils.getKey(context, R.string.metric_units_key).equals(key)) {
|
||||||
|
metricUnits = PreferencesUtils.getBoolean(
|
||||||
|
context, R.string.metric_units_key, PreferencesUtils.METRIC_UNITS_DEFAULT);
|
||||||
|
}
|
||||||
|
if (key == null || PreferencesUtils.getKey(context, R.string.report_speed_key).equals(key)) {
|
||||||
|
reportSpeed = PreferencesUtils.getBoolean(
|
||||||
|
context, R.string.report_speed_key, PreferencesUtils.REPORT_SPEED_DEFAULT);
|
||||||
|
}
|
||||||
|
if (key == null
|
||||||
|
|| PreferencesUtils.getKey(context, R.string.stats_use_total_time_key).equals(key)) {
|
||||||
|
useTotalTime = PreferencesUtils.getBoolean(context, R.string.stats_use_total_time_key,
|
||||||
|
PreferencesUtils.STATS_USE_TOTAL_TIME_DEFAULT);
|
||||||
|
}
|
||||||
|
if (key == null
|
||||||
|
|| PreferencesUtils.getKey(context, R.string.selected_track_id_key).equals(key)) {
|
||||||
|
selectedTrackId = PreferencesUtils.getLong(context, R.string.selected_track_id_key);
|
||||||
|
}
|
||||||
|
if (key != null) {
|
||||||
|
updateTrack(null);
|
||||||
}
|
}
|
||||||
this.context = aContext;
|
|
||||||
trackObserver = new TrackObserver();
|
|
||||||
providerUtils = MyTracksProviderUtils.Factory.get(context);
|
|
||||||
unknown = context.getString(R.string.value_unknown);
|
|
||||||
|
|
||||||
sharedPreferences = context.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE);
|
|
||||||
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
|
|
||||||
onSharedPreferenceChanged(sharedPreferences, null);
|
|
||||||
|
|
||||||
context.getContentResolver().registerContentObserver(
|
|
||||||
TracksColumns.CONTENT_URI, true, trackObserver);
|
|
||||||
TRACK_STARTED_ACTION = context.getString(R.string.track_started_broadcast_action);
|
|
||||||
TRACK_STOPPED_ACTION = context.getString(R.string.track_stopped_broadcast_action);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -111,43 +121,62 @@ public class TrackWidgetProvider
|
|||||||
selectedTrackId = intent.getLongExtra(
|
selectedTrackId = intent.getLongExtra(
|
||||||
context.getString(R.string.track_id_broadcast_extra), selectedTrackId);
|
context.getString(R.string.track_id_broadcast_extra), selectedTrackId);
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
Log.d(TAG,
|
|
||||||
"TrackWidgetProvider.onReceive: trackId=" + selectedTrackId + ", action=" + action);
|
|
||||||
|
|
||||||
if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)
|
if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)
|
||||||
|| AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
|
|| AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
|
||||||
|| TRACK_STARTED_ACTION.equals(action)
|
|| trackStartedBroadcastAction.equals(action)
|
||||||
|| TRACK_STOPPED_ACTION.equals(action)) {
|
|| trackStoppedBroadcastAction.equals(action)) {
|
||||||
updateTrack(action);
|
updateTrack(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisabled(Context aContext) {
|
public void onDisabled(Context aContext) {
|
||||||
if (trackObserver != null) {
|
|
||||||
aContext.getContentResolver().unregisterContentObserver(trackObserver);
|
|
||||||
}
|
|
||||||
if (sharedPreferences != null) {
|
if (sharedPreferences != null) {
|
||||||
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
|
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
|
||||||
}
|
}
|
||||||
|
if (trackObserver != null) {
|
||||||
|
aContext.getContentResolver().unregisterContentObserver(trackObserver);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTrack(String action) {
|
/**
|
||||||
Track track = null;
|
* Initializes the widget.
|
||||||
if (selectedTrackId != PreferencesUtils.SELECTED_TRACK_ID_DEFAULT) {
|
*
|
||||||
Log.d(TAG, "TrackWidgetProvider.updateTrack: Retrieving specified track.");
|
* @param aContext a context
|
||||||
track = providerUtils.getTrack(selectedTrackId);
|
*/
|
||||||
} else {
|
private void initialize(Context aContext) {
|
||||||
Log.d(TAG, "TrackWidgetProvider.updateTrack: Attempting to retrieve previous track.");
|
if (context != null) {
|
||||||
// TODO we should really read the pref.
|
// Already initialized
|
||||||
track = providerUtils.getLastTrack();
|
return;
|
||||||
}
|
}
|
||||||
|
context = aContext;
|
||||||
|
trackObserver = new TrackObserver();
|
||||||
|
myTracksProviderUtils = MyTracksProviderUtils.Factory.get(context);
|
||||||
|
|
||||||
|
unknown = context.getString(R.string.value_unknown);
|
||||||
|
trackStartedBroadcastAction = context.getString(R.string.track_started_broadcast_action);
|
||||||
|
trackStoppedBroadcastAction = context.getString(R.string.track_stopped_broadcast_action);
|
||||||
|
|
||||||
|
sharedPreferences = context.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE);
|
||||||
|
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
|
||||||
|
onSharedPreferenceChanged(sharedPreferences, null);
|
||||||
|
|
||||||
|
context.getContentResolver()
|
||||||
|
.registerContentObserver(TracksColumns.CONTENT_URI, true, trackObserver);
|
||||||
|
}
|
||||||
|
|
||||||
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
|
/**
|
||||||
ComponentName widget = new ComponentName(context, TrackWidgetProvider.class);
|
* Updates the widget.
|
||||||
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.track_widget);
|
*
|
||||||
|
* @param action the action
|
||||||
|
*/
|
||||||
|
private void updateTrack(String action) {
|
||||||
|
Track track = selectedTrackId != PreferencesUtils.SELECTED_TRACK_ID_DEFAULT ? myTracksProviderUtils
|
||||||
|
.getTrack(selectedTrackId)
|
||||||
|
: myTracksProviderUtils.getLastTrack();
|
||||||
|
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.track_widget);
|
||||||
|
|
||||||
// Make all of the stats open the mytracks activity.
|
|
||||||
Intent intent;
|
Intent intent;
|
||||||
if (track != null) {
|
if (track != null) {
|
||||||
intent = IntentUtils.newIntent(context, TrackDetailActivity.class)
|
intent = IntentUtils.newIntent(context, TrackDetailActivity.class)
|
||||||
@@ -156,92 +185,68 @@ public class TrackWidgetProvider
|
|||||||
intent = IntentUtils.newIntent(context, TrackListActivity.class);
|
intent = IntentUtils.newIntent(context, TrackListActivity.class);
|
||||||
}
|
}
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
|
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
|
||||||
views.setOnClickPendingIntent(R.id.appwidget_track_statistics, pendingIntent);
|
remoteViews.setOnClickPendingIntent(R.id.track_widget_statistics, pendingIntent);
|
||||||
|
|
||||||
if (action != null) {
|
if (action != null) {
|
||||||
updateViewButton(views, action);
|
updateButton(remoteViews, action);
|
||||||
}
|
}
|
||||||
updateViewTrackStatistics(views, track);
|
updateStatistics(remoteViews, track);
|
||||||
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(widget);
|
|
||||||
|
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
|
||||||
|
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(
|
||||||
|
new ComponentName(context, TrackWidgetProvider.class));
|
||||||
for (int appWidgetId : appWidgetIds) {
|
for (int appWidgetId : appWidgetIds) {
|
||||||
appWidgetManager.updateAppWidget(appWidgetId, views);
|
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the widget's button with the appropriate intent and icon.
|
* Updates button to start/stop recording.
|
||||||
*
|
*
|
||||||
* @param views The RemoteViews containing the button
|
* @param remoteViews the remote views
|
||||||
* @param action The action broadcast from the track service
|
* @param action the action
|
||||||
*/
|
*/
|
||||||
private void updateViewButton(RemoteViews views, String action) {
|
private void updateButton(RemoteViews remoteViews, String action) {
|
||||||
if (TRACK_STARTED_ACTION.equals(action)) {
|
int trackAction = trackStartedBroadcastAction.equals(action) ? R.string.track_action_end
|
||||||
// If a new track is started by this appwidget or elsewhere,
|
: R.string.track_action_start;
|
||||||
// toggle the button to active and have it disable the track if pressed.
|
int icon = trackStartedBroadcastAction.equals(action) ? R.drawable.app_widget_button_enabled
|
||||||
setButtonIntent(views, R.string.track_action_end, R.drawable.app_widget_button_enabled);
|
: R.drawable.app_widget_button_disabled;
|
||||||
|
Intent intent = new Intent(context, ControlRecordingService.class).setAction(
|
||||||
|
context.getString(trackAction));
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getService(
|
||||||
|
context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
remoteViews.setOnClickPendingIntent(R.id.track_widget_button, pendingIntent);
|
||||||
|
remoteViews.setImageViewResource(R.id.track_widget_button, icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates statistics.
|
||||||
|
*
|
||||||
|
* @param remoteViews the remote views
|
||||||
|
* @param track the track
|
||||||
|
*/
|
||||||
|
private void updateStatistics(RemoteViews remoteViews, Track track) {
|
||||||
|
TripStatistics tripStatistics = track == null ? null : track.getStatistics();
|
||||||
|
String distance = tripStatistics == null ? unknown
|
||||||
|
: StringUtils.formatDistance(context, tripStatistics.getTotalDistance(), metricUnits);
|
||||||
|
int timeLabelId = useTotalTime ? R.string.stats_total_time : R.string.stats_moving_time;
|
||||||
|
String time = tripStatistics == null ? unknown : StringUtils.formatElapsedTime(
|
||||||
|
useTotalTime ? tripStatistics.getTotalTime()
|
||||||
|
: tripStatistics.getMovingTime());
|
||||||
|
int speedLabelId;
|
||||||
|
if (useTotalTime) {
|
||||||
|
speedLabelId = reportSpeed ? R.string.stats_average_speed : R.string.stats_average_pace;
|
||||||
} else {
|
} else {
|
||||||
// If a track is stopped by this appwidget or elsewhere,
|
speedLabelId = reportSpeed ? R.string.stats_average_moving_speed
|
||||||
// toggle the button to inactive and have it start a new track if pressed.
|
: R.string.stats_average_moving_pace;
|
||||||
setButtonIntent(views, R.string.track_action_start, R.drawable.app_widget_button_disabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up the main widget button.
|
|
||||||
*
|
|
||||||
* @param views The widget views
|
|
||||||
* @param action The resource id of the action to fire when the button is pressed
|
|
||||||
* @param icon The resource id of the icon to show for the button
|
|
||||||
*/
|
|
||||||
private void setButtonIntent(RemoteViews views, int action, int icon) {
|
|
||||||
Intent intent = new Intent(context, ControlRecordingService.class)
|
|
||||||
.setAction(context.getString(action));
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getService(context, 0,
|
|
||||||
intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
||||||
views.setOnClickPendingIntent(R.id.appwidget_button, pendingIntent);
|
|
||||||
views.setImageViewResource(R.id.appwidget_button, icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the specified widget's view with the distance, time, and speed of
|
|
||||||
* the specified track.
|
|
||||||
*
|
|
||||||
* @param views The RemoteViews to update with statistics
|
|
||||||
* @param track The track to extract statistics from.
|
|
||||||
*/
|
|
||||||
protected void updateViewTrackStatistics(RemoteViews views, Track track) {
|
|
||||||
if (track == null) {
|
|
||||||
views.setTextViewText(R.id.appwidget_distance_text, unknown);
|
|
||||||
views.setTextViewText(R.id.appwidget_time_text, unknown);
|
|
||||||
views.setTextViewText(R.id.appwidget_speed_text, unknown);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TripStatistics stats = track.getStatistics();
|
|
||||||
String distance = StringUtils.formatDistance(context, stats.getTotalDistance(), metricUnits);
|
|
||||||
String time = StringUtils.formatElapsedTime(stats.getMovingTime());
|
|
||||||
String speed = StringUtils.formatSpeed(
|
|
||||||
context, stats.getAverageMovingSpeed(), metricUnits, reportSpeed);
|
|
||||||
|
|
||||||
views.setTextViewText(R.id.appwidget_distance_text, distance);
|
|
||||||
views.setTextViewText(R.id.appwidget_time_text, time);
|
|
||||||
views.setTextViewText(R.id.appwidget_speed_text, speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
|
|
||||||
if (key == null || PreferencesUtils.getKey(context, R.string.metric_units_key).equals(key)) {
|
|
||||||
metricUnits = PreferencesUtils.getBoolean(
|
|
||||||
context, R.string.metric_units_key, PreferencesUtils.METRIC_UNITS_DEFAULT);
|
|
||||||
}
|
|
||||||
if (key == null || PreferencesUtils.getKey(context, R.string.report_speed_key).equals(key)) {
|
|
||||||
reportSpeed = PreferencesUtils.getBoolean(
|
|
||||||
context, R.string.report_speed_key, PreferencesUtils.REPORT_SPEED_DEFAULT);
|
|
||||||
}
|
|
||||||
if (key == null
|
|
||||||
|| PreferencesUtils.getKey(context, R.string.selected_track_id_key).equals(key)) {
|
|
||||||
selectedTrackId = PreferencesUtils.getLong(context, R.string.selected_track_id_key);
|
|
||||||
Log.d(TAG, "TrackWidgetProvider setting selecting track from preference: " + selectedTrackId);
|
|
||||||
}
|
}
|
||||||
|
String speed = tripStatistics == null ? unknown : StringUtils.formatSpeed(
|
||||||
|
context, useTotalTime ? tripStatistics.getAverageSpeed()
|
||||||
|
: tripStatistics.getAverageMovingSpeed(), metricUnits, reportSpeed);
|
||||||
|
remoteViews.setTextViewText(R.id.track_widget_distance_value, distance);
|
||||||
|
remoteViews.setTextViewText(R.id.track_widget_time_label, context.getString(timeLabelId));
|
||||||
|
remoteViews.setTextViewText(R.id.track_widget_time_value, time);
|
||||||
|
remoteViews.setTextViewText(R.id.track_widget_speed_label, context.getString(speedLabelId));
|
||||||
|
remoteViews.setTextViewText(R.id.track_widget_speed_value, speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user