From 16f321736450d8e715927dac6f6d0e7b594e2a1d Mon Sep 17 00:00:00 2001 From: Jimmy Shih Date: Wed, 28 Mar 2012 15:28:38 -0700 Subject: [PATCH] Set TrackListActivity as the main activity. Move all startup dialogs to TrackListActivity. Move one-time application config to MyTracksApplication --- MyTracks/AndroidManifest.xml | 28 +- .../res/drawable-hdpi/ic_menu_tracklist.png | Bin 2147 -> 0 bytes .../res/drawable-ldpi/ic_menu_tracklist.png | Bin 1076 -> 0 bytes .../res/drawable-mdpi/ic_menu_tracklist.png | Bin 1458 -> 0 bytes MyTracks/res/menu/track_detail.xml | 5 - MyTracks/res/values/strings.xml | 4 - .../android/apps/mytracks/Constants.java | 4 +- .../android/apps/mytracks/ImportActivity.java | 14 +- .../android/apps/mytracks/MenuManager.java | 5 - .../apps/mytracks/MyTracksApplication.java | 7 + .../android/apps/mytracks/SearchActivity.java | 15 +- .../apps/mytracks/TrackDetailActivity.java | 292 ++++-------------- .../apps/mytracks/TrackListActivity.java | 173 +++++++++-- .../apps/mytracks/util/CheckUnitsUtils.java | 47 +++ 14 files changed, 274 insertions(+), 320 deletions(-) delete mode 100644 MyTracks/res/drawable-hdpi/ic_menu_tracklist.png delete mode 100644 MyTracks/res/drawable-ldpi/ic_menu_tracklist.png delete mode 100644 MyTracks/res/drawable-mdpi/ic_menu_tracklist.png create mode 100644 MyTracks/src/com/google/android/apps/mytracks/util/CheckUnitsUtils.java diff --git a/MyTracks/AndroidManifest.xml b/MyTracks/AndroidManifest.xml index 80f7e11fe..6b255feb1 100755 --- a/MyTracks/AndroidManifest.xml +++ b/MyTracks/AndroidManifest.xml @@ -190,28 +190,6 @@ limitations under the License. android:name="android.app.default_searchable" android:value="com.google.android.apps.mytracks.SearchActivity" /> - - - - - - - - - - - - - - - - - - @@ -244,6 +222,7 @@ limitations under the License. android:name="android.app.default_searchable" android:value="com.google.android.apps.mytracks.SearchActivity" /> + @@ -257,6 +236,11 @@ limitations under the License. + + + + + diff --git a/MyTracks/res/drawable-hdpi/ic_menu_tracklist.png b/MyTracks/res/drawable-hdpi/ic_menu_tracklist.png deleted file mode 100644 index 68338297b5b7ee6a274ce26cb3de84ef67a1b797..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2147 zcmV-p2%PtcP)rh!-?`^KSGinPT18x3 zEr418wE$`XBr!lPPTcI*sFZc0uj`Vm-`K{IL7N=`gq><*;$h-uVgyc+Nr@eIbM<8c zsl=qfNl65f2q4lJFGzrip99II0|S; zOoBFUjyGIm`+f$jtYrn{CCDArP>4%scwH{Fx3_ol^y$-=VfP;flFCNHy5h00KL|)Do6UaG z+1csu=;**d|KG*=d|t_9GCg7|aB|o(H zBiOyhz!91ND}c1~(P-2U8ltqdwHaRQ^?Ff*lyErgrDN^w?cQRssDWbyYBS5$ty>W& zvZWrg8QNnpy=ya8AP~?*qzR=`Nz)?!JZ=YrK@B{&+bxv_;e*5Wa`smE1g&)6MV&Mad_dc(Qv_Icuo%xUr#0ta?&PSR}m;?wnPNn zW-nG6R3_9(L{CM3o@BW6}e?hVg ztdbKh=HciDa?#8 zkJSk<;wy~;aSwBukyceS%wA^=LSQl+QFYAb$p*#l+_{sOot@neV^^pNKupu4qoeC= z(1i;ZhJX~lAsaeiOLN1+!@uv^wd*PDF0tXJI_Vl-abR9o_{D)jF_l}vd#sBH+ z>zg=p=FBwipF4MM_|cd40C z&1h3i0FefWw1C1LPV2o=Y@YwM!H^X@QGjN$d9F=0v-vXb7g&Wm9E2C70EpA-Qmp_L z89%`Qyb4A-j8nN$XURqZoOuFpDK+o8|$WG(7O{7~NQ_CEUTUtVWqfZ6~m!>bRJU zJd8??(Tt2z!^*0j%@bMmnP^;2S-yFwvQ1+uM^;VQyd4L{W%C-BgX2v%MYb=r z7-Atd#G*EbSY9{8yb=#Fl?}0%N*&1yIJ7!XojUdD{QUe$wp?piz!;}TMn+B?K73e< zOJBKi2X5({n za|Zw*EqUSAty>=eS&esfbxD=HfG!8L)en6df!!aKMkFr)Fka$RMgZYCB&7gIWk}(6 zEEY2)xH7PLrMf0xfAWG=xC5UGYLR|jjMnpIOkUu^9rY(Kkf$ut22t_?X_jmN=^k`r zk{3us!$p6NPiT-0ARQO0KipwOOgAH&Z+N)lRZCuIM7U#J@&XPMtKQ7$i?(Tlv-rl|&jj>T@aXjNnK{y<)BrhZqiN~2thNe{c+-Oy8T=K%RXV2bz`0(Kn zARjRCE#?OY2j_UIasB%B_uxr&$QE)1m!vo_F!0N^ZQK4*nvlG}Cz6LG$LDSOn zh9xghxWlDX*XDx~GWs>8n%$9AHaK}9&jA!-!&Szj*Pz;y7jE9XiLVt5!L`E90$+PR zK0f{%Y0%2bO5ptY^Y1S#EbNmF86e(Ij~+dGEtyO%a5kv+=a{X2}?(gsa za&mI=C)^$z8~gD7{rltmOef1U&p^6y>C&afBrm|9?LcNOnzAV&0A{T2iVDJZJRYws zJDVP4>FHr*!^RxM;*f0@+;?LkLs+{Af;ou5!eM6hX$oTX9;N!3 z38PO_P!A>Gnbt?@4kEPJrB9vZcE)X6sgNb*8z%p?qjeFED4j@GZWT; zS+F!L;qrwUHcVshHvIr)mX?-wTdmej{y>&xqgX61uCA`Ws#Gd_r>Cc?sAy!f*|!@T z8}~7-`2k9dj*hB|qDYBELZXD%G%eQK+j|4P-LbJTH5!dNzOX~rb$b6*7IEJ#lY4r4 zq;xt>k#Qavh9M=BNxD&Txtx^AWX^nH1}zplA$hmo3&>eL8UJV`5|Jn>G~)62IbT>n zmStU<)W+c8ppHmn-J!(~>y&^)LqkSiUtdgA?W)ykx;vpe0cuW6Oe~~QsTqY52?Jr( z0Pq>6zY2vy8QWPxghH1KEYiYzztA_&<&0;w5m?GYZCXK#(KI2L_Bx}!DeZl4rL`xdK1rk@^? zUDoNDEQuQ(-*mH`RedP!8N2RV# ziOq6|sD2&O9Xu~mqvgIZ1GYKys7(xF+JXLh=Iz_I+6Skzyv|_++{2kiY!E>B5m8T%eKsD3wav^YimR zmY0_oQ4(&6qW!?Yz-vgFr-AZge}8`yQOmiL57ejo$45s;k3=3WkB^V<;PO0BevFTg zD_qp`o&zmSTNuyh^NL83j~r51ngq)a_qmHYyZh8ZHA)m9Rvd%n2NgdmjuaWj1_J2F z5Au<5U#LcgMKL{O2LaNirlxjr)KPg9*pG;wb(Dl1)SPwRx*pIU0R{kXfrSM|4PmeV0000OaI^+EI{N#P@Yqz%T8M|RBM6jS>x~it@y{h-V@4eTadcCgP<>t9p;9h~&E8wB7 zQulIKg}EB{DnFa^sze#h{i^)CewzXi%1=E)JxE<+rLeF6Y%_^OB0p_yZGAvLGt|rC zoX=)GZXg(s#~*fdbl}g|6Zw2zDVNLXIeA7AW zyqy9t1r5SOFjakN-lUZALciY+v+^er2_+hhDjttVngVTYZN{FB%(RgL9uiUs27|8% z2XoVP9b?9tKp>!?%Txe+Rw|Wixtu6aH$A-(#MZAS>f$Cc6|l{Dq;k>V(LELILVgpeDnrN5JF)casOg0$0f3fimxRX~zSNOsK}fdih!9u?mly zFVT5}nj|(h<m>2Q+4}l=y05QKUtC;#Mh=~n&BWx$ zf9&k+OwrGCHlwB{1XJ)23=G79@jwCLG!zOQ6691JpmlQMB)9@>EUN(pOQlkreNlCS zLPjJC!4O7RQ3%5Nt|ZpL)L>%SD8w>&ohl#-dP4!+h&g7ik*z?pJ({5q2+KB1pm8%k zH`d5jKtLo%L}ox&dwaVM^AMdJr=Q7WYGgWD5DNu&I(1EC>sB`eli6%mgi=RLTp%a@ zj0An1Za}oVIz@-idwYBT#>3#?;3u>uB{L(V1FX?u{>%{Sh>2D9_;8bqtRz5gKr$1H z8CltS3#xL*o81lIG$U(kYaf#By(yXy!f1lm=bM|GpW}ITb@k(1E|;>HS<6j`eDQE& zW8(|X$aE(uW$5(u^iy)qgf*d|_TI_K$u~noLq%G%PGg$vgy#JG{4M(V6`Rtn3g9#~ za$*g!znD_uWyNAqrMx(XXRHC?iECOO%@It~ei~bbBO){ELI@+QDW$1|_bR?H*ji>n zZ((B9X-avGzxbn70r9l$=4Ek#8zwd?VWwcBlVc1oBi}Ic0#gCmY|OG$oe~)qmAkvU zFDPA%iY$wmQO$Qf17SaT0}=lluk+1w@hTNm^dUbv1(yOk%`UPsLYhI$f3lITWE+v zEV$p2)O+|8D#HK$l0yk|&yw994U4-A3k#3Q_H2v0dwY8*?$+n$=f5NqnwE`12J zMW;aO6(YkJ@qum@cQJ;NyR2r);kvjxGBWanZ2U%Xmyqe%#Kgp(c-iRa=pp%vbQGdI z+;wsH|M-zF#}In!M?N>7S=B}brxvrZtIw==J}16c;9db2?Oy=~01#Pgt0>OQIRF3v M07*qoM6N<$g7_=H{{R30 diff --git a/MyTracks/res/menu/track_detail.xml b/MyTracks/res/menu/track_detail.xml index 5ed7798dc..95d8bbca8 100644 --- a/MyTracks/res/menu/track_detail.xml +++ b/MyTracks/res/menu/track_detail.xml @@ -25,11 +25,6 @@ limitations under the License. android:id="@+id/menu_stop_recording" android:showAsAction="always" android:title="@string/menu_stop_recording"/> - Stop recording - - Tracks - clickedData) { - Intent intent = new Intent(Intent.ACTION_VIEW); + Intent intent = new Intent(this, TrackDetailActivity.class) + .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); if (clickedData.containsKey(WAYPOINT_ID_FIELD)) { - long waypointId = (Long) clickedData.get(WAYPOINT_ID_FIELD); - Uri uri = ContentUris.withAppendedId(WaypointsColumns.CONTENT_URI, waypointId); - intent.setDataAndType(uri, WaypointsColumns.CONTENT_ITEMTYPE); + intent.putExtra(TrackDetailActivity.WAYPOINT_ID, (Long) clickedData.get(WAYPOINT_ID_FIELD)); } else { - long trackId = (Long) clickedData.get(TRACK_ID_FIELD); - Uri uri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, trackId); - intent.setDataAndType(uri, TracksColumns.CONTENT_ITEMTYPE); + intent.putExtra(TrackDetailActivity.TRACK_ID, (Long) clickedData.get(TRACK_ID_FIELD)); } return intent; } diff --git a/MyTracks/src/com/google/android/apps/mytracks/TrackDetailActivity.java b/MyTracks/src/com/google/android/apps/mytracks/TrackDetailActivity.java index c4c586ad2..97df82df0 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/TrackDetailActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/TrackDetailActivity.java @@ -22,31 +22,19 @@ import static com.google.android.apps.mytracks.Constants.TAG; import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.TrackDataHub; -import com.google.android.apps.mytracks.content.TracksColumns; import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.content.WaypointCreationRequest; -import com.google.android.apps.mytracks.content.WaypointsColumns; import com.google.android.apps.mytracks.services.ITrackRecordingService; import com.google.android.apps.mytracks.services.ServiceUtils; import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection; -import com.google.android.apps.mytracks.util.AnalyticsUtils; import com.google.android.apps.mytracks.util.ApiAdapterFactory; -import com.google.android.apps.mytracks.util.EulaUtils; -import com.google.android.apps.mytracks.util.UriUtils; -import com.google.android.maps.mytracks.BuildConfig; import com.google.android.maps.mytracks.R; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; import android.app.TabActivity; -import android.content.ContentUris; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Resources; -import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; import android.speech.tts.TextToSpeech; @@ -62,62 +50,44 @@ import android.widget.TabHost; import android.widget.Toast; /** - * The super activity that embeds our sub activities. + * An activity to show the track detail. * * @author Leif Hendrik Wilden * @author Rodrigo Damazio */ @SuppressWarnings("deprecation") public class TrackDetailActivity extends TabActivity implements OnTouchListener { - private static final int DIALOG_EULA_ID = 0; - private static final int DIALOG_CHECK_UNITS_ID = 1; - private static final String CHECK_UNITS_PREFERENCE_FILE = "checkunits"; - private static final String CHECK_UNITS_PREFERENCE_KEY = "checkunits.checked"; - - private TrackDataHub dataHub; - - /** - * Menu manager. - */ + + public static final String TRACK_ID = "track_id"; + public static final String WAYPOINT_ID = "waypoint_id"; + + private MyTracksProviderUtils myTracksProviderUtils; + private SharedPreferences sharedPreferences; + private TrackDataHub trackDataHub; private MenuManager menuManager; - - /** - * Preferences. - */ - private SharedPreferences preferences; - + private TrackRecordingServiceConnection trackRecordingServiceConnection; + private NavControls navControls; + /** * True if a new track should be created after the track recording service * binds. */ private boolean startNewTrackRequested = false; - /** - * Utilities to deal with the database. - */ - private MyTracksProviderUtils providerUtils; - - /* - * Tabs/View navigation: - */ - - private NavControls navControls; - private final Runnable changeTab = new Runnable() { public void run() { getTabHost().setCurrentTab(navControls.getCurrentIcons()); } }; - /* - * Recording service interaction: + /** + * Callback when {@linkk TrackRecordingServiceConnection} binding changes. */ - private final Runnable serviceBindCallback = new Runnable() { @Override public void run() { - synchronized (serviceConnection) { - ITrackRecordingService service = serviceConnection.getServiceIfBound(); + synchronized (trackRecordingServiceConnection) { + ITrackRecordingService service = trackRecordingServiceConnection.getServiceIfBound(); if (startNewTrackRequested && service != null) { Log.i(TAG, "Starting recording"); startNewTrackRequested = false; @@ -129,37 +99,21 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener } }; - private TrackRecordingServiceConnection serviceConnection; - - /* - * Application lifetime events: - * ============================ - */ - @Override protected void onCreate(Bundle savedInstanceState) { - Log.d(TAG, "MyTracks.onCreate"); super.onCreate(savedInstanceState); - if (BuildConfig.DEBUG) { - ApiAdapterFactory.getApiAdapter().enableStrictMode(); - } - AnalyticsUtils.sendPageViews(this, "/appstart"); - - providerUtils = MyTracksProviderUtils.Factory.get(this); - preferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE); - dataHub = ((MyTracksApplication) getApplication()).getTrackDataHub(); + myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this); + sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE); + trackDataHub = ((MyTracksApplication) getApplication()).getTrackDataHub(); menuManager = new MenuManager(this); - serviceConnection = new TrackRecordingServiceConnection(this, serviceBindCallback); + trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, serviceBindCallback); setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM); // Show the action bar (or nothing at all). ApiAdapterFactory.getApiAdapter().showActionBar(this); - // If the user just starts typing (on a device with a keyboard), we start a search. - setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); - final Resources res = getResources(); final TabHost tabHost = getTabHost(); tabHost.addTab(tabHost.newTabSpec(MAP_TAB_TAG) @@ -189,138 +143,55 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener navControls.show(); tabHost.addView(layout); layout.setOnTouchListener(this); - - if (!EulaUtils.getEulaValue(this)) { - showDialog(DIALOG_EULA_ID); - } } @Override protected void onStart() { - Log.d(TAG, "MyTracks.onStart"); super.onStart(); - dataHub.start(); + trackDataHub.start(); // Ensure that service is running and bound if we're supposed to be recording - if (ServiceUtils.isRecording(this, null, preferences)) { - serviceConnection.startAndBind(); + if (ServiceUtils.isRecording( + this, trackRecordingServiceConnection.getServiceIfBound(), sharedPreferences)) { + trackRecordingServiceConnection.startAndBind(); } Intent intent = getIntent(); - String action = intent.getAction(); - Uri data = intent.getData(); - if ((Intent.ACTION_VIEW.equals(action) || Intent.ACTION_EDIT.equals(action)) - && TracksColumns.CONTENT_ITEMTYPE.equals(intent.getType()) - && UriUtils.matchesContentUri(data, TracksColumns.CONTENT_URI)) { - long trackId = ContentUris.parseId(data); - dataHub.loadTrack(trackId); - } else if (Intent.ACTION_VIEW.equals(action) - && WaypointsColumns.CONTENT_ITEMTYPE.equals(intent.getType()) - && UriUtils.matchesContentUri(data, WaypointsColumns.CONTENT_URI)) { - // TODO(rdamazio): Waypoint URIs should be base/trackid/waypointid - long waypointId = ContentUris.parseId(data); - Waypoint waypoint = providerUtils.getWaypoint(waypointId); - long trackId = waypoint.getTrackId(); - + long trackId = intent.getLongExtra(TRACK_ID, -1L); + if (trackId != -1L) { + trackDataHub.loadTrack(trackId); + return; + } + + long waypointId = intent.getLongExtra(WAYPOINT_ID, -1L); + if (waypointId != -1L) { + Waypoint waypoint = myTracksProviderUtils.getWaypoint(waypointId); + trackId = waypoint.getTrackId(); + // Request that the waypoint is shown (now or when the right track is loaded). showWaypoint(trackId, waypointId); - + // Load the right track, if not loaded already. - dataHub.loadTrack(trackId); + trackDataHub.loadTrack(trackId); } } @Override protected void onResume() { - // Called when the current activity is being displayed or re-displayed - // to the user. - Log.d(TAG, "MyTracks.onResume"); - serviceConnection.bindIfRunning(); super.onResume(); - } - - @Override - protected void onPause() { - // Called when activity is going into the background, but has not (yet) been - // killed. Shouldn't block longer than approx. 2 seconds. - Log.d(TAG, "MyTracks.onPause"); - super.onPause(); + trackRecordingServiceConnection.bindIfRunning(); } @Override protected void onStop() { - Log.d(TAG, "MyTracks.onStop"); - dataHub.stop(); super.onStop(); + trackDataHub.stop(); } @Override protected void onDestroy() { - Log.d(TAG, "MyTracks.onDestroy"); - serviceConnection.unbind(); super.onDestroy(); - } - - @Override - protected Dialog onCreateDialog(int id) { - switch (id) { - case DIALOG_EULA_ID: - return new AlertDialog.Builder(this) - .setCancelable(true) - .setMessage(EulaUtils.getEulaMessage(this)) - .setNegativeButton(R.string.eula_decline, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - finish(); - } - }) - .setOnCancelListener(new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - finish(); - } - }) - .setPositiveButton(R.string.eula_accept, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - EulaUtils.setEulaValue(TrackDetailActivity.this); - startActivityForResult( - new Intent(TrackDetailActivity.this, WelcomeActivity.class), Constants.WELCOME); - } - }) - .setTitle(R.string.eula_title) - .create(); - case DIALOG_CHECK_UNITS_ID: - return new AlertDialog.Builder(this) - .setCancelable(true) - .setOnCancelListener(new DialogInterface.OnCancelListener() { - public void onCancel(DialogInterface dialog) { - SharedPreferences sharedPreferences = getSharedPreferences( - CHECK_UNITS_PREFERENCE_FILE, Context.MODE_PRIVATE); - ApiAdapterFactory.getApiAdapter().applyPreferenceChanges( - sharedPreferences.edit().putBoolean(CHECK_UNITS_PREFERENCE_KEY, true)); - } - }) - .setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - SharedPreferences sharedPreferences = getSharedPreferences( - CHECK_UNITS_PREFERENCE_FILE, Context.MODE_PRIVATE); - ApiAdapterFactory.getApiAdapter().applyPreferenceChanges( - sharedPreferences.edit().putBoolean(CHECK_UNITS_PREFERENCE_KEY, true)); - - int position = ((AlertDialog) dialog).getListView().getSelectedItemPosition(); - SharedPreferences.Editor editor = preferences.edit(); - ApiAdapterFactory.getApiAdapter().applyPreferenceChanges( - editor.putBoolean(getString(R.string.metric_units_key), position == 0)); - } - }) - .setSingleChoiceItems(new CharSequence[] { getString(R.string.preferred_units_metric), - getString(R.string.preferred_units_imperial) }, 0, null) - .setTitle(R.string.preferred_units_title) - .create(); - default: - return null; - } + trackRecordingServiceConnection.unbind(); } @Override @@ -334,9 +205,9 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener MapActivity map = getMapTab(); boolean isSatelliteView = map != null ? map.isSatelliteView() : false; - menuManager.onPrepareOptionsMenu(menu, providerUtils.getLastTrack() != null, - ServiceUtils.isRecording(this, serviceConnection.getServiceIfBound(), preferences), - dataHub.isATrackSelected(), + menuManager.onPrepareOptionsMenu(menu, myTracksProviderUtils.getLastTrack() != null, + ServiceUtils.isRecording(this, trackRecordingServiceConnection.getServiceIfBound(), sharedPreferences), + trackDataHub.isATrackSelected(), isSatelliteView, getTabHost().getCurrentTabTag()); @@ -350,15 +221,10 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener : super.onOptionsItemSelected(item); } - /* - * Key events: - * =========== - */ - @Override public boolean onTrackballEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { - if (ServiceUtils.isRecording(this, serviceConnection.getServiceIfBound(), preferences)) { + if (ServiceUtils.isRecording(this, trackRecordingServiceConnection.getServiceIfBound(), sharedPreferences)) { try { insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS); } catch (RemoteException e) { @@ -374,53 +240,19 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener } @Override - public void onActivityResult(int requestCode, int resultCode, - final Intent results) { - Log.d(TAG, "MyTracks.onActivityResult"); - long trackId = dataHub.getSelectedTrackId(); - if (results != null) { - trackId = results.getLongExtra("trackid", trackId); + public void onActivityResult(int requestCode, int resultCode, final Intent results) { + if (requestCode != Constants.SHOW_WAYPOINT) { + Log.d(TAG, "Warning unhandled request code: " + requestCode); + return; } - - switch (requestCode) { - case Constants.SHOW_TRACK: { - if (results != null) { - if (trackId >= 0) { - dataHub.loadTrack(trackId); - - // The track list passed the requested action as result code. Hand - // it off to the onActivityResult for further processing: - if (resultCode != Constants.SHOW_TRACK) { - onActivityResult(resultCode, Activity.RESULT_OK, results); - } - } + if (results != null) { + long waypointId = results.getLongExtra(WaypointDetails.WAYPOINT_ID_EXTRA, -1L); + if (waypointId != -1L) { + MapActivity map = getMapTab(); + if (map != null) { + getTabHost().setCurrentTab(0); + map.showWaypoint(waypointId); } - break; - } - case Constants.SHOW_WAYPOINT: { - if (results != null) { - final long waypointId = results.getLongExtra(WaypointDetails.WAYPOINT_ID_EXTRA, -1); - if (waypointId >= 0) { - MapActivity map = getMapTab(); - if (map != null) { - getTabHost().setCurrentTab(0); - map.showWaypoint(waypointId); - } - } - } - break; - } - case Constants.WELCOME: { - SharedPreferences sharedPreferences = getSharedPreferences( - CHECK_UNITS_PREFERENCE_FILE, Context.MODE_PRIVATE); - if (!sharedPreferences.getBoolean(CHECK_UNITS_PREFERENCE_KEY, false)) { - showDialog(DIALOG_CHECK_UNITS_ID); - } - break; - } - - default: { - Log.w(TAG, "Warning unhandled request code: " + requestCode); } } } @@ -453,7 +285,7 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener * @throws RemoteException If the call on the service failed. */ private long insertWaypoint(WaypointCreationRequest request) throws RemoteException { - ITrackRecordingService trackRecordingService = serviceConnection.getServiceIfBound(); + ITrackRecordingService trackRecordingService = trackRecordingServiceConnection.getServiceIfBound(); if (trackRecordingService == null) { throw new IllegalStateException("The recording service is not bound."); } @@ -474,7 +306,7 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener try { long recordingTrackId = trackRecordingService.startNewTrack(); // Select the recording track. - dataHub.loadTrack(recordingTrackId); + trackDataHub.loadTrack(recordingTrackId); Toast.makeText(this, getString(R.string.track_record_success), Toast.LENGTH_SHORT).show(); // TODO: We catch Exception, because after eliminating the service process // all exceptions it may throw are no longer wrapped in a RemoteException. @@ -489,9 +321,9 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener * it. Starts recording a new track. */ void startRecording() { - synchronized (serviceConnection) { + synchronized (trackRecordingServiceConnection) { startNewTrackRequested = true; - serviceConnection.startAndBind(); + trackRecordingServiceConnection.startAndBind(); // Binding was already requested before, it either already happened // (in which case running the callback manually triggers the actual recording start) @@ -511,7 +343,7 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener Constants.SETTINGS_NAME, Context.MODE_PRIVATE); long currentTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1); - ITrackRecordingService trackRecordingService = serviceConnection.getServiceIfBound(); + ITrackRecordingService trackRecordingService = trackRecordingServiceConnection.getServiceIfBound(); if (trackRecordingService != null) { try { trackRecordingService.endCurrentTrack(); @@ -520,7 +352,7 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener } } - serviceConnection.stop(); + trackRecordingServiceConnection.stop(); if (currentTrackId > 0) { Intent intent = new Intent(this, TrackEditActivity.class) @@ -531,7 +363,7 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener } long getSelectedTrackId() { - return dataHub.getSelectedTrackId(); + return trackDataHub.getSelectedTrackId(); } /** @@ -577,4 +409,4 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener private ChartActivity getChartTab() { return (ChartActivity) getLocalActivityManager().getActivity(CHART_TAB_TAG); } -} +} \ No newline at end of file diff --git a/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java b/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java index 7a1af743d..9d6fdbd3e 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/TrackListActivity.java @@ -23,7 +23,9 @@ import com.google.android.apps.mytracks.services.ITrackRecordingService; import com.google.android.apps.mytracks.services.ServiceUtils; import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection; import com.google.android.apps.mytracks.util.ApiAdapterFactory; +import com.google.android.apps.mytracks.util.CheckUnitsUtils; import com.google.android.apps.mytracks.util.DialogUtils; +import com.google.android.apps.mytracks.util.EulaUtils; import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.maps.mytracks.R; @@ -37,8 +39,10 @@ import android.content.SharedPreferences.Editor; import android.database.Cursor; import android.os.Bundle; import android.os.Parcelable; +import android.speech.tts.TextToSpeech; import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentActivity; +import android.support.v4.app.FragmentTransaction; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; @@ -62,8 +66,13 @@ import android.widget.Toast; public class TrackListActivity extends FragmentActivity { private static final String TAG = TrackListActivity.class.getSimpleName(); - private static final String EXPORT_ALL_DIALOG_TAG = "exportAllDialog"; + private static final String CHECK_UNITS_DIALOG_TAG = "checkUnitsDialog"; private static final String DELETE_ALL_DIALOG_TAG = "deleteAllDialog"; + private static final String EULA_DIALOG_TAG = "eulaDialog"; + private static final String EXPORT_ALL_DIALOG_TAG = "exportAllDialog"; + + private static final int WELCOME_ACTIVITY_REQUEST_CODE = 0; + private static final String[] PROJECTION = new String[] { TracksColumns._ID, TracksColumns.NAME, @@ -108,8 +117,10 @@ public class TrackListActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM); + setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); setContentView(R.layout.track_list); - + trackRecordingServiceConnection = new TrackRecordingServiceConnection( this, bindChangedCallback); @@ -138,8 +149,9 @@ public class TrackListActivity extends FragmentActivity { listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - setResult(Constants.SHOW_TRACK, new Intent().putExtra("trackid", id)); - finish(); + Intent intent = new Intent(TrackListActivity.this, TrackDetailActivity.class) + .putExtra(TrackDetailActivity.TRACK_ID, id); + startActivity(intent); } }); adapter = new ResourceCursorAdapter(this, R.layout.track_list_item, null, 0) { @@ -205,13 +217,27 @@ public class TrackListActivity extends FragmentActivity { adapter.swapCursor(null); } }); + + if (!EulaUtils.getEulaValue(this)) { + new EulaDialogFragment().show(getSupportFragmentManager(), EULA_DIALOG_TAG); + } } @Override protected void onStart() { super.onStart(); + if (ServiceUtils.isRecording( + this, trackRecordingServiceConnection.getServiceIfBound(), sharedPreferences)) { + trackRecordingServiceConnection.startAndBind(); + } + } + + @Override + protected void onResume() { + super.onResume(); trackRecordingServiceConnection.bindIfRunning(); } + @Override protected void onDestroy() { @@ -219,6 +245,23 @@ public class TrackListActivity extends FragmentActivity { trackRecordingServiceConnection.unbind(); } + @Override + public void onActivityResult(int requestCode, int resultCode, final Intent results) { + if (requestCode == WELCOME_ACTIVITY_REQUEST_CODE) { + if (!CheckUnitsUtils.getCheckUnitsValue(this)) { + /* + * See bug http://code.google.com/p/android/issues/detail?id=23761. + * Instead of + * new CheckUnitsDialogFragment().show(getSupportFragmentManager(), CHECK_UNITS_DIALOG_TAG) + * Need to use commitAllowingStateLoss with the support package. + */ + FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); + fragmentTransaction.add(new CheckUnitsDialogFragment(), CHECK_UNITS_DIALOG_TAG); + fragmentTransaction.commitAllowingStateLoss(); + } + } + } + @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.track_list, menu); @@ -361,6 +404,101 @@ public class TrackListActivity extends FragmentActivity { } } + /** + * Check Units DialogFragment. + */ + private static class CheckUnitsDialogFragment extends DialogFragment { + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + + return new AlertDialog.Builder(getActivity()).setCancelable(true) + .setOnCancelListener(new DialogInterface.OnCancelListener() { + public void onCancel(DialogInterface dialog) { + CheckUnitsUtils.setCheckUnitsValue(getActivity()); + } + }) + .setPositiveButton(R.string.generic_ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + CheckUnitsUtils.setCheckUnitsValue(getActivity()); + + int position = ((AlertDialog) dialog).getListView().getSelectedItemPosition(); + SharedPreferences sharedPreferences = getActivity() + .getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE); + ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(sharedPreferences.edit() + .putBoolean(getString(R.string.metric_units_key), position == 0)); + } + }) + .setSingleChoiceItems(new CharSequence[] { getString(R.string.preferred_units_metric), + getString(R.string.preferred_units_imperial) }, 0, null) + .setTitle(R.string.preferred_units_title) + .create(); + } + } + + /** + * Delete All DialogFragment. + */ + private static class DeleteAllDialogFragment extends DialogFragment { + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + return DialogUtils.createConfirmationDialog(getActivity(), + R.string.track_list_delete_all_confirm_message, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + MyTracksProviderUtils.Factory.get(getActivity()).deleteAllTracks(); + /* + * TODO Verify that selected_track_key is still needed with the + * ICS navigation design + */ + SharedPreferences sharedPreferences = getActivity() + .getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE); + Editor editor = sharedPreferences.edit(); + // TODO: Go through data manager + editor.putLong(getString(R.string.selected_track_key), -1L); + ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor); + } + }); + } + }; + + /** + * Eula DialogFragment. + */ + private static class EulaDialogFragment extends DialogFragment { + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + return new AlertDialog.Builder(getActivity()) + .setCancelable(true) + .setMessage( + EulaUtils.getEulaMessage(getActivity())) + .setNegativeButton(R.string.eula_decline, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + getActivity().finish(); + } + }) + .setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + getActivity().finish(); + } + }) + .setPositiveButton(R.string.eula_accept, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + EulaUtils.setEulaValue(getActivity()); + getActivity().startActivityForResult( + new Intent(getActivity(), WelcomeActivity.class), WELCOME_ACTIVITY_REQUEST_CODE); + } + }) + .setTitle(R.string.eula_title) + .create(); + } + } + /** * Export All DialogFragment. */ @@ -391,33 +529,6 @@ public class TrackListActivity extends FragmentActivity { } }; - /** - * Delete All DialogFragment. - */ - private static class DeleteAllDialogFragment extends DialogFragment { - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - return DialogUtils.createConfirmationDialog(getActivity(), - R.string.track_list_delete_all_confirm_message, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - MyTracksProviderUtils.Factory.get(getActivity()).deleteAllTracks(); - /* - * TODO Verify that selected_track_key is still needed with the - * ICS navigation design - */ - SharedPreferences sharedPreferences = getActivity() - .getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE); - Editor editor = sharedPreferences.edit(); - // TODO: Go through data manager - editor.putLong(getString(R.string.selected_track_key), -1L); - ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor); - } - }); - } - }; - @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_SEARCH) { diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/CheckUnitsUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/CheckUnitsUtils.java new file mode 100644 index 000000000..85fe5aa0b --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/util/CheckUnitsUtils.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.android.apps.mytracks.util; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; + +/** + * Utilities for checking units. + * + * @author Jimmy Shih + */ +public class CheckUnitsUtils { + + private static final String CHECK_UNITS_PREFERENCE_FILE = "checkunits"; + private static final String CHECK_UNITS_PREFERENCE_KEY = "checkunits.checked"; + + private CheckUnitsUtils() {} + + public static boolean getCheckUnitsValue(Context context) { + SharedPreferences sharedPreferences = context.getSharedPreferences( + CHECK_UNITS_PREFERENCE_FILE, Context.MODE_PRIVATE); + return sharedPreferences.getBoolean(CHECK_UNITS_PREFERENCE_KEY, false); + } + + public static void setCheckUnitsValue(Context context) { + SharedPreferences sharedPreferences = context.getSharedPreferences( + CHECK_UNITS_PREFERENCE_FILE, Context.MODE_PRIVATE); + Editor editor = sharedPreferences.edit().putBoolean(CHECK_UNITS_PREFERENCE_KEY, true); + ApiAdapterFactory.getApiAdapter().applyPreferenceChanges(editor); + } +}