From 953bd8b908e851da77b16e42428a7b6196ad436b Mon Sep 17 00:00:00 2001 From: youtaol Date: Mon, 4 Jun 2012 13:20:38 +0800 Subject: [PATCH] Merge heads --- MyTracks/AndroidManifest.xml | 2 +- .../res/drawable-hdpi/menu_delete_all.png | Bin 1285 -> 0 bytes MyTracks/res/drawable-hdpi/menu_save_all.png | Bin 1810 -> 0 bytes .../res/drawable-mdpi/menu_delete_all.png | Bin 1138 -> 0 bytes MyTracks/res/drawable-mdpi/menu_save_all.png | Bin 1479 -> 0 bytes .../res/drawable-xhdpi/menu_delete_all.png | Bin 1348 -> 0 bytes MyTracks/res/drawable-xhdpi/menu_save_all.png | Bin 2065 -> 0 bytes MyTracks/res/layout/track_list.xml | 1 + MyTracks/res/layout/track_widget.xml | 123 ++++---- MyTracks/res/menu/track_list.xml | 4 +- MyTracks/res/values-v14/dimens.xml | 19 ++ MyTracks/res/values/colors.xml | 41 ++- MyTracks/res/values/dimens.xml | 19 ++ MyTracks/res/values/styles.xml | 9 +- MyTracks/res/xml/stats_settings.xml | 4 +- MyTracks/res/xml/track_widget_info.xml | 7 +- .../android/apps/mytracks/ChartView.java | 4 +- .../services/sensors/SensorManager.java | 4 +- .../sensors/ant/AntSensorManager.java | 50 ++-- .../apps/mytracks/util/StatsUtils.java | 40 +-- .../apps/mytracks/util/StringUtils.java | 39 +-- .../mytracks/widgets/TrackWidgetProvider.java | 265 +++++++++--------- 22 files changed, 325 insertions(+), 306 deletions(-) delete mode 100644 MyTracks/res/drawable-hdpi/menu_delete_all.png delete mode 100644 MyTracks/res/drawable-hdpi/menu_save_all.png delete mode 100644 MyTracks/res/drawable-mdpi/menu_delete_all.png delete mode 100644 MyTracks/res/drawable-mdpi/menu_save_all.png delete mode 100644 MyTracks/res/drawable-xhdpi/menu_delete_all.png delete mode 100644 MyTracks/res/drawable-xhdpi/menu_save_all.png create mode 100644 MyTracks/res/values-v14/dimens.xml create mode 100644 MyTracks/res/values/dimens.xml diff --git a/MyTracks/AndroidManifest.xml b/MyTracks/AndroidManifest.xml index fbf179b96..0763730ee 100755 --- a/MyTracks/AndroidManifest.xml +++ b/MyTracks/AndroidManifest.xml @@ -16,7 +16,7 @@ limitations under the License. --> diff --git a/MyTracks/res/drawable-hdpi/menu_delete_all.png b/MyTracks/res/drawable-hdpi/menu_delete_all.png deleted file mode 100644 index 094eea589246b46e26d3cf02285f26c1abb33700..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1285 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 S+PXgDUn)c#CORQV&i@Df@x@jE diff --git a/MyTracks/res/drawable-mdpi/menu_delete_all.png b/MyTracks/res/drawable-mdpi/menu_delete_all.png deleted file mode 100644 index 3336760d5f3efdfefefd6899317c3a09264430f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1138 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 diff --git a/MyTracks/res/drawable-xhdpi/menu_save_all.png b/MyTracks/res/drawable-xhdpi/menu_save_all.png deleted file mode 100644 index 791240fd255052e94c008e8d5393d0b0f6175020..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2065 zcmaJ?ZB!Fi8V&&^i9q>SMG@*43|Jt^3=kz#0_GD_2%kYi3rB`zfGi{vl8FQkb%UhP ztyL7no{F|YD@EKB#YIKSDyD2LQW0I0==y;zE>;u~6ys-iV#V%{vUASNz3)Bm^SsZ! z?{n__H8nZGlNLZDkw~7>)uMD_T;+TzbBS-8y5u@BEW*VKJOj(eOA$Rv;;XPc6p(6= z0yG^(RAnW-Xe^23x=bxs;0jq1ti&`d#F@h~X>-~aX` z9Z;)y^tBurDANhiLiOr$J(^LTELWBnDY+_od>jyKf(Zf*iX(tYQ>-<>CLaA2FHFpx z%WOLEDg`g%(SH-Akfj1bOpgK_7RXeBDtHs!w6v5}8pXo&1#F1R<+8y@c4Q=z$Y2`Ev^Zj7 zY7N0N3?kH^)T?#48q)$!MkEh2;ygN`^tUZ&bZ=<2hS$eL92nb#=-3bobZ%)TQ6~HU zsT$3jYy+N-{;u~Ai4F2H9m-Be4VY1{BpR0=>@1~&g?bdhF})naif2wSwGhKGLm{RE zgc%$b1jrDjTI*bSg^MT~8SM9_#U+NhG%_sfaH(UAg;y zV#=TR-s6{V9Rp~E1D*#Oy#Ic6q^Hs}S?HLTee5=0NeSdsR-LNK?t1F~aY9OutN()| zi-jNWabrw^lru$(_S=S#$j^6Q|K-{j5tpqaeR286_dgwL+mQLLb?lS(cUW3W+T9f7 z2$vnCL^Gq?H<#L)wQrN-WuhP)`DmiyV6xrai!utW&komBZ4L1tpQN&re7b2%n%YAx zQMMJ7ClWjG9JuSde&TPw`uYLsZQ$xs-0!KGCEzt}8xWYV3$AMhO#bhUAw4+)-$yT8 zU9LKKrqg5uYPPytAi?6Mpk<)TS>Oa|^#Nt07xEQEw%x;im^Ktk|U6d@#vj zJwKM6Zw8Ybu0aJrhe8pUzyR(5on8#&CtIrZSujHGp?V$)O-&#h+os2#_qRyN_QOYq z#}QjoyU4WVu@RkTjA-fyk;V-+iPG))NB))ugLmWo=4pw~Wl_$Y!Jtb!jP}A$&92L( zVFL4)@eEb?s#Ob&jQLBqS~Tt<)R@!qZ)lYn9=QgzZmT%RwKZctd2!khohth*cJi2V zYtbZbUpJR}=)sHD@a2PDH)?S~a*dhi5iLDu4vo+GGA*$79|6mL`2KOT*J=N}M{(Dr z_6~n{mv>3wGM_k~5JQ3-CorEBv@Nqtm7 zgIk&mv=tp?J8pbW)wKtFFnxB4Ym2h&wE124t|ou+*3B%%xdZ%!{-eo?YT35>K%*dK z!Ep6Ue&}1Sd*>|)`_Fhf6?+gJw**`szf^^Xm3pAnUDgWAuRDiN@Ha0%y6Z^H+zjRQ zQ%RPGxqHuK2Du!9rW`M01i^S85!j;cj4H#{8r|fF?HP#EEuE@9yJ!9Z*hLRF4%t2L zY~LS79@!Y;DZ1tm*Kk7?ZLFLW$}Fdkj~Yv>_U;OO*xh2MEUaq(h4QRS!_M3l z`Zdz0$aaf~F%N%wHoRn8V?D1G?#=q{632fcwx*zM%EGO6H=e3S>?1vVb5i=GOV5Y4 zh?`517E66#W?c4AHT$geT;Giy`gvbogTb9VD13c-iI zSBB5OV`!)V&g|=8xA67^75h&-8=Ttr@2NE2&B1TJB{g38nNk^De(@3Kh~mew@i3#J!s4-)4X84-BE%{h$3!JZ$0?VWE=`s&UdOib@uQ(G=; zaj&|;PP@W*hwI2s^6SnD=ywEu$K>)3d&wtvUTyB|%4#_tGDPZd`h9{SI#F|!T>R5X zS7f?* - - + android:padding="@dimen/widget_margin" > + android:layout_width="fill_parent" + android:orientation="horizontal" > + - - - - - - - - - - - - + android:clickable="true" + android:id="@+id/track_widget_statistics" + android:layout_height="fill_parent" + android:layout_weight="1" + android:layout_width="0dp" + android:orientation="vertical" + android:paddingLeft="8dp" > + + + + + + + + + + + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/MyTracks/res/menu/track_list.xml b/MyTracks/res/menu/track_list.xml index ef23f34fc..7aa85c5b3 100644 --- a/MyTracks/res/menu/track_list.xml +++ b/MyTracks/res/menu/track_list.xml @@ -36,7 +36,7 @@ limitations under the License. android:id="@+id/track_list_import" android:title="@string/menu_import"/> @@ -47,7 +47,7 @@ limitations under the License. + + + 0dp + \ No newline at end of file diff --git a/MyTracks/res/values/colors.xml b/MyTracks/res/values/colors.xml index 672ffeeba..c2935ec0b 100644 --- a/MyTracks/res/values/colors.xml +++ b/MyTracks/res/values/colors.xml @@ -19,46 +19,45 @@ limitations under the License. #FF0000FF #FFAAAAAA #FFFF0000 + #00000000 #FFFFFFFF #FFFF8800 - - - + + #FF339933 #40B3CFB3 - + #FF0066FF #40C8E0FF - + #FF0066FF #40C8E0FF - - - #FFCC3300 - #40E88A70 - + + #FFCC3300 + #40E88A70 + + #FFF128F3 #40F128F3 - + #FF401465 #40401465 - - #99999999 - - - + + #99999999 + + #F774DF00 - - + + #F75858FA - - + + #F7DF0101 - + \ No newline at end of file diff --git a/MyTracks/res/values/dimens.xml b/MyTracks/res/values/dimens.xml new file mode 100644 index 000000000..11c778950 --- /dev/null +++ b/MyTracks/res/values/dimens.xml @@ -0,0 +1,19 @@ + + + + 8dp + \ No newline at end of file diff --git a/MyTracks/res/values/styles.xml b/MyTracks/res/values/styles.xml index cd6dae0d8..04f9c5ae7 100644 --- a/MyTracks/res/values/styles.xml +++ b/MyTracks/res/values/styles.xml @@ -157,8 +157,13 @@ limitations under the License. + + \ No newline at end of file diff --git a/MyTracks/res/xml/stats_settings.xml b/MyTracks/res/xml/stats_settings.xml index 9186c4a09..42c628a51 100644 --- a/MyTracks/res/xml/stats_settings.xml +++ b/MyTracks/res/xml/stats_settings.xml @@ -29,8 +29,8 @@ limitations under the License. - diff --git a/MyTracks/src/com/google/android/apps/mytracks/ChartView.java b/MyTracks/src/com/google/android/apps/mytracks/ChartView.java index 880e146e8..bfa518280 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/ChartView.java +++ b/MyTracks/src/com/google/android/apps/mytracks/ChartView.java @@ -160,8 +160,8 @@ public class ChartView extends View { new int[] {25, 50 }, R.string.description_sensor_heart_rate, R.string.description_sensor_heart_rate, - R.color.heartrate_fill, - R.color.heartrate_border); + R.color.heart_rate_fill, + R.color.heart_rate_border); series[CADENCE_SERIES] = new ChartValueSeries(context, 0, Integer.MAX_VALUE, diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/SensorManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/SensorManager.java index eb63ce6a0..8b3787abf 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/SensorManager.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/SensorManager.java @@ -33,8 +33,8 @@ public abstract class SensorManager { private static final String TAG = SensorManager.class.getSimpleName(); private static final long MAX_SENSOR_DATE_SET_AGE = 5000; - private static final long MAX_SENSOR_STATE_AGE = 30000; - private static final int RETRY_PERIOD = 30000; + private static final long MAX_SENSOR_STATE_AGE = 20000; + private static final int RETRY_PERIOD = 20000; private SensorState sensorState = SensorState.NONE; private long sensorStateTimestamp = System.currentTimeMillis(); diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java index 2ed9f6cf1..a227afa1a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java @@ -126,28 +126,39 @@ public class AntSensorManager extends SensorManager { } @Override - protected void setUpChannel() { + protected synchronized void setUpChannel() { + tearDownChannel(); if (AntInterface.hasAntSupport(context)) { context.registerReceiver(statusReceiver, statusIntentFilter); if (!antInterface.initService(context, serviceListener)) { AntInterface.goToMarket(context); } else { setSensorState(Sensor.SensorState.CONNECTING); - serviceConnected = antInterface.isServiceConnected(); - if (serviceConnected) { - try { - hasClaimedInterface = antInterface.hasClaimedInterface(); - if (hasClaimedInterface) { - enableDataMessage(true); - } - } catch (AntInterfaceException e) { - handleAntError(); - } - } + handleServiceConnected(); } } } + /** + * 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 protected void tearDownChannel() { try { @@ -161,6 +172,7 @@ public class AntSensorManager extends SensorManager { if (hasClaimedInterface) { antInterface.releaseInterface(); } + hasClaimedInterface = false; antInterface.stopRequestForceClaimInterface(); } catch (AntServiceNotConnectedException e) { // Can safely ignore @@ -168,6 +180,7 @@ public class AntSensorManager extends SensorManager { Log.w(TAG, "Exception in tearDonwChannel.", e); } antInterface.releaseService(); + serviceConnected = false; } } @@ -190,18 +203,7 @@ public class AntSensorManager extends SensorManager { private AntInterface.ServiceListener serviceListener = new AntInterface.ServiceListener() { @Override public void onServiceConnected() { - serviceConnected = true; - 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(); - } + handleServiceConnected(); } @Override diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/StatsUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/StatsUtils.java index 32e49af82..07ebe5634 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/StatsUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/StatsUtils.java @@ -220,31 +220,7 @@ public class StatsUtils { private static void setSpeedValue( Activity activity, int id, double speed, boolean metricUnits, boolean reportSpeed) { TextView textView = (TextView) activity.findViewById(id); - String value; - 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); + textView.setText(StringUtils.formatSpeed(activity, speed, metricUnits, reportSpeed)); } /** @@ -258,19 +234,7 @@ public class StatsUtils { private static void setDistanceValue( Activity activity, int id, double distance, boolean metricUnits) { TextView textView = (TextView) activity.findViewById(id); - String value; - 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); + textView.setText(StringUtils.formatDistance(activity, distance, metricUnits)); } /** diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java index 4046d7f41..3ac00583f 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/StringUtils.java @@ -108,23 +108,26 @@ public class StringUtils { /** * Formats the distance. - * + * * @param context the context * @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) { - if (metric) { - if (distance > 2000.0) { + public static String formatDistance(Context context, double distance, boolean metricUnits) { + if (Double.isNaN(distance) || Double.isInfinite(distance)) { + return context.getString(R.string.value_unknown); + } + if (metricUnits) { + if (distance > 1000.0) { distance *= UnitConversions.M_TO_KM; return context.getString(R.string.value_float_kilometer, distance); } else { - return context.getString(R.string.value_float_meter, distance); + return context.getString(R.string.value_float_meter, distance); } } else { - if (distance * UnitConversions.M_TO_MI > 2) { + if (distance * UnitConversions.M_TO_MI > 1) { distance *= UnitConversions.M_TO_MI; - return context.getString(R.string.value_float_mile, distance); + return context.getString(R.string.value_float_mile, distance); } else { distance *= UnitConversions.M_TO_FT; return context.getString(R.string.value_float_feet, distance); @@ -137,29 +140,31 @@ public class StringUtils { * * @param context the context * @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 */ 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)) { return context.getString(R.string.value_unknown); } - if (metric) { - speed = speed * UnitConversions.MS_TO_KMH; + speed *= UnitConversions.MS_TO_KMH; + if (metricUnits) { if (reportSpeed) { return context.getString(R.string.value_float_kilometer_hour, speed); } else { - double paceInMinute = speed == 0 ? 0.0 : 60 / speed; - return context.getString(R.string.value_float_minute_kilometer, paceInMinute); + // convert from hours to minutes + double pace = speed == 0 ? 0.0 : 60.0 / speed; + return context.getString(R.string.value_float_minute_kilometer, pace); } } else { - speed = speed * UnitConversions.MS_TO_KMH * UnitConversions.KM_TO_MI; + speed *= UnitConversions.KM_TO_MI; if (reportSpeed) { return context.getString(R.string.value_float_mile_hour, speed); } else { - double paceInMinute = speed == 0 ? 0.0 : 60 / speed; - return context.getString(R.string.value_float_minute_mile, paceInMinute); + // convert from hours to minutes + double pace = speed == 0 ? 0.0 : 60.0 / speed; + return context.getString(R.string.value_float_minute_mile, pace); } } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java b/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java index c92f92984..d02a5eb11 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java +++ b/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java @@ -17,7 +17,6 @@ package com.google.android.apps.mytracks.widgets; import static com.google.android.apps.mytracks.Constants.SETTINGS_NAME; -import static com.google.android.apps.mytracks.Constants.TAG; import com.google.android.apps.mytracks.TrackDetailActivity; import com.google.android.apps.mytracks.TrackListActivity; @@ -41,66 +40,77 @@ import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.database.ContentObserver; import android.os.Handler; -import android.util.Log; import android.widget.RemoteViews; /** - * An AppWidgetProvider for displaying key track statistics (distance, time, - * speed) from the current or most recent track. - * + * A track widget to start/stop recording, launch My Tracks, and display track + * statistics (distance, time, speed) for the selected track or the last track. + * * @author Sandor Dornbush * @author Paul R. Saxman */ -public class TrackWidgetProvider - extends AppWidgetProvider +public class TrackWidgetProvider extends AppWidgetProvider implements OnSharedPreferenceChangeListener { - class TrackObserver extends ContentObserver { + /** + * Observer for track content. + * + * @author Jimmy Shih + */ + private class TrackObserver extends ContentObserver { public TrackObserver() { - super(contentHandler); + super(handler); } + @Override public void onChange(boolean selfChange) { updateTrack(null); } } - private final Handler contentHandler; - private MyTracksProviderUtils providerUtils; + private final Handler handler; private Context context; - private String unknown; 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 reportSpeed; - private long selectedTrackId; - private SharedPreferences sharedPreferences; - private String TRACK_STARTED_ACTION; - private String TRACK_STOPPED_ACTION; + private boolean useTotalTime; public TrackWidgetProvider() { super(); - contentHandler = new Handler(); - selectedTrackId = PreferencesUtils.SELECTED_TRACK_ID_DEFAULT; + handler = new Handler(); } - private void initialize(Context aContext) { - if (this.context != null) { - return; + @Override + public void onSharedPreferenceChanged(SharedPreferences preferences, 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.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 @@ -111,43 +121,62 @@ public class TrackWidgetProvider selectedTrackId = intent.getLongExtra( context.getString(R.string.track_id_broadcast_extra), selectedTrackId); String action = intent.getAction(); - Log.d(TAG, - "TrackWidgetProvider.onReceive: trackId=" + selectedTrackId + ", action=" + action); if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action) || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action) - || TRACK_STARTED_ACTION.equals(action) - || TRACK_STOPPED_ACTION.equals(action)) { + || trackStartedBroadcastAction.equals(action) + || trackStoppedBroadcastAction.equals(action)) { updateTrack(action); } } @Override public void onDisabled(Context aContext) { - if (trackObserver != null) { - aContext.getContentResolver().unregisterContentObserver(trackObserver); - } if (sharedPreferences != null) { sharedPreferences.unregisterOnSharedPreferenceChangeListener(this); } + if (trackObserver != null) { + aContext.getContentResolver().unregisterContentObserver(trackObserver); + } } - private void updateTrack(String action) { - Track track = null; - if (selectedTrackId != PreferencesUtils.SELECTED_TRACK_ID_DEFAULT) { - Log.d(TAG, "TrackWidgetProvider.updateTrack: Retrieving specified track."); - track = providerUtils.getTrack(selectedTrackId); - } else { - Log.d(TAG, "TrackWidgetProvider.updateTrack: Attempting to retrieve previous track."); - // TODO we should really read the pref. - track = providerUtils.getLastTrack(); + /** + * Initializes the widget. + * + * @param aContext a context + */ + private void initialize(Context aContext) { + if (context != null) { + // Already initialized + 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); - RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.track_widget); + /** + * Updates the 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; if (track != null) { intent = IntentUtils.newIntent(context, TrackDetailActivity.class) @@ -156,92 +185,68 @@ public class TrackWidgetProvider intent = IntentUtils.newIntent(context, TrackListActivity.class); } 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) { - updateViewButton(views, action); + updateButton(remoteViews, action); } - updateViewTrackStatistics(views, track); - int[] appWidgetIds = appWidgetManager.getAppWidgetIds(widget); + updateStatistics(remoteViews, track); + + AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); + int[] appWidgetIds = appWidgetManager.getAppWidgetIds( + new ComponentName(context, TrackWidgetProvider.class)); for (int appWidgetId : appWidgetIds) { - appWidgetManager.updateAppWidget(appWidgetId, views); + appWidgetManager.updateAppWidget(appWidgetId, remoteViews); } } /** - * Update the widget's button with the appropriate intent and icon. - * - * @param views The RemoteViews containing the button - * @param action The action broadcast from the track service + * Updates button to start/stop recording. + * + * @param remoteViews the remote views + * @param action the action */ - private void updateViewButton(RemoteViews views, String action) { - if (TRACK_STARTED_ACTION.equals(action)) { - // If a new track is started by this appwidget or elsewhere, - // toggle the button to active and have it disable the track if pressed. - setButtonIntent(views, R.string.track_action_end, R.drawable.app_widget_button_enabled); + private void updateButton(RemoteViews remoteViews, String action) { + int trackAction = trackStartedBroadcastAction.equals(action) ? R.string.track_action_end + : R.string.track_action_start; + int icon = trackStartedBroadcastAction.equals(action) ? 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 { - // If a track is stopped by this appwidget or elsewhere, - // toggle the button to inactive and have it start a new track if pressed. - 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); + speedLabelId = reportSpeed ? R.string.stats_average_moving_speed + : R.string.stats_average_moving_pace; } + 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); } }