Set TrackListActivity as the main activity.

Move all startup dialogs to TrackListActivity.
Move one-time application config to MyTracksApplication
This commit is contained in:
Jimmy Shih
2012-03-28 15:28:38 -07:00
parent 9500169719
commit 16f3217364
14 changed files with 274 additions and 320 deletions
+6 -22
View File
@@ -190,28 +190,6 @@ limitations under the License.
android:name="android.app.default_searchable" android:name="android.app.default_searchable"
android:value="com.google.android.apps.mytracks.SearchActivity" /> android:value="com.google.android.apps.mytracks.SearchActivity" />
</activity> </activity>
<activity
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale"
android:name="com.google.android.apps.mytracks.TrackDetailActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.google.track" />
<data android:mimeType="vnd.android.cursor.item/vnd.google.waypoint" />
</intent-filter>
<meta-data
android:name="android.app.default_searchable"
android:value="com.google.android.apps.mytracks.SearchActivity" />
</activity>
<activity <activity
android:launchMode="singleTop" android:launchMode="singleTop"
android:name="com.google.android.apps.mytracks.SearchActivity" > android:name="com.google.android.apps.mytracks.SearchActivity" >
@@ -244,6 +222,7 @@ limitations under the License.
android:name="android.app.default_searchable" android:name="android.app.default_searchable"
android:value="com.google.android.apps.mytracks.SearchActivity" /> android:value="com.google.android.apps.mytracks.SearchActivity" />
</activity> </activity>
<activity android:name="com.google.android.apps.mytracks.TrackDetailActivity" />
<activity <activity
android:label="@string/track_edit_title" android:label="@string/track_edit_title"
android:name="com.google.android.apps.mytracks.TrackEditActivity" > android:name="com.google.android.apps.mytracks.TrackEditActivity" >
@@ -257,6 +236,11 @@ limitations under the License.
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name="com.google.android.apps.mytracks.TrackListActivity" > <activity android:name="com.google.android.apps.mytracks.TrackListActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data <meta-data
android:name="android.app.default_searchable" android:name="android.app.default_searchable"
android:value="com.google.android.apps.mytracks.SearchActivity" /> android:value="com.google.android.apps.mytracks.SearchActivity" />
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

-5
View File
@@ -25,11 +25,6 @@ limitations under the License.
android:id="@+id/menu_stop_recording" android:id="@+id/menu_stop_recording"
android:showAsAction="always" android:showAsAction="always"
android:title="@string/menu_stop_recording"/> android:title="@string/menu_stop_recording"/>
<item
android:icon="@drawable/ic_menu_tracklist"
android:id="@+id/menu_tracks"
android:showAsAction="ifRoom"
android:title="@string/menu_tracks"/>
<item <item
android:icon="@drawable/ic_menu_waypoints" android:icon="@drawable/ic_menu_waypoints"
android:id="@+id/menu_markers" android:id="@+id/menu_markers"
-4
View File
@@ -1025,10 +1025,6 @@ limitations under the License.
translation_description="In the menu, to stop recording a track."> translation_description="In the menu, to stop recording a track.">
Stop recording Stop recording
</string> </string>
<string name="menu_tracks"
translation_description="In the menu, to show a list of all the tracks.">
Tracks
</string>
<!-- My Location --> <!-- My Location -->
<string name="my_location_approximate_location" <string name="my_location_approximate_location"
@@ -36,9 +36,7 @@ public abstract class Constants {
/* /*
* onActivityResult request codes: * onActivityResult request codes:
*/ */
public static final int SHOW_TRACK = 0; public static final int SHOW_WAYPOINT = 0;
public static final int SHOW_WAYPOINT = 1;
public static final int WELCOME = 2;
/* /*
* Context menu ids. Sorted alphabetically. * Context menu ids. Sorted alphabetically.
@@ -16,7 +16,6 @@
package com.google.android.apps.mytracks; package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.util.DialogUtils; import com.google.android.apps.mytracks.util.DialogUtils;
import com.google.android.apps.mytracks.util.FileUtils; import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.UriUtils; import com.google.android.apps.mytracks.util.UriUtils;
@@ -26,7 +25,6 @@ import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.ContentUris;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
@@ -129,7 +127,7 @@ public class ImportActivity extends Activity {
.getQuantityString(R.plurals.importGpxFiles, totalCount, totalCount); .getQuantityString(R.plurals.importGpxFiles, totalCount, totalCount);
message = getString(R.string.import_success, successCount, totalFiles, path); message = getString(R.string.import_success, successCount, totalFiles, path);
} }
return new AlertDialog.Builder(this).setCancelable(true) return new AlertDialog.Builder(this)
.setCancelable(true) .setCancelable(true)
.setMessage(message) .setMessage(message)
.setOnCancelListener(new DialogInterface.OnCancelListener() { .setOnCancelListener(new DialogInterface.OnCancelListener() {
@@ -142,12 +140,10 @@ public class ImportActivity extends Activity {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if (!importAll && trackId != -1L) { if (!importAll && trackId != -1L) {
Intent intent = new Intent(Intent.ACTION_VIEW); Intent intent = new Intent(ImportActivity.this, TrackDetailActivity.class)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.setDataAndType( .putExtra(TrackDetailActivity.TRACK_ID, trackId);
ContentUris.withAppendedId(TracksColumns.CONTENT_URI, trackId),
TracksColumns.CONTENT_ITEMTYPE);
startActivity(intent); startActivity(intent);
} }
finish(); finish();
@@ -117,11 +117,6 @@ class MenuManager {
updateActionItems(false); updateActionItems(false);
return true; return true;
} }
case R.id.menu_tracks: {
activity.startActivityForResult(new Intent(activity, TrackListActivity.class),
Constants.SHOW_TRACK);
return true;
}
case R.id.menu_markers: { case R.id.menu_markers: {
Intent startIntent = new Intent(activity, WaypointsList.class); Intent startIntent = new Intent(activity, WaypointsList.class);
startIntent.putExtra("trackid", activity.getSelectedTrackId()); startIntent.putExtra("trackid", activity.getSelectedTrackId());
@@ -17,6 +17,9 @@ package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.TrackDataHub; import com.google.android.apps.mytracks.content.TrackDataHub;
import com.google.android.apps.mytracks.services.RemoveTempFilesService; import com.google.android.apps.mytracks.services.RemoveTempFilesService;
import com.google.android.apps.mytracks.util.AnalyticsUtils;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
import com.google.android.maps.mytracks.BuildConfig;
import android.app.Application; import android.app.Application;
import android.content.Intent; import android.content.Intent;
@@ -32,6 +35,10 @@ public class MyTracksApplication extends Application {
@Override @Override
public void onCreate() { public void onCreate() {
if (BuildConfig.DEBUG) {
ApiAdapterFactory.getApiAdapter().enableStrictMode();
}
AnalyticsUtils.sendPageViews(this, "/appstart");
startService(new Intent(this, RemoveTempFilesService.class)); startService(new Intent(this, RemoveTempFilesService.class));
} }
@@ -23,22 +23,18 @@ import com.google.android.apps.mytracks.content.SearchEngine.ScoredResult;
import com.google.android.apps.mytracks.content.SearchEngine.SearchQuery; import com.google.android.apps.mytracks.content.SearchEngine.SearchQuery;
import com.google.android.apps.mytracks.content.SearchEngineProvider; import com.google.android.apps.mytracks.content.SearchEngineProvider;
import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.TracksColumns;
import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.WaypointsColumns;
import com.google.android.apps.mytracks.stats.TripStatistics; import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.ListActivity; import android.app.ListActivity;
import android.app.SearchManager; import android.app.SearchManager;
import android.content.ContentUris;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.location.Location; import android.location.Location;
import android.location.LocationManager; import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.provider.SearchRecentSuggestions; import android.provider.SearchRecentSuggestions;
import android.util.Log; import android.util.Log;
@@ -251,15 +247,12 @@ public class SearchActivity extends ListActivity {
} }
private Intent createViewDataIntent(Map<String, Object> clickedData) { private Intent createViewDataIntent(Map<String, Object> 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)) { if (clickedData.containsKey(WAYPOINT_ID_FIELD)) {
long waypointId = (Long) clickedData.get(WAYPOINT_ID_FIELD); intent.putExtra(TrackDetailActivity.WAYPOINT_ID, (Long) clickedData.get(WAYPOINT_ID_FIELD));
Uri uri = ContentUris.withAppendedId(WaypointsColumns.CONTENT_URI, waypointId);
intent.setDataAndType(uri, WaypointsColumns.CONTENT_ITEMTYPE);
} else { } else {
long trackId = (Long) clickedData.get(TRACK_ID_FIELD); intent.putExtra(TrackDetailActivity.TRACK_ID, (Long) clickedData.get(TRACK_ID_FIELD));
Uri uri = ContentUris.withAppendedId(TracksColumns.CONTENT_URI, trackId);
intent.setDataAndType(uri, TracksColumns.CONTENT_ITEMTYPE);
} }
return intent; return intent;
} }
@@ -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.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.TrackDataHub; 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.Waypoint;
import com.google.android.apps.mytracks.content.WaypointCreationRequest; 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.ITrackRecordingService;
import com.google.android.apps.mytracks.services.ServiceUtils; import com.google.android.apps.mytracks.services.ServiceUtils;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection; 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.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 com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.TabActivity; import android.app.TabActivity;
import android.content.ContentUris;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.RemoteException; import android.os.RemoteException;
import android.speech.tts.TextToSpeech; import android.speech.tts.TextToSpeech;
@@ -62,62 +50,44 @@ import android.widget.TabHost;
import android.widget.Toast; import android.widget.Toast;
/** /**
* The super activity that embeds our sub activities. * An activity to show the track detail.
* *
* @author Leif Hendrik Wilden * @author Leif Hendrik Wilden
* @author Rodrigo Damazio * @author Rodrigo Damazio
*/ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class TrackDetailActivity extends TabActivity implements OnTouchListener { public class TrackDetailActivity extends TabActivity implements OnTouchListener {
private static final int DIALOG_EULA_ID = 0;
private static final int DIALOG_CHECK_UNITS_ID = 1; public static final String TRACK_ID = "track_id";
private static final String CHECK_UNITS_PREFERENCE_FILE = "checkunits"; public static final String WAYPOINT_ID = "waypoint_id";
private static final String CHECK_UNITS_PREFERENCE_KEY = "checkunits.checked";
private MyTracksProviderUtils myTracksProviderUtils;
private TrackDataHub dataHub; private SharedPreferences sharedPreferences;
private TrackDataHub trackDataHub;
/**
* Menu manager.
*/
private MenuManager menuManager; private MenuManager menuManager;
private TrackRecordingServiceConnection trackRecordingServiceConnection;
/** private NavControls navControls;
* Preferences.
*/
private SharedPreferences preferences;
/** /**
* True if a new track should be created after the track recording service * True if a new track should be created after the track recording service
* binds. * binds.
*/ */
private boolean startNewTrackRequested = false; 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() { private final Runnable changeTab = new Runnable() {
public void run() { public void run() {
getTabHost().setCurrentTab(navControls.getCurrentIcons()); getTabHost().setCurrentTab(navControls.getCurrentIcons());
} }
}; };
/* /**
* Recording service interaction: * Callback when {@linkk TrackRecordingServiceConnection} binding changes.
*/ */
private final Runnable serviceBindCallback = new Runnable() { private final Runnable serviceBindCallback = new Runnable() {
@Override @Override
public void run() { public void run() {
synchronized (serviceConnection) { synchronized (trackRecordingServiceConnection) {
ITrackRecordingService service = serviceConnection.getServiceIfBound(); ITrackRecordingService service = trackRecordingServiceConnection.getServiceIfBound();
if (startNewTrackRequested && service != null) { if (startNewTrackRequested && service != null) {
Log.i(TAG, "Starting recording"); Log.i(TAG, "Starting recording");
startNewTrackRequested = false; startNewTrackRequested = false;
@@ -129,37 +99,21 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
} }
}; };
private TrackRecordingServiceConnection serviceConnection;
/*
* Application lifetime events:
* ============================
*/
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "MyTracks.onCreate");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (BuildConfig.DEBUG) {
ApiAdapterFactory.getApiAdapter().enableStrictMode();
}
AnalyticsUtils.sendPageViews(this, "/appstart"); myTracksProviderUtils = MyTracksProviderUtils.Factory.get(this);
sharedPreferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
providerUtils = MyTracksProviderUtils.Factory.get(this); trackDataHub = ((MyTracksApplication) getApplication()).getTrackDataHub();
preferences = getSharedPreferences(Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
dataHub = ((MyTracksApplication) getApplication()).getTrackDataHub();
menuManager = new MenuManager(this); menuManager = new MenuManager(this);
serviceConnection = new TrackRecordingServiceConnection(this, serviceBindCallback); trackRecordingServiceConnection = new TrackRecordingServiceConnection(this, serviceBindCallback);
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM); setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
// Show the action bar (or nothing at all). // Show the action bar (or nothing at all).
ApiAdapterFactory.getApiAdapter().showActionBar(this); 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 Resources res = getResources();
final TabHost tabHost = getTabHost(); final TabHost tabHost = getTabHost();
tabHost.addTab(tabHost.newTabSpec(MAP_TAB_TAG) tabHost.addTab(tabHost.newTabSpec(MAP_TAB_TAG)
@@ -189,138 +143,55 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
navControls.show(); navControls.show();
tabHost.addView(layout); tabHost.addView(layout);
layout.setOnTouchListener(this); layout.setOnTouchListener(this);
if (!EulaUtils.getEulaValue(this)) {
showDialog(DIALOG_EULA_ID);
}
} }
@Override @Override
protected void onStart() { protected void onStart() {
Log.d(TAG, "MyTracks.onStart");
super.onStart(); super.onStart();
dataHub.start(); trackDataHub.start();
// Ensure that service is running and bound if we're supposed to be recording // Ensure that service is running and bound if we're supposed to be recording
if (ServiceUtils.isRecording(this, null, preferences)) { if (ServiceUtils.isRecording(
serviceConnection.startAndBind(); this, trackRecordingServiceConnection.getServiceIfBound(), sharedPreferences)) {
trackRecordingServiceConnection.startAndBind();
} }
Intent intent = getIntent(); Intent intent = getIntent();
String action = intent.getAction(); long trackId = intent.getLongExtra(TRACK_ID, -1L);
Uri data = intent.getData(); if (trackId != -1L) {
if ((Intent.ACTION_VIEW.equals(action) || Intent.ACTION_EDIT.equals(action)) trackDataHub.loadTrack(trackId);
&& TracksColumns.CONTENT_ITEMTYPE.equals(intent.getType()) return;
&& UriUtils.matchesContentUri(data, TracksColumns.CONTENT_URI)) { }
long trackId = ContentUris.parseId(data);
dataHub.loadTrack(trackId); long waypointId = intent.getLongExtra(WAYPOINT_ID, -1L);
} else if (Intent.ACTION_VIEW.equals(action) if (waypointId != -1L) {
&& WaypointsColumns.CONTENT_ITEMTYPE.equals(intent.getType()) Waypoint waypoint = myTracksProviderUtils.getWaypoint(waypointId);
&& UriUtils.matchesContentUri(data, WaypointsColumns.CONTENT_URI)) { trackId = waypoint.getTrackId();
// TODO(rdamazio): Waypoint URIs should be base/trackid/waypointid
long waypointId = ContentUris.parseId(data);
Waypoint waypoint = providerUtils.getWaypoint(waypointId);
long trackId = waypoint.getTrackId();
// Request that the waypoint is shown (now or when the right track is loaded). // Request that the waypoint is shown (now or when the right track is loaded).
showWaypoint(trackId, waypointId); showWaypoint(trackId, waypointId);
// Load the right track, if not loaded already. // Load the right track, if not loaded already.
dataHub.loadTrack(trackId); trackDataHub.loadTrack(trackId);
} }
} }
@Override @Override
protected void onResume() { 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(); super.onResume();
} trackRecordingServiceConnection.bindIfRunning();
@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();
} }
@Override @Override
protected void onStop() { protected void onStop() {
Log.d(TAG, "MyTracks.onStop");
dataHub.stop();
super.onStop(); super.onStop();
trackDataHub.stop();
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
Log.d(TAG, "MyTracks.onDestroy");
serviceConnection.unbind();
super.onDestroy(); super.onDestroy();
} trackRecordingServiceConnection.unbind();
@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;
}
} }
@Override @Override
@@ -334,9 +205,9 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
MapActivity map = getMapTab(); MapActivity map = getMapTab();
boolean isSatelliteView = map != null ? map.isSatelliteView() : false; boolean isSatelliteView = map != null ? map.isSatelliteView() : false;
menuManager.onPrepareOptionsMenu(menu, providerUtils.getLastTrack() != null, menuManager.onPrepareOptionsMenu(menu, myTracksProviderUtils.getLastTrack() != null,
ServiceUtils.isRecording(this, serviceConnection.getServiceIfBound(), preferences), ServiceUtils.isRecording(this, trackRecordingServiceConnection.getServiceIfBound(), sharedPreferences),
dataHub.isATrackSelected(), trackDataHub.isATrackSelected(),
isSatelliteView, isSatelliteView,
getTabHost().getCurrentTabTag()); getTabHost().getCurrentTabTag());
@@ -350,15 +221,10 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
: super.onOptionsItemSelected(item); : super.onOptionsItemSelected(item);
} }
/*
* Key events:
* ===========
*/
@Override @Override
public boolean onTrackballEvent(MotionEvent event) { public boolean onTrackballEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) { if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (ServiceUtils.isRecording(this, serviceConnection.getServiceIfBound(), preferences)) { if (ServiceUtils.isRecording(this, trackRecordingServiceConnection.getServiceIfBound(), sharedPreferences)) {
try { try {
insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS); insertWaypoint(WaypointCreationRequest.DEFAULT_STATISTICS);
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -374,53 +240,19 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
} }
@Override @Override
public void onActivityResult(int requestCode, int resultCode, public void onActivityResult(int requestCode, int resultCode, final Intent results) {
final Intent results) { if (requestCode != Constants.SHOW_WAYPOINT) {
Log.d(TAG, "MyTracks.onActivityResult"); Log.d(TAG, "Warning unhandled request code: " + requestCode);
long trackId = dataHub.getSelectedTrackId(); return;
if (results != null) {
trackId = results.getLongExtra("trackid", trackId);
} }
if (results != null) {
switch (requestCode) { long waypointId = results.getLongExtra(WaypointDetails.WAYPOINT_ID_EXTRA, -1L);
case Constants.SHOW_TRACK: { if (waypointId != -1L) {
if (results != null) { MapActivity map = getMapTab();
if (trackId >= 0) { if (map != null) {
dataHub.loadTrack(trackId); getTabHost().setCurrentTab(0);
map.showWaypoint(waypointId);
// 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);
}
}
} }
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. * @throws RemoteException If the call on the service failed.
*/ */
private long insertWaypoint(WaypointCreationRequest request) throws RemoteException { private long insertWaypoint(WaypointCreationRequest request) throws RemoteException {
ITrackRecordingService trackRecordingService = serviceConnection.getServiceIfBound(); ITrackRecordingService trackRecordingService = trackRecordingServiceConnection.getServiceIfBound();
if (trackRecordingService == null) { if (trackRecordingService == null) {
throw new IllegalStateException("The recording service is not bound."); throw new IllegalStateException("The recording service is not bound.");
} }
@@ -474,7 +306,7 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
try { try {
long recordingTrackId = trackRecordingService.startNewTrack(); long recordingTrackId = trackRecordingService.startNewTrack();
// Select the recording track. // Select the recording track.
dataHub.loadTrack(recordingTrackId); trackDataHub.loadTrack(recordingTrackId);
Toast.makeText(this, getString(R.string.track_record_success), Toast.LENGTH_SHORT).show(); Toast.makeText(this, getString(R.string.track_record_success), Toast.LENGTH_SHORT).show();
// TODO: We catch Exception, because after eliminating the service process // TODO: We catch Exception, because after eliminating the service process
// all exceptions it may throw are no longer wrapped in a RemoteException. // 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. * it. Starts recording a new track.
*/ */
void startRecording() { void startRecording() {
synchronized (serviceConnection) { synchronized (trackRecordingServiceConnection) {
startNewTrackRequested = true; startNewTrackRequested = true;
serviceConnection.startAndBind(); trackRecordingServiceConnection.startAndBind();
// Binding was already requested before, it either already happened // Binding was already requested before, it either already happened
// (in which case running the callback manually triggers the actual recording start) // (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); Constants.SETTINGS_NAME, Context.MODE_PRIVATE);
long currentTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1); long currentTrackId = sharedPreferences.getLong(getString(R.string.recording_track_key), -1);
ITrackRecordingService trackRecordingService = serviceConnection.getServiceIfBound(); ITrackRecordingService trackRecordingService = trackRecordingServiceConnection.getServiceIfBound();
if (trackRecordingService != null) { if (trackRecordingService != null) {
try { try {
trackRecordingService.endCurrentTrack(); trackRecordingService.endCurrentTrack();
@@ -520,7 +352,7 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
} }
} }
serviceConnection.stop(); trackRecordingServiceConnection.stop();
if (currentTrackId > 0) { if (currentTrackId > 0) {
Intent intent = new Intent(this, TrackEditActivity.class) Intent intent = new Intent(this, TrackEditActivity.class)
@@ -531,7 +363,7 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
} }
long getSelectedTrackId() { long getSelectedTrackId() {
return dataHub.getSelectedTrackId(); return trackDataHub.getSelectedTrackId();
} }
/** /**
@@ -577,4 +409,4 @@ public class TrackDetailActivity extends TabActivity implements OnTouchListener
private ChartActivity getChartTab() { private ChartActivity getChartTab() {
return (ChartActivity) getLocalActivityManager().getActivity(CHART_TAB_TAG); return (ChartActivity) getLocalActivityManager().getActivity(CHART_TAB_TAG);
} }
} }
@@ -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.ServiceUtils;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection; import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.ApiAdapterFactory; 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.DialogUtils;
import com.google.android.apps.mytracks.util.EulaUtils;
import com.google.android.apps.mytracks.util.StringUtils; import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
@@ -37,8 +39,10 @@ import android.content.SharedPreferences.Editor;
import android.database.Cursor; import android.database.Cursor;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
import android.speech.tts.TextToSpeech;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader; import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader; import android.support.v4.content.Loader;
@@ -62,8 +66,13 @@ import android.widget.Toast;
public class TrackListActivity extends FragmentActivity { public class TrackListActivity extends FragmentActivity {
private static final String TAG = TrackListActivity.class.getSimpleName(); 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 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[] { private static final String[] PROJECTION = new String[] {
TracksColumns._ID, TracksColumns._ID,
TracksColumns.NAME, TracksColumns.NAME,
@@ -108,8 +117,10 @@ public class TrackListActivity extends FragmentActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
setContentView(R.layout.track_list); setContentView(R.layout.track_list);
trackRecordingServiceConnection = new TrackRecordingServiceConnection( trackRecordingServiceConnection = new TrackRecordingServiceConnection(
this, bindChangedCallback); this, bindChangedCallback);
@@ -138,8 +149,9 @@ public class TrackListActivity extends FragmentActivity {
listView.setOnItemClickListener(new OnItemClickListener() { listView.setOnItemClickListener(new OnItemClickListener() {
@Override @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
setResult(Constants.SHOW_TRACK, new Intent().putExtra("trackid", id)); Intent intent = new Intent(TrackListActivity.this, TrackDetailActivity.class)
finish(); .putExtra(TrackDetailActivity.TRACK_ID, id);
startActivity(intent);
} }
}); });
adapter = new ResourceCursorAdapter(this, R.layout.track_list_item, null, 0) { adapter = new ResourceCursorAdapter(this, R.layout.track_list_item, null, 0) {
@@ -205,13 +217,27 @@ public class TrackListActivity extends FragmentActivity {
adapter.swapCursor(null); adapter.swapCursor(null);
} }
}); });
if (!EulaUtils.getEulaValue(this)) {
new EulaDialogFragment().show(getSupportFragmentManager(), EULA_DIALOG_TAG);
}
} }
@Override @Override
protected void onStart() { protected void onStart() {
super.onStart(); super.onStart();
if (ServiceUtils.isRecording(
this, trackRecordingServiceConnection.getServiceIfBound(), sharedPreferences)) {
trackRecordingServiceConnection.startAndBind();
}
}
@Override
protected void onResume() {
super.onResume();
trackRecordingServiceConnection.bindIfRunning(); trackRecordingServiceConnection.bindIfRunning();
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
@@ -219,6 +245,23 @@ public class TrackListActivity extends FragmentActivity {
trackRecordingServiceConnection.unbind(); 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 @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.track_list, 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. * 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 @Override
public boolean onKeyUp(int keyCode, KeyEvent event) { public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_SEARCH) { if (keyCode == KeyEvent.KEYCODE_SEARCH) {
@@ -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);
}
}