Strong references in ETD listener, replaced SQLite junk with simple JSON file, annotation conversion
This commit is contained in:
parent
aaefc58702
commit
601d8516e6
@ -14,7 +14,7 @@
|
||||
android:targetSdkVersion="14" />
|
||||
|
||||
<application
|
||||
android:name=".BartRunnerApplication"
|
||||
android:name=".BartRunnerApplication_"
|
||||
android:icon="@drawable/icon"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
@ -61,17 +61,11 @@
|
||||
android:label="@string/system_map" >
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name=".data.BartContentProvider"
|
||||
android:authorities="com.dougkeen.bart.dataprovider"
|
||||
android:exported="false"
|
||||
android:label="BartRunner data provider" />
|
||||
|
||||
<service
|
||||
android:name=".services.BoardedDepartureService"
|
||||
android:exported="false" />
|
||||
<service
|
||||
android:name=".services.EtdService"
|
||||
android:name=".services.EtdService_"
|
||||
android:exported="false" />
|
||||
|
||||
<receiver
|
||||
|
BIN
libs/jackson-annotations-2.1.1.jar
Normal file
BIN
libs/jackson-annotations-2.1.1.jar
Normal file
Binary file not shown.
BIN
libs/jackson-core-2.1.2.jar
Normal file
BIN
libs/jackson-core-2.1.2.jar
Normal file
Binary file not shown.
BIN
libs/jackson-databind-2.1.0.jar
Normal file
BIN
libs/jackson-databind-2.1.0.jar
Normal file
Binary file not shown.
@ -16,21 +16,9 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/empty_favorites_list_message"
|
||||
android:visibility="gone" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1000" >
|
||||
|
||||
<ProgressBar
|
||||
style="?android:attr/progressBarStyleLarge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center" />
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/alertMessages"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -4,6 +4,7 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
@ -15,9 +16,16 @@ import android.media.MediaPlayer;
|
||||
import android.os.Parcel;
|
||||
import android.util.Log;
|
||||
|
||||
import com.dougkeen.bart.data.DatabaseHelper;
|
||||
import com.dougkeen.bart.data.FavoritesPersistence;
|
||||
import com.dougkeen.bart.model.Constants;
|
||||
import com.dougkeen.bart.model.Departure;
|
||||
import com.dougkeen.bart.model.Station;
|
||||
import com.dougkeen.bart.model.StationPair;
|
||||
import com.googlecode.androidannotations.annotations.Bean;
|
||||
import com.googlecode.androidannotations.annotations.EApplication;
|
||||
|
||||
@EApplication
|
||||
public class BartRunnerApplication extends Application {
|
||||
private static final int FIVE_MINUTES = 5 * 60 * 1000;
|
||||
|
||||
@ -33,6 +41,53 @@ public class BartRunnerApplication extends Application {
|
||||
|
||||
private static Context context;
|
||||
|
||||
@Bean
|
||||
FavoritesPersistence favoritesPersistenceContext;
|
||||
|
||||
private List<StationPair> favorites;
|
||||
|
||||
public void saveFavorites() {
|
||||
if (favorites != null) {
|
||||
favoritesPersistenceContext.persist(favorites);
|
||||
}
|
||||
}
|
||||
|
||||
public List<StationPair> getFavorites() {
|
||||
if (favorites == null) {
|
||||
favorites = favoritesPersistenceContext.restore();
|
||||
if (favorites.isEmpty()) {
|
||||
// Upgrade database, in case favorites are still in there
|
||||
new DatabaseHelper(this).getReadableDatabase().close();
|
||||
favorites = favoritesPersistenceContext.restore();
|
||||
}
|
||||
}
|
||||
return favorites;
|
||||
}
|
||||
|
||||
public void setFavorites(List<StationPair> favorites) {
|
||||
this.favorites = favorites;
|
||||
}
|
||||
|
||||
public StationPair getFavorite(Station origin, Station destination) {
|
||||
for (StationPair favorite : getFavorites()) {
|
||||
if (origin.equals(favorite.getOrigin())
|
||||
&& destination.equals(favorite.getDestination())) {
|
||||
return favorite;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addFavorite(StationPair favorite) {
|
||||
getFavorites().add(favorite);
|
||||
saveFavorites();
|
||||
}
|
||||
|
||||
public void removeFavorite(StationPair favorite) {
|
||||
getFavorites().remove(favorite);
|
||||
saveFavorites();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
@ -59,12 +114,13 @@ public class BartRunnerApplication extends Application {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(cachedDepartureFile);
|
||||
byte[] byteArray = IOUtils.toByteArray(inputStream);
|
||||
Parcel parcel = Parcel.obtain();
|
||||
final byte[] byteArray = IOUtils.toByteArray(inputStream);
|
||||
final Parcel parcel = Parcel.obtain();
|
||||
parcel.unmarshall(byteArray, 0, byteArray.length);
|
||||
parcel.setDataPosition(0);
|
||||
Departure lastBoardedDeparture = Departure.CREATOR
|
||||
.createFromParcel(parcel);
|
||||
parcel.recycle();
|
||||
|
||||
/*
|
||||
* Check if the cached one is relatively recent. If so,
|
||||
|
@ -29,6 +29,13 @@ public abstract class AbstractRouteSelectionFragment extends DialogFragment {
|
||||
mTitle = title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArguments(Bundle args) {
|
||||
super.setArguments(args);
|
||||
if (args.containsKey("title"))
|
||||
mTitle = args.getString("title");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -1,14 +1,12 @@
|
||||
package com.dougkeen.bart.activities;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import com.dougkeen.bart.BartRunnerApplication;
|
||||
import com.dougkeen.bart.R;
|
||||
import com.dougkeen.bart.data.RoutesColumns;
|
||||
import com.dougkeen.bart.model.Constants;
|
||||
import com.dougkeen.bart.model.Station;
|
||||
import com.dougkeen.bart.model.StationPair;
|
||||
|
||||
public class AddRouteDialogFragment extends AbstractRouteSelectionFragment {
|
||||
public AddRouteDialogFragment() {
|
||||
@ -16,10 +14,6 @@ public class AddRouteDialogFragment extends AbstractRouteSelectionFragment {
|
||||
R.string.add_route));
|
||||
}
|
||||
|
||||
public AddRouteDialogFragment(String title) {
|
||||
super(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
@ -29,22 +23,12 @@ public class AddRouteDialogFragment extends AbstractRouteSelectionFragment {
|
||||
|
||||
@Override
|
||||
protected void onOkButtonClick(Station origin, Station destination) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(RoutesColumns.FROM_STATION.string, origin.abbreviation);
|
||||
values.put(RoutesColumns.TO_STATION.string, destination.abbreviation);
|
||||
|
||||
getActivity().getContentResolver().insert(
|
||||
Constants.FAVORITE_CONTENT_URI, values);
|
||||
RoutesListActivity activity = (RoutesListActivity) getActivity();
|
||||
activity.addFavorite(new StationPair(origin, destination));
|
||||
|
||||
if (((CheckBox) getDialog().findViewById(R.id.return_checkbox))
|
||||
.isChecked()) {
|
||||
values = new ContentValues();
|
||||
values.put(RoutesColumns.FROM_STATION.string,
|
||||
destination.abbreviation);
|
||||
values.put(RoutesColumns.TO_STATION.string, origin.abbreviation);
|
||||
|
||||
getActivity().getContentResolver().insert(
|
||||
Constants.FAVORITE_CONTENT_URI, values);
|
||||
activity.addFavorite(new StationPair(destination, origin));
|
||||
}
|
||||
|
||||
dismiss();
|
||||
|
@ -14,10 +14,6 @@ public class QuickRouteDialogFragment extends AbstractRouteSelectionFragment {
|
||||
R.string.quick_departure_lookup));
|
||||
}
|
||||
|
||||
public QuickRouteDialogFragment(String title) {
|
||||
super(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onOkButtonClick(Station origin, Station destination) {
|
||||
startActivity(new Intent(Intent.ACTION_VIEW,
|
||||
|
@ -3,16 +3,10 @@ package com.dougkeen.bart.activities;
|
||||
import java.util.Calendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
@ -29,24 +23,24 @@ import com.actionbarsherlock.view.ActionMode;
|
||||
import com.actionbarsherlock.view.Menu;
|
||||
import com.actionbarsherlock.view.MenuInflater;
|
||||
import com.actionbarsherlock.view.MenuItem;
|
||||
import com.dougkeen.bart.BartRunnerApplication;
|
||||
import com.dougkeen.bart.R;
|
||||
import com.dougkeen.bart.controls.Ticker;
|
||||
import com.dougkeen.bart.controls.Ticker.TickSubscriber;
|
||||
import com.dougkeen.bart.data.CursorUtils;
|
||||
import com.dougkeen.bart.data.FavoritesArrayAdapter;
|
||||
import com.dougkeen.bart.data.RoutesColumns;
|
||||
import com.dougkeen.bart.model.Alert;
|
||||
import com.dougkeen.bart.model.Alert.AlertList;
|
||||
import com.dougkeen.bart.model.Constants;
|
||||
import com.dougkeen.bart.model.Station;
|
||||
import com.dougkeen.bart.model.StationPair;
|
||||
import com.dougkeen.bart.networktasks.AlertsClient;
|
||||
import com.dougkeen.bart.networktasks.ElevatorClient;
|
||||
import com.dougkeen.bart.networktasks.GetRouteFareTask;
|
||||
import com.googlecode.androidannotations.annotations.AfterViews;
|
||||
import com.googlecode.androidannotations.annotations.App;
|
||||
import com.googlecode.androidannotations.annotations.Background;
|
||||
import com.googlecode.androidannotations.annotations.Click;
|
||||
import com.googlecode.androidannotations.annotations.EActivity;
|
||||
import com.googlecode.androidannotations.annotations.InstanceState;
|
||||
import com.googlecode.androidannotations.annotations.ItemClick;
|
||||
import com.googlecode.androidannotations.annotations.ItemLongClick;
|
||||
import com.googlecode.androidannotations.annotations.UiThread;
|
||||
@ -54,24 +48,25 @@ import com.googlecode.androidannotations.annotations.ViewById;
|
||||
import com.googlecode.androidannotations.annotations.rest.RestService;
|
||||
|
||||
@EActivity(R.layout.main)
|
||||
public class RoutesListActivity extends SActivity implements
|
||||
LoaderCallbacks<Cursor>, TickSubscriber {
|
||||
public class RoutesListActivity extends SActivity implements TickSubscriber {
|
||||
private static final String NO_DELAYS_REPORTED = "No delays reported";
|
||||
|
||||
private static final int FAVORITES_LOADER_ID = 0;
|
||||
|
||||
private static final TimeZone PACIFIC_TIME = TimeZone
|
||||
.getTimeZone("America/Los_Angeles");
|
||||
|
||||
private Uri mCurrentlySelectedUri;
|
||||
@InstanceState
|
||||
StationPair mCurrentlySelectedStationPair;
|
||||
|
||||
private Station mCurrentlySelectedOrigin;
|
||||
private Station mCurrentlySelectedDestination;
|
||||
@InstanceState
|
||||
String mCurrentAlerts;
|
||||
|
||||
private ActionMode mActionMode;
|
||||
|
||||
private FavoritesArrayAdapter mRoutesAdapter;
|
||||
|
||||
@App
|
||||
BartRunnerApplication app;
|
||||
|
||||
@RestService
|
||||
AlertsClient alertsClient;
|
||||
|
||||
@ -89,16 +84,16 @@ public class RoutesListActivity extends SActivity implements
|
||||
|
||||
@Click(R.id.quickLookupButton)
|
||||
void quickLookupButtonClick() {
|
||||
DialogFragment dialog = new QuickRouteDialogFragment(
|
||||
getString(R.string.quick_departure_lookup));
|
||||
DialogFragment dialog = new QuickRouteDialogFragment();
|
||||
dialog.show(getSupportFragmentManager().beginTransaction());
|
||||
}
|
||||
|
||||
@ItemClick(android.R.id.list)
|
||||
void listItemClicked(StationPair item) {
|
||||
startActivity(new Intent(Intent.ACTION_VIEW,
|
||||
ContentUris.withAppendedId(Constants.FAVORITE_CONTENT_URI,
|
||||
item.getId())));
|
||||
Intent intent = new Intent(RoutesListActivity.this,
|
||||
ViewDeparturesActivity.class);
|
||||
intent.putExtra(Constants.STATION_PAIR_EXTRA, item);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
@ItemLongClick(android.R.id.list)
|
||||
@ -107,11 +102,7 @@ public class RoutesListActivity extends SActivity implements
|
||||
mActionMode.finish();
|
||||
}
|
||||
|
||||
mCurrentlySelectedUri = ContentUris.withAppendedId(
|
||||
Constants.FAVORITE_CONTENT_URI, item.getId());
|
||||
|
||||
mCurrentlySelectedOrigin = item.getOrigin();
|
||||
mCurrentlySelectedDestination = item.getDestination();
|
||||
mCurrentlySelectedStationPair = item;
|
||||
|
||||
startContextualActionMode();
|
||||
}
|
||||
@ -121,9 +112,7 @@ public class RoutesListActivity extends SActivity implements
|
||||
setTitle(R.string.favorite_routes);
|
||||
|
||||
mRoutesAdapter = new FavoritesArrayAdapter(this,
|
||||
R.layout.favorite_listing);
|
||||
|
||||
getSupportLoaderManager().initLoader(FAVORITES_LOADER_ID, null, this);
|
||||
R.layout.favorite_listing, app.getFavorites());
|
||||
|
||||
setListAdapter(mRoutesAdapter);
|
||||
|
||||
@ -132,6 +121,9 @@ public class RoutesListActivity extends SActivity implements
|
||||
if (mCurrentAlerts != null) {
|
||||
showAlertMessage(mCurrentAlerts);
|
||||
}
|
||||
|
||||
startEtdListeners();
|
||||
refreshFares();
|
||||
}
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@ -140,58 +132,14 @@ public class RoutesListActivity extends SActivity implements
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
if (savedInstanceState.getString("currentlySelectedOrigin") != null) {
|
||||
mCurrentlySelectedOrigin = Station
|
||||
.getByAbbreviation(savedInstanceState
|
||||
.getString("currentlySelectedOrigin"));
|
||||
}
|
||||
if (savedInstanceState.getString("currentlySelectedDestination") != null) {
|
||||
mCurrentlySelectedDestination = Station
|
||||
.getByAbbreviation(savedInstanceState
|
||||
.getString("currentlySelectedDestination"));
|
||||
}
|
||||
if (savedInstanceState.getParcelable("currentlySelectedUri") != null) {
|
||||
mCurrentlySelectedUri = (Uri) savedInstanceState
|
||||
.getParcelable("currentlySelectedUri");
|
||||
}
|
||||
if (savedInstanceState.getBoolean("hasActionMode")) {
|
||||
startContextualActionMode();
|
||||
}
|
||||
mCurrentAlerts = savedInstanceState.getString("currentAlerts");
|
||||
}
|
||||
|
||||
Ticker.getInstance().addSubscriber(this, getApplicationContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
return new CursorLoader(this, Constants.FAVORITE_CONTENT_URI,
|
||||
new String[] { RoutesColumns._ID.string,
|
||||
RoutesColumns.FROM_STATION.string,
|
||||
RoutesColumns.TO_STATION.string,
|
||||
RoutesColumns.FARE.string,
|
||||
RoutesColumns.FARE_LAST_UPDATED.string,
|
||||
RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string,
|
||||
RoutesColumns.AVERAGE_TRIP_LENGTH.string }, null, null,
|
||||
RoutesColumns._ID.string);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
|
||||
if (cursor.getCount() == 0) {
|
||||
((TextView) findViewById(android.R.id.empty))
|
||||
.setText(R.string.empty_favorites_list_message);
|
||||
}
|
||||
mRoutesAdapter.updateFromCursor(cursor);
|
||||
refreshFares(cursor);
|
||||
findViewById(R.id.progress).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> loader) {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
private AdapterView<ListAdapter> getListView() {
|
||||
return listView;
|
||||
}
|
||||
@ -205,70 +153,59 @@ public class RoutesListActivity extends SActivity implements
|
||||
getListView().setAdapter(mRoutesAdapter);
|
||||
}
|
||||
|
||||
private void refreshFares(Cursor cursor) {
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
final Station orig = Station.getByAbbreviation(CursorUtils
|
||||
.getString(cursor, RoutesColumns.FROM_STATION));
|
||||
final Station dest = Station.getByAbbreviation(CursorUtils
|
||||
.getString(cursor, RoutesColumns.TO_STATION));
|
||||
final Long id = CursorUtils.getLong(cursor, RoutesColumns._ID);
|
||||
final Long lastUpdateMillis = CursorUtils.getLong(cursor,
|
||||
RoutesColumns.FARE_LAST_UPDATED);
|
||||
void addFavorite(StationPair pair) {
|
||||
mRoutesAdapter.add(pair);
|
||||
}
|
||||
|
||||
Calendar now = Calendar.getInstance();
|
||||
Calendar lastUpdate = Calendar.getInstance();
|
||||
lastUpdate.setTimeInMillis(lastUpdateMillis);
|
||||
private void refreshFares() {
|
||||
for (int i = getListAdapter().getCount() - 1; i >= 0; i--) {
|
||||
final StationPair stationPair = getListAdapter().getItem(i);
|
||||
|
||||
now.setTimeZone(PACIFIC_TIME);
|
||||
lastUpdate.setTimeZone(PACIFIC_TIME);
|
||||
Calendar now = Calendar.getInstance();
|
||||
Calendar lastUpdate = Calendar.getInstance();
|
||||
lastUpdate.setTimeInMillis(stationPair.getFareLastUpdated());
|
||||
|
||||
// Update every day
|
||||
if (now.get(Calendar.DAY_OF_YEAR) != lastUpdate
|
||||
.get(Calendar.DAY_OF_YEAR)) {
|
||||
GetRouteFareTask fareTask = new GetRouteFareTask() {
|
||||
@Override
|
||||
public void onResult(String fare) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(RoutesColumns.FARE.string, fare);
|
||||
values.put(RoutesColumns.FARE_LAST_UPDATED.string,
|
||||
System.currentTimeMillis());
|
||||
now.setTimeZone(PACIFIC_TIME);
|
||||
lastUpdate.setTimeZone(PACIFIC_TIME);
|
||||
|
||||
getContentResolver()
|
||||
.update(ContentUris.withAppendedId(
|
||||
Constants.FAVORITE_CONTENT_URI, id),
|
||||
values, null, null);
|
||||
}
|
||||
// Update every day
|
||||
if (now.get(Calendar.DAY_OF_YEAR) != lastUpdate
|
||||
.get(Calendar.DAY_OF_YEAR)
|
||||
|| now.get(Calendar.YEAR) != lastUpdate.get(Calendar.YEAR)) {
|
||||
GetRouteFareTask fareTask = new GetRouteFareTask() {
|
||||
@Override
|
||||
public void onResult(String fare) {
|
||||
stationPair.setFare(fare);
|
||||
stationPair.setFareLastUpdated(System
|
||||
.currentTimeMillis());
|
||||
getListAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
// Ignore... we can do this later
|
||||
}
|
||||
};
|
||||
fareTask.execute(new GetRouteFareTask.Params(orig, dest));
|
||||
}
|
||||
} while (cursor.moveToNext());
|
||||
@Override
|
||||
public void onError(Exception exception) {
|
||||
// Ignore... we can do this later
|
||||
}
|
||||
};
|
||||
fareTask.execute(new GetRouteFareTask.Params(stationPair
|
||||
.getOrigin(), stationPair.getDestination()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if (mCurrentlySelectedOrigin != null)
|
||||
outState.putString("currentlySelectedOrigin",
|
||||
mCurrentlySelectedOrigin.abbreviation);
|
||||
if (mCurrentlySelectedDestination != null)
|
||||
outState.putString("currentlySelectedDestination",
|
||||
mCurrentlySelectedDestination.abbreviation);
|
||||
outState.putParcelable("currentlySelectedUri", mCurrentlySelectedUri);
|
||||
outState.putBoolean("hasActionMode", mActionMode != null);
|
||||
outState.putString("currentAlerts", mCurrentAlerts);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
Ticker.getInstance().startTicking(this);
|
||||
startEtdListeners();
|
||||
}
|
||||
|
||||
private void startEtdListeners() {
|
||||
if (mRoutesAdapter != null && !mRoutesAdapter.isEmpty()
|
||||
&& !mRoutesAdapter.areEtdListenersActive()) {
|
||||
mRoutesAdapter.setUpEtdListeners();
|
||||
@ -287,6 +224,8 @@ public class RoutesListActivity extends SActivity implements
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
Ticker.getInstance().stopTicking(this);
|
||||
app.saveFavorites();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -314,13 +253,11 @@ public class RoutesListActivity extends SActivity implements
|
||||
private MenuItem elevatorMenuItem;
|
||||
private View origElevatorActionView;
|
||||
|
||||
private String mCurrentAlerts;
|
||||
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == R.id.add_favorite_menu_button) {
|
||||
new AddRouteDialogFragment(getString(R.string.add_route))
|
||||
.show(getSupportFragmentManager().beginTransaction());
|
||||
new AddRouteDialogFragment().show(getSupportFragmentManager()
|
||||
.beginTransaction());
|
||||
return true;
|
||||
} else if (itemId == R.id.view_system_map_button) {
|
||||
startActivity(new Intent(this, ViewMapActivity.class));
|
||||
@ -393,7 +330,7 @@ public class RoutesListActivity extends SActivity implements
|
||||
|
||||
@UiThread
|
||||
void resetElevatorMenuGraphic() {
|
||||
invalidateOptionsMenu();
|
||||
ActivityCompat.invalidateOptionsMenu(this);
|
||||
elevatorMenuItem.setActionView(origElevatorActionView);
|
||||
}
|
||||
|
||||
@ -407,8 +344,9 @@ public class RoutesListActivity extends SActivity implements
|
||||
|
||||
private void startContextualActionMode() {
|
||||
mActionMode = startActionMode(new RouteActionMode());
|
||||
mActionMode.setTitle(mCurrentlySelectedOrigin.name);
|
||||
mActionMode.setSubtitle("to " + mCurrentlySelectedDestination.name);
|
||||
mActionMode.setTitle(mCurrentlySelectedStationPair.getOrigin().name);
|
||||
mActionMode.setSubtitle("to "
|
||||
+ mCurrentlySelectedStationPair.getDestination().name);
|
||||
}
|
||||
|
||||
private final class RouteActionMode implements ActionMode.Callback {
|
||||
@ -426,8 +364,11 @@ public class RoutesListActivity extends SActivity implements
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
if (item.getItemId() == R.id.view) {
|
||||
startActivity(new Intent(Intent.ACTION_VIEW,
|
||||
mCurrentlySelectedUri));
|
||||
Intent intent = new Intent(RoutesListActivity.this,
|
||||
ViewDeparturesActivity.class);
|
||||
intent.putExtra(Constants.STATION_PAIR_EXTRA,
|
||||
mCurrentlySelectedStationPair);
|
||||
startActivity(intent);
|
||||
mode.finish();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.delete) {
|
||||
@ -439,11 +380,9 @@ public class RoutesListActivity extends SActivity implements
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog,
|
||||
int which) {
|
||||
getContentResolver().delete(
|
||||
mCurrentlySelectedUri, null, null);
|
||||
mCurrentlySelectedUri = null;
|
||||
mCurrentlySelectedOrigin = null;
|
||||
mCurrentlySelectedDestination = null;
|
||||
getListAdapter().remove(
|
||||
mCurrentlySelectedStationPair);
|
||||
mCurrentlySelectedStationPair = null;
|
||||
mActionMode.finish();
|
||||
dialog.dismiss();
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.database.Cursor;
|
||||
import android.media.MediaPlayer;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
@ -18,9 +17,6 @@ import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Vibrator;
|
||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.util.Linkify;
|
||||
import android.util.Log;
|
||||
@ -44,27 +40,21 @@ import com.dougkeen.bart.controls.SwipeHelper;
|
||||
import com.dougkeen.bart.controls.Ticker;
|
||||
import com.dougkeen.bart.controls.YourTrainLayout;
|
||||
import com.dougkeen.bart.data.DepartureArrayAdapter;
|
||||
import com.dougkeen.bart.data.RoutesColumns;
|
||||
import com.dougkeen.bart.model.Constants;
|
||||
import com.dougkeen.bart.model.Departure;
|
||||
import com.dougkeen.bart.model.Station;
|
||||
import com.dougkeen.bart.model.StationPair;
|
||||
import com.dougkeen.bart.services.BoardedDepartureService;
|
||||
import com.dougkeen.bart.services.EtdService;
|
||||
import com.dougkeen.bart.services.EtdService.EtdServiceBinder;
|
||||
import com.dougkeen.bart.services.EtdService.EtdServiceListener;
|
||||
import com.dougkeen.bart.services.EtdService_;
|
||||
import com.dougkeen.util.Observer;
|
||||
import com.dougkeen.util.WakeLocker;
|
||||
|
||||
public class ViewDeparturesActivity extends SActivity implements
|
||||
EtdServiceListener {
|
||||
|
||||
private static final int LOADER_ID = 123;
|
||||
|
||||
private Uri mUri;
|
||||
|
||||
private Station mOrigin;
|
||||
private Station mDestination;
|
||||
private StationPair mStationPair;
|
||||
|
||||
private Departure mSelectedDeparture;
|
||||
|
||||
@ -89,64 +79,8 @@ public class ViewDeparturesActivity extends SActivity implements
|
||||
|
||||
final Intent intent = getIntent();
|
||||
|
||||
String action = intent.getAction();
|
||||
|
||||
if (Intent.ACTION_VIEW.equals(action)) {
|
||||
mUri = intent.getData();
|
||||
}
|
||||
|
||||
final Uri uri = mUri;
|
||||
|
||||
final BartRunnerApplication bartRunnerApplication = (BartRunnerApplication) getApplication();
|
||||
|
||||
if (savedInstanceState != null
|
||||
&& savedInstanceState.containsKey("origin")
|
||||
&& savedInstanceState.containsKey("destination")) {
|
||||
mOrigin = Station.getByAbbreviation(savedInstanceState
|
||||
.getString("origin"));
|
||||
mDestination = Station.getByAbbreviation(savedInstanceState
|
||||
.getString("destination"));
|
||||
setListTitle();
|
||||
} else {
|
||||
getSupportLoaderManager().initLoader(LOADER_ID, null,
|
||||
new LoaderCallbacks<Cursor>() {
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
return new CursorLoader(
|
||||
ViewDeparturesActivity.this, uri,
|
||||
new String[] {
|
||||
RoutesColumns.FROM_STATION.string,
|
||||
RoutesColumns.TO_STATION.string },
|
||||
null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> loader,
|
||||
Cursor cursor) {
|
||||
if (!cursor.moveToFirst()) {
|
||||
Log.wtf(Constants.TAG,
|
||||
"Couldn't find Route record for the current Activity");
|
||||
}
|
||||
mOrigin = Station.getByAbbreviation(cursor
|
||||
.getString(0));
|
||||
mDestination = Station.getByAbbreviation(cursor
|
||||
.getString(1));
|
||||
setListTitle();
|
||||
if (mBound && mEtdService != null)
|
||||
mEtdService.registerListener(
|
||||
ViewDeparturesActivity.this, false);
|
||||
refreshBoardedDeparture(false);
|
||||
|
||||
getSupportLoaderManager().destroyLoader(LOADER_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> loader) {
|
||||
// ignore
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mEmptyView = (TextView) findViewById(android.R.id.empty);
|
||||
mEmptyView.setText(R.string.departure_wait_message);
|
||||
|
||||
@ -155,6 +89,43 @@ public class ViewDeparturesActivity extends SActivity implements
|
||||
mDeparturesAdapter = new DepartureArrayAdapter(this,
|
||||
R.layout.departure_listing);
|
||||
|
||||
setListAdapter(mDeparturesAdapter);
|
||||
final ListView listView = getListView();
|
||||
listView.setEmptyView(findViewById(android.R.id.empty));
|
||||
listView.setOnItemClickListener(mListItemClickListener);
|
||||
listView.setOnItemLongClickListener(mListItemLongClickListener);
|
||||
|
||||
mMissingDepartureText = findViewById(R.id.missingDepartureText);
|
||||
mMissingDepartureText.setVisibility(View.VISIBLE);
|
||||
|
||||
mYourTrainSection = (YourTrainLayout) findViewById(R.id.yourTrainSection);
|
||||
mYourTrainSection.setOnClickListener(mYourTrainSectionClickListener);
|
||||
mSwipeHelper = new SwipeHelper(mYourTrainSection, null,
|
||||
new SwipeHelper.OnDismissCallback() {
|
||||
@Override
|
||||
public void onDismiss(View view, Object token) {
|
||||
dismissYourTrainSelection();
|
||||
if (mActionMode != null) {
|
||||
mActionMode.finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
mYourTrainSection.setOnTouchListener(mSwipeHelper);
|
||||
|
||||
if (savedInstanceState != null
|
||||
&& savedInstanceState.containsKey("stationPair")) {
|
||||
mStationPair = savedInstanceState.getParcelable("stationPair");
|
||||
setListTitle();
|
||||
} else {
|
||||
mStationPair = intent.getExtras().getParcelable(
|
||||
Constants.STATION_PAIR_EXTRA);
|
||||
setListTitle();
|
||||
if (mBound && mEtdService != null)
|
||||
mEtdService
|
||||
.registerListener(ViewDeparturesActivity.this, false);
|
||||
refreshBoardedDeparture(false);
|
||||
}
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
if (savedInstanceState.containsKey("departures")) {
|
||||
for (Parcelable departure : savedInstanceState
|
||||
@ -178,29 +149,6 @@ public class ViewDeparturesActivity extends SActivity implements
|
||||
startYourTrainActionMode();
|
||||
}
|
||||
}
|
||||
setListAdapter(mDeparturesAdapter);
|
||||
final ListView listView = getListView();
|
||||
listView.setEmptyView(findViewById(android.R.id.empty));
|
||||
listView.setOnItemClickListener(mListItemClickListener);
|
||||
listView.setOnItemLongClickListener(mListItemLongClickListener);
|
||||
|
||||
mMissingDepartureText = findViewById(R.id.missingDepartureText);
|
||||
mMissingDepartureText.setVisibility(View.VISIBLE);
|
||||
|
||||
mYourTrainSection = (YourTrainLayout) findViewById(R.id.yourTrainSection);
|
||||
mYourTrainSection.setOnClickListener(mYourTrainSectionClickListener);
|
||||
mSwipeHelper = new SwipeHelper(mYourTrainSection, null,
|
||||
new SwipeHelper.OnDismissCallback() {
|
||||
@Override
|
||||
public void onDismiss(View view, Object token) {
|
||||
dismissYourTrainSelection();
|
||||
if (mActionMode != null) {
|
||||
mActionMode.finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
mYourTrainSection.setOnTouchListener(mSwipeHelper);
|
||||
|
||||
refreshBoardedDeparture(false);
|
||||
|
||||
getSupportActionBar().setHomeButtonEnabled(true);
|
||||
@ -297,8 +245,9 @@ public class ViewDeparturesActivity extends SActivity implements
|
||||
}
|
||||
|
||||
private void setListTitle() {
|
||||
((TextView) findViewById(R.id.listTitle)).setText(mOrigin.name + " to "
|
||||
+ mDestination.name);
|
||||
((TextView) findViewById(R.id.listTitle))
|
||||
.setText(mStationPair.getOrigin().name + " to "
|
||||
+ mStationPair.getDestination().name);
|
||||
}
|
||||
|
||||
private ListView getListView() {
|
||||
@ -399,7 +348,7 @@ public class ViewDeparturesActivity extends SActivity implements
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if (mOrigin != null || mDestination != null) {
|
||||
if (mStationPair != null) {
|
||||
/*
|
||||
* If origin or destination are null, this thing was never
|
||||
* initialized in the first place, so there's really nothing to save
|
||||
@ -415,15 +364,14 @@ public class ViewDeparturesActivity extends SActivity implements
|
||||
isDepartureActionModeActive());
|
||||
outState.putBoolean("hasYourTrainActionMode",
|
||||
isYourTrainActionModeActive());
|
||||
outState.putString("origin", mOrigin.abbreviation);
|
||||
outState.putString("destination", mDestination.abbreviation);
|
||||
outState.putParcelable("stationPair", mStationPair);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
bindService(new Intent(this, EtdService.class), mConnection,
|
||||
bindService(EtdService_.intent(this).get(), mConnection,
|
||||
Context.BIND_AUTO_CREATE);
|
||||
Ticker.getInstance().startTicking(this);
|
||||
}
|
||||
@ -459,10 +407,8 @@ public class ViewDeparturesActivity extends SActivity implements
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == android.R.id.home) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW,
|
||||
Constants.FAVORITE_CONTENT_URI);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
startActivity(intent);
|
||||
RoutesListActivity_.intent(this)
|
||||
.flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start();
|
||||
return true;
|
||||
} else if (itemId == R.id.view_on_bart_site_button) {
|
||||
startActivity(new Intent(
|
||||
@ -471,9 +417,9 @@ public class ViewDeparturesActivity extends SActivity implements
|
||||
+ DateFormat.format("h:mmaa",
|
||||
System.currentTimeMillis())
|
||||
+ "&orig="
|
||||
+ mOrigin.abbreviation
|
||||
+ mStationPair.getOrigin().abbreviation
|
||||
+ "&dest="
|
||||
+ mDestination.abbreviation)));
|
||||
+ mStationPair.getDestination().abbreviation)));
|
||||
return true;
|
||||
} else if (itemId == R.id.view_system_map_button) {
|
||||
startActivity(new Intent(this, ViewMapActivity.class));
|
||||
@ -508,13 +454,16 @@ public class ViewDeparturesActivity extends SActivity implements
|
||||
|
||||
private void setBoardedDeparture(Departure selectedDeparture) {
|
||||
final BartRunnerApplication application = (BartRunnerApplication) getApplication();
|
||||
selectedDeparture.setPassengerDestination(mDestination);
|
||||
selectedDeparture
|
||||
.setPassengerDestination(mStationPair.getDestination());
|
||||
application.setBoardedDeparture(selectedDeparture);
|
||||
refreshBoardedDeparture(true);
|
||||
|
||||
// Start the notification service
|
||||
startService(new Intent(ViewDeparturesActivity.this,
|
||||
BoardedDepartureService.class));
|
||||
final Intent intent = new Intent(ViewDeparturesActivity.this,
|
||||
BoardedDepartureService.class);
|
||||
intent.putExtra("departure", selectedDeparture);
|
||||
startService(intent);
|
||||
}
|
||||
|
||||
private void startDepartureActionMode() {
|
||||
@ -815,9 +764,7 @@ public class ViewDeparturesActivity extends SActivity implements
|
||||
|
||||
@Override
|
||||
public StationPair getStationPair() {
|
||||
if (mOrigin == null || mDestination == null)
|
||||
return null;
|
||||
return new StationPair(mOrigin, mDestination);
|
||||
return mStationPair;
|
||||
}
|
||||
|
||||
private void hideYourTrainSection() {
|
||||
|
@ -1,271 +0,0 @@
|
||||
package com.dougkeen.bart.data;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.UriMatcher;
|
||||
import android.database.Cursor;
|
||||
import android.database.MatrixCursor;
|
||||
import android.database.MatrixCursor.RowBuilder;
|
||||
import android.database.SQLException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteQueryBuilder;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.dougkeen.bart.model.Constants;
|
||||
|
||||
public class BartContentProvider extends ContentProvider {
|
||||
|
||||
private static final UriMatcher sUriMatcher;
|
||||
private static HashMap<String, String> sFavoritesProjectionMap;
|
||||
|
||||
private static final int FAVORITES = 1;
|
||||
private static final int FAVORITE_ID = 2;
|
||||
private static final int ARBITRARY_ROUTE = 3;
|
||||
private static final int ARBITRARY_ROUTE_UNDEFINED = 4;
|
||||
|
||||
/**
|
||||
* The default sort order for events
|
||||
*/
|
||||
private static final String DEFAULT_SORT_ORDER = RoutesColumns.FROM_STATION.string
|
||||
+ " DESC";
|
||||
|
||||
static {
|
||||
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||
sUriMatcher.addURI(Constants.AUTHORITY, "favorites", FAVORITES);
|
||||
sUriMatcher.addURI(Constants.AUTHORITY, "favorites/#", FAVORITE_ID);
|
||||
sUriMatcher.addURI(Constants.AUTHORITY, "route/*/*", ARBITRARY_ROUTE);
|
||||
sUriMatcher.addURI(Constants.AUTHORITY, "route",
|
||||
ARBITRARY_ROUTE_UNDEFINED);
|
||||
|
||||
sFavoritesProjectionMap = new HashMap<String, String>();
|
||||
sFavoritesProjectionMap.put(RoutesColumns._ID.string,
|
||||
RoutesColumns._ID.string);
|
||||
sFavoritesProjectionMap.put(RoutesColumns.FROM_STATION.string,
|
||||
RoutesColumns.FROM_STATION.string);
|
||||
sFavoritesProjectionMap.put(RoutesColumns.TO_STATION.string,
|
||||
RoutesColumns.TO_STATION.string);
|
||||
sFavoritesProjectionMap.put(RoutesColumns.FARE.string,
|
||||
RoutesColumns.FARE.string);
|
||||
sFavoritesProjectionMap.put(RoutesColumns.FARE_LAST_UPDATED.string,
|
||||
RoutesColumns.FARE_LAST_UPDATED.string);
|
||||
sFavoritesProjectionMap.put(
|
||||
RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string,
|
||||
RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string);
|
||||
sFavoritesProjectionMap.put(RoutesColumns.AVERAGE_TRIP_LENGTH.string,
|
||||
RoutesColumns.AVERAGE_TRIP_LENGTH.string);
|
||||
}
|
||||
|
||||
private DatabaseHelper mDatabaseHelper;
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
mDatabaseHelper = new DatabaseHelper(getContext());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri uri) {
|
||||
int match = sUriMatcher.match(uri);
|
||||
if (match == FAVORITES) {
|
||||
return Constants.FAVORITE_CONTENT_TYPE;
|
||||
} else if (match == FAVORITE_ID) {
|
||||
return Constants.FAVORITE_CONTENT_ITEM_TYPE;
|
||||
} else if (match == ARBITRARY_ROUTE) {
|
||||
return Constants.ARBITRARY_ROUTE_TYPE;
|
||||
} else if (match == ARBITRARY_ROUTE_UNDEFINED) {
|
||||
return Constants.ARBITRARY_ROUTE_UNDEFINED_TYPE;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown URI " + uri);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(Uri uri, String[] projection, String selection,
|
||||
String[] selectionArgs, String sortOrder) {
|
||||
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
|
||||
|
||||
SQLiteDatabase db = mDatabaseHelper.getReadableDatabase();
|
||||
|
||||
String orderBy = sortOrder;
|
||||
|
||||
int match = sUriMatcher.match(uri);
|
||||
|
||||
if (match == ARBITRARY_ROUTE) {
|
||||
final String origin = uri.getPathSegments().get(1);
|
||||
final String destination = uri.getPathSegments().get(2);
|
||||
|
||||
qb.setTables(DatabaseHelper.FAVORITES_TABLE_NAME);
|
||||
qb.setProjectionMap(sFavoritesProjectionMap);
|
||||
qb.appendWhere(String.format("%s = '%s' AND %s = '%s'",
|
||||
RoutesColumns.FROM_STATION, origin,
|
||||
RoutesColumns.TO_STATION, destination));
|
||||
Cursor query = qb.query(db, projection, selection, selectionArgs,
|
||||
null, null, sortOrder);
|
||||
if (query.getCount() > 0)
|
||||
return query;
|
||||
|
||||
MatrixCursor returnCursor = new MatrixCursor(projection);
|
||||
RowBuilder newRow = returnCursor.newRow();
|
||||
|
||||
for (String column : projection) {
|
||||
if (column.equals(RoutesColumns.FROM_STATION.string)) {
|
||||
newRow.add(origin);
|
||||
} else if (column.equals(RoutesColumns.TO_STATION.string)) {
|
||||
newRow.add(destination);
|
||||
} else {
|
||||
newRow.add(null);
|
||||
}
|
||||
}
|
||||
|
||||
return returnCursor;
|
||||
} else if (match == FAVORITE_ID) {
|
||||
qb.setTables(DatabaseHelper.FAVORITES_TABLE_NAME);
|
||||
qb.setProjectionMap(sFavoritesProjectionMap);
|
||||
qb.appendWhere(RoutesColumns._ID + " = "
|
||||
+ uri.getPathSegments().get(1));
|
||||
} else if (match == FAVORITES) {
|
||||
qb.setTables(DatabaseHelper.FAVORITES_TABLE_NAME);
|
||||
qb.setProjectionMap(sFavoritesProjectionMap);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown URI " + uri);
|
||||
}
|
||||
|
||||
// If no sort order is specified use the default
|
||||
if (TextUtils.isEmpty(orderBy)) {
|
||||
orderBy = DEFAULT_SORT_ORDER;
|
||||
}
|
||||
|
||||
// Get the database and run the query
|
||||
Cursor cursor = qb.query(db, projection, selection, selectionArgs,
|
||||
null, null, orderBy);
|
||||
|
||||
// Tell the cursor what uri to watch, so it knows when its source data
|
||||
// changes
|
||||
cursor.setNotificationUri(getContext().getContentResolver(), uri);
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri uri, ContentValues initialValues) {
|
||||
ContentValues values;
|
||||
if (initialValues != null) {
|
||||
values = new ContentValues(initialValues);
|
||||
} else {
|
||||
values = new ContentValues();
|
||||
}
|
||||
|
||||
SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
|
||||
|
||||
// Validate the requested uri
|
||||
int match = sUriMatcher.match(uri);
|
||||
if (match == FAVORITES) {
|
||||
long rowId = -1;
|
||||
Cursor cursor = db
|
||||
.query(DatabaseHelper.FAVORITES_TABLE_NAME,
|
||||
new String[] { RoutesColumns._ID.string },
|
||||
RoutesColumns.FROM_STATION + "=? AND "
|
||||
+ RoutesColumns.TO_STATION + "=?",
|
||||
new String[] {
|
||||
values.getAsString(RoutesColumns.FROM_STATION.string),
|
||||
values.getAsString(RoutesColumns.TO_STATION.string) },
|
||||
null, null, null);
|
||||
try {
|
||||
if (cursor.moveToFirst()) {
|
||||
rowId = cursor.getLong(0);
|
||||
}
|
||||
} finally {
|
||||
CursorUtils.closeCursorQuietly(cursor);
|
||||
}
|
||||
if (rowId < 0) {
|
||||
rowId = db.insert(DatabaseHelper.FAVORITES_TABLE_NAME,
|
||||
RoutesColumns.FROM_STATION.string, values);
|
||||
}
|
||||
if (rowId > 0) {
|
||||
Uri eventUri = ContentUris.withAppendedId(
|
||||
Constants.FAVORITE_CONTENT_URI, rowId);
|
||||
getContext().getContentResolver().notifyChange(eventUri, null,
|
||||
false);
|
||||
return eventUri;
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown URI " + uri);
|
||||
}
|
||||
|
||||
throw new SQLException("Failed to insert row into " + uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri uri, ContentValues values, String where,
|
||||
String[] whereArgs) {
|
||||
SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
|
||||
|
||||
// Validate the requested uri
|
||||
int match = sUriMatcher.match(uri);
|
||||
if (match == FAVORITE_ID) {
|
||||
String favoriteId = uri.getPathSegments().get(1);
|
||||
int count = db.update(
|
||||
DatabaseHelper.FAVORITES_TABLE_NAME,
|
||||
values,
|
||||
RoutesColumns._ID
|
||||
+ " = "
|
||||
+ favoriteId
|
||||
+ (!TextUtils.isEmpty(where) ? " AND (" + where
|
||||
+ ')' : ""), whereArgs);
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
return count;
|
||||
} else if (match == ARBITRARY_ROUTE) {
|
||||
// Get the route with the origin and destination provided, and
|
||||
// simply delegate to the previous log branch. If the given route
|
||||
// doesn't exist, do nothing.
|
||||
String origin = uri.getPathSegments().get(1);
|
||||
String destination = uri.getPathSegments().get(2);
|
||||
|
||||
Cursor query = db.query(DatabaseHelper.FAVORITES_TABLE_NAME,
|
||||
new String[] { RoutesColumns._ID.string },
|
||||
RoutesColumns.FROM_STATION.string + "=? AND "
|
||||
+ RoutesColumns.TO_STATION.string + "=?",
|
||||
new String[] { origin, destination }, null, null, null);
|
||||
|
||||
try {
|
||||
if (query.moveToFirst()) {
|
||||
return update(ContentUris.withAppendedId(
|
||||
Constants.FAVORITE_CONTENT_URI, query.getLong(0)),
|
||||
values, where, whereArgs);
|
||||
}
|
||||
} finally {
|
||||
CursorUtils.closeCursorQuietly(query);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(Uri uri, String where, String[] whereArgs) {
|
||||
// TODO: Sync with REST service?
|
||||
SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
|
||||
int count;
|
||||
int match = sUriMatcher.match(uri);
|
||||
if (match == FAVORITES) {
|
||||
count = db.delete(DatabaseHelper.FAVORITES_TABLE_NAME, where,
|
||||
whereArgs);
|
||||
} else if (match == FAVORITE_ID) {
|
||||
String favoriteId = uri.getPathSegments().get(1);
|
||||
count = db.delete(
|
||||
DatabaseHelper.FAVORITES_TABLE_NAME,
|
||||
RoutesColumns._ID
|
||||
+ " = "
|
||||
+ favoriteId
|
||||
+ (!TextUtils.isEmpty(where) ? " AND (" + where
|
||||
+ ')' : ""), whereArgs);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown URI " + uri);
|
||||
}
|
||||
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
return count;
|
||||
}
|
||||
}
|
@ -20,4 +20,8 @@ public final class CursorUtils {
|
||||
public static final Long getLong(Cursor cursor, RoutesColumns column) {
|
||||
return cursor.getLong(cursor.getColumnIndex(column.string));
|
||||
}
|
||||
|
||||
public static final Integer getInteger(Cursor cursor, RoutesColumns column) {
|
||||
return cursor.getInt(cursor.getColumnIndex(column.string));
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,32 @@
|
||||
package com.dougkeen.bart.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.dougkeen.bart.BartRunnerApplication;
|
||||
import com.dougkeen.bart.model.StationPair;
|
||||
|
||||
public class DatabaseHelper extends SQLiteOpenHelper {
|
||||
|
||||
private static final String DATABASE_NAME = "bart.dougkeen.db";
|
||||
private static final int DATABASE_VERSION = 4;
|
||||
private static final int DATABASE_VERSION = 6;
|
||||
|
||||
public static final String FAVORITES_TABLE_NAME = "Favorites";
|
||||
|
||||
private BartRunnerApplication app;
|
||||
|
||||
public DatabaseHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
app = (BartRunnerApplication) context.getApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
createFavoritesTable(db);
|
||||
}
|
||||
|
||||
private void createFavoritesTable(SQLiteDatabase db) {
|
||||
@ -45,54 +46,24 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
||||
try {
|
||||
createFavoritesTable(db);
|
||||
|
||||
List<String> columns = getColumns(db, FAVORITES_TABLE_NAME);
|
||||
Cursor query = db.query(FAVORITES_TABLE_NAME, RoutesColumns.all(),
|
||||
null, null, null, null, null);
|
||||
|
||||
db.execSQL("ALTER TABLE " + FAVORITES_TABLE_NAME
|
||||
+ " RENAME TO temp_" + FAVORITES_TABLE_NAME);
|
||||
List<StationPair> favorites = new ArrayList<StationPair>();
|
||||
|
||||
createFavoritesTable(db);
|
||||
while (query.moveToNext()) {
|
||||
favorites.add(StationPair.createFromCursor(query));
|
||||
}
|
||||
|
||||
columns.retainAll(getColumns(db, FAVORITES_TABLE_NAME));
|
||||
query.close();
|
||||
|
||||
String cols = StringUtils.join(columns, ",");
|
||||
db.execSQL(String.format(
|
||||
"INSERT INTO %s (%s) SELECT %s from temp_%s",
|
||||
FAVORITES_TABLE_NAME, cols, cols, FAVORITES_TABLE_NAME));
|
||||
new FavoritesPersistence(app).persist(favorites);
|
||||
|
||||
db.execSQL("DROP TABLE temp_" + FAVORITES_TABLE_NAME);
|
||||
db.execSQL("DROP TABLE " + FAVORITES_TABLE_NAME);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> getColumns(SQLiteDatabase db, String tableName) {
|
||||
List<String> ar = null;
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = db.rawQuery("select * from " + tableName + " limit 1", null);
|
||||
if (c != null) {
|
||||
ar = new ArrayList<String>(Arrays.asList(c.getColumnNames()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.v(tableName, e.getMessage(), e);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (c != null)
|
||||
c.close();
|
||||
}
|
||||
return ar;
|
||||
}
|
||||
|
||||
public static String join(List<String> list, String delim) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
int num = list.size();
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (i != 0)
|
||||
buf.append(delim);
|
||||
buf.append((String) list.get(i));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.database.Cursor;
|
||||
import android.os.IBinder;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@ -32,6 +30,7 @@ import com.dougkeen.bart.model.TextProvider;
|
||||
import com.dougkeen.bart.services.EtdService;
|
||||
import com.dougkeen.bart.services.EtdService.EtdServiceBinder;
|
||||
import com.dougkeen.bart.services.EtdService.EtdServiceListener;
|
||||
import com.dougkeen.bart.services.EtdService_;
|
||||
|
||||
public class FavoritesArrayAdapter extends ArrayAdapter<StationPair> {
|
||||
|
||||
@ -82,10 +81,11 @@ public class FavoritesArrayAdapter extends ArrayAdapter<StationPair> {
|
||||
return !mEtdListeners.isEmpty();
|
||||
}
|
||||
|
||||
public FavoritesArrayAdapter(Context context, int textViewResourceId) {
|
||||
super(context, textViewResourceId);
|
||||
public FavoritesArrayAdapter(Context context, int textViewResourceId,
|
||||
List<StationPair> objects) {
|
||||
super(context, textViewResourceId, objects);
|
||||
mHostActivity = (Activity) context;
|
||||
mHostActivity.bindService(new Intent(mHostActivity, EtdService.class),
|
||||
mHostActivity.bindService(EtdService_.intent(mHostActivity).get(),
|
||||
mConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
@ -118,42 +118,6 @@ public class FavoritesArrayAdapter extends ArrayAdapter<StationPair> {
|
||||
clearEtdListeners();
|
||||
}
|
||||
|
||||
public void updateFromCursor(Cursor cursor) {
|
||||
if (!cursor.moveToFirst()) {
|
||||
clear();
|
||||
}
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
StationPair adapterItem = getItem(i);
|
||||
if (cursor.isAfterLast()) {
|
||||
while (i < getCount()) {
|
||||
remove(getItem(i));
|
||||
}
|
||||
} else {
|
||||
StationPair cursorItem = StationPair.createFromCursor(cursor);
|
||||
while (!cursorItem.equals(adapterItem)) {
|
||||
remove(adapterItem);
|
||||
if (i < getCount()) {
|
||||
adapterItem = getItem(i);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cursorItem.equals(adapterItem)
|
||||
&& !cursorItem.fareEquals(adapterItem)) {
|
||||
adapterItem.setFare(cursorItem.getFare());
|
||||
adapterItem.setFareLastUpdated(cursorItem
|
||||
.getFareLastUpdated());
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
cursor.moveToNext();
|
||||
}
|
||||
}
|
||||
while (!cursor.isAfterLast()) {
|
||||
add(StationPair.createFromCursor(cursor));
|
||||
cursor.moveToNext();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View view;
|
||||
|
63
src/com/dougkeen/bart/data/FavoritesPersistence.java
Normal file
63
src/com/dougkeen/bart/data/FavoritesPersistence.java
Normal file
@ -0,0 +1,63 @@
|
||||
package com.dougkeen.bart.data;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.dougkeen.bart.BartRunnerApplication;
|
||||
import com.dougkeen.bart.model.StationPair;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.googlecode.androidannotations.annotations.EBean;
|
||||
|
||||
@EBean
|
||||
public class FavoritesPersistence {
|
||||
private static final String TAG = "FavoritesPersistence";
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private BartRunnerApplication app;
|
||||
|
||||
public FavoritesPersistence(Context context) {
|
||||
app = (BartRunnerApplication) context.getApplicationContext();
|
||||
}
|
||||
|
||||
public void persist(List<StationPair> favorites) {
|
||||
FileOutputStream outputStream = null;
|
||||
try {
|
||||
outputStream = app
|
||||
.openFileOutput("favorites", Context.MODE_PRIVATE);
|
||||
objectMapper.writeValue(outputStream, favorites);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Could not write favorites file", e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(outputStream);
|
||||
}
|
||||
}
|
||||
|
||||
public List<StationPair> restore() {
|
||||
for (String file : app.fileList()) {
|
||||
if ("favorites".equals(file)) {
|
||||
FileInputStream inputStream = null;
|
||||
try {
|
||||
inputStream = app.openFileInput("favorites");
|
||||
return objectMapper.readValue(inputStream,
|
||||
new TypeReference<ArrayList<StationPair>>() {
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Could not read favorites file", e);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<StationPair>();
|
||||
}
|
||||
}
|
@ -1,14 +1,11 @@
|
||||
package com.dougkeen.bart.data;
|
||||
|
||||
|
||||
public enum RoutesColumns {
|
||||
_ID("_id", "INTEGER", false),
|
||||
FROM_STATION("FROM_STATION", "TEXT", false),
|
||||
TO_STATION("TO_STATION", "TEXT", false),
|
||||
FARE("FARE", "TEXT", true),
|
||||
FARE_LAST_UPDATED("FARE_LAST_UPDATED", "INTEGER", true),
|
||||
AVERAGE_TRIP_SAMPLE_COUNT("AVE_TRIP_SAMPLE_COUNT", "INTEGER", true),
|
||||
AVERAGE_TRIP_LENGTH("AVE_TRIP_LENGTH", "INTEGER", true);
|
||||
_ID("_id", "INTEGER", false), FROM_STATION("FROM_STATION", "TEXT", false), TO_STATION(
|
||||
"TO_STATION", "TEXT", false), FARE("FARE", "TEXT", true), FARE_LAST_UPDATED(
|
||||
"FARE_LAST_UPDATED", "INTEGER", true), AVERAGE_TRIP_SAMPLE_COUNT(
|
||||
"AVE_TRIP_SAMPLE_COUNT", "INTEGER", true), AVERAGE_TRIP_LENGTH(
|
||||
"AVE_TRIP_LENGTH", "INTEGER", true);
|
||||
|
||||
// This class cannot be instantiated
|
||||
private RoutesColumns(String string, String type, Boolean nullable) {
|
||||
@ -24,4 +21,13 @@ public enum RoutesColumns {
|
||||
protected String getColumnDef() {
|
||||
return string + " " + sqliteType + (nullable ? "" : " NOT NULL");
|
||||
}
|
||||
|
||||
public static String[] all() {
|
||||
final RoutesColumns[] values = RoutesColumns.values();
|
||||
String[] returnArray = new String[values.length];
|
||||
for (int i = values.length - 1; i >= 0; i--) {
|
||||
returnArray[i] = values[i].string;
|
||||
}
|
||||
return returnArray;
|
||||
}
|
||||
}
|
||||
|
@ -17,4 +17,5 @@ public class Constants {
|
||||
public static final String TAG = "com.dougkeen.BartRunner";
|
||||
public static final String API_KEY = "5LD9-IAYI-TRAT-MHHW";
|
||||
public static final String ACTION_ALARM = "com.dougkeen.action.ALARM";
|
||||
public static final String STATION_PAIR_EXTRA = "StationPair";
|
||||
}
|
||||
|
@ -3,27 +3,23 @@ package com.dougkeen.bart.model;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.dougkeen.bart.data.CursorUtils;
|
||||
import com.dougkeen.bart.data.RoutesColumns;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class StationPair implements Parcelable {
|
||||
public StationPair(Station origin, Station destination) {
|
||||
@JsonCreator
|
||||
public StationPair(@JsonProperty("origin") Station origin,
|
||||
@JsonProperty("destination") Station destination) {
|
||||
super();
|
||||
this.origin = origin;
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
public StationPair(Long id, Station origin, Station destination) {
|
||||
super();
|
||||
this.origin = origin;
|
||||
this.destination = destination;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public StationPair(Parcel in) {
|
||||
readFromParcel(in);
|
||||
}
|
||||
@ -34,22 +30,22 @@ public class StationPair implements Parcelable {
|
||||
RoutesColumns.FROM_STATION)),
|
||||
Station.getByAbbreviation(CursorUtils.getString(cursor,
|
||||
RoutesColumns.TO_STATION)));
|
||||
pair.id = CursorUtils.getLong(cursor, RoutesColumns._ID);
|
||||
pair.fare = CursorUtils.getString(cursor, RoutesColumns.FARE);
|
||||
pair.fareLastUpdated = CursorUtils.getLong(cursor,
|
||||
RoutesColumns.FARE_LAST_UPDATED);
|
||||
pair.averageTripLength = CursorUtils.getInteger(cursor,
|
||||
RoutesColumns.AVERAGE_TRIP_LENGTH);
|
||||
pair.averageTripSampleCount = CursorUtils.getInteger(cursor,
|
||||
RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT);
|
||||
return pair;
|
||||
}
|
||||
|
||||
private Long id;
|
||||
private Station origin;
|
||||
private Station destination;
|
||||
private String fare;
|
||||
private Long fareLastUpdated;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
private long fareLastUpdated;
|
||||
private int averageTripLength;
|
||||
private int averageTripSampleCount;
|
||||
|
||||
public Station getOrigin() {
|
||||
return origin;
|
||||
@ -67,29 +63,35 @@ public class StationPair implements Parcelable {
|
||||
this.fare = fare;
|
||||
}
|
||||
|
||||
public Long getFareLastUpdated() {
|
||||
public long getFareLastUpdated() {
|
||||
return fareLastUpdated;
|
||||
}
|
||||
|
||||
public void setFareLastUpdated(Long fareLastUpdated) {
|
||||
public void setFareLastUpdated(long fareLastUpdated) {
|
||||
this.fareLastUpdated = fareLastUpdated;
|
||||
}
|
||||
|
||||
public int getAverageTripLength() {
|
||||
return averageTripLength;
|
||||
}
|
||||
|
||||
public void setAverageTripLength(int averageTripLength) {
|
||||
this.averageTripLength = averageTripLength;
|
||||
}
|
||||
|
||||
public int getAverageTripSampleCount() {
|
||||
return averageTripSampleCount;
|
||||
}
|
||||
|
||||
public void setAverageTripSampleCount(int averageTripSampleCount) {
|
||||
this.averageTripSampleCount = averageTripSampleCount;
|
||||
}
|
||||
|
||||
public boolean isBetweenStations(Station station1, Station station2) {
|
||||
return (origin.equals(station1) && destination.equals(station2))
|
||||
|| (origin.equals(station2) && destination.equals(station1));
|
||||
}
|
||||
|
||||
public Uri getUri() {
|
||||
if (getOrigin() != null && getDestination() != null) {
|
||||
return Constants.ARBITRARY_ROUTE_CONTENT_URI_ROOT.buildUpon()
|
||||
.appendPath(getOrigin().abbreviation)
|
||||
.appendPath(getDestination().abbreviation).build();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
|
@ -89,7 +89,7 @@ public class BoardedDepartureService extends Service implements
|
||||
mServiceLooper = thread.getLooper();
|
||||
mServiceHandler = new ServiceHandler(mServiceLooper, this);
|
||||
|
||||
bindService(new Intent(this, EtdService.class), mConnection,
|
||||
bindService(EtdService_.intent(this).get(), mConnection,
|
||||
Context.BIND_AUTO_CREATE);
|
||||
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||
|
@ -10,20 +10,15 @@ import java.util.WeakHashMap;
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.util.Log;
|
||||
|
||||
import com.dougkeen.bart.BartRunnerApplication;
|
||||
import com.dougkeen.bart.R;
|
||||
import com.dougkeen.bart.data.RoutesColumns;
|
||||
import com.dougkeen.bart.model.Constants;
|
||||
import com.dougkeen.bart.model.Departure;
|
||||
import com.dougkeen.bart.model.RealTimeDepartures;
|
||||
@ -33,7 +28,9 @@ import com.dougkeen.bart.model.Station;
|
||||
import com.dougkeen.bart.model.StationPair;
|
||||
import com.dougkeen.bart.networktasks.GetRealTimeDeparturesTask;
|
||||
import com.dougkeen.bart.networktasks.GetScheduleInformationTask;
|
||||
import com.googlecode.androidannotations.annotations.EService;
|
||||
|
||||
@EService
|
||||
public class EtdService extends Service {
|
||||
|
||||
private IBinder mBinder;
|
||||
@ -106,19 +103,13 @@ public class EtdService extends Service {
|
||||
private class EtdServiceEngine {
|
||||
private static final int UNCERTAINTY_THRESHOLD = 17;
|
||||
|
||||
private Uri mUri;
|
||||
|
||||
private final StationPair mStationPair;
|
||||
|
||||
private boolean mIgnoreDepartureDirection = false;
|
||||
|
||||
private boolean mPendingEtdRequest = false;
|
||||
|
||||
private int mAverageTripLength;
|
||||
private int mAverageTripSampleCount;
|
||||
|
||||
// We'll only use the keys
|
||||
private WeakHashMap<EtdServiceListener, Boolean> mListeners;
|
||||
private Map<EtdServiceListener, Boolean> mListeners;
|
||||
|
||||
private boolean mLimitToFirstNonDeparted = true;
|
||||
|
||||
@ -134,24 +125,9 @@ public class EtdService extends Service {
|
||||
|
||||
public EtdServiceEngine(final StationPair route) {
|
||||
mStationPair = route;
|
||||
mListeners = new WeakHashMap<EtdService.EtdServiceListener, Boolean>();
|
||||
mListeners = new HashMap<EtdService.EtdServiceListener, Boolean>();
|
||||
mRunnableQueue = new Handler();
|
||||
mLatestDepartures = new ArrayList<Departure>();
|
||||
|
||||
mUri = Constants.ARBITRARY_ROUTE_CONTENT_URI_ROOT.buildUpon()
|
||||
.appendPath(mStationPair.getOrigin().abbreviation)
|
||||
.appendPath(mStationPair.getDestination().abbreviation)
|
||||
.build();
|
||||
|
||||
Cursor cursor = new CursorLoader(EtdService.this, mUri,
|
||||
new String[] { RoutesColumns.AVERAGE_TRIP_LENGTH.string,
|
||||
RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string },
|
||||
null, null, null).loadInBackground();
|
||||
if (cursor.moveToFirst()) {
|
||||
mAverageTripLength = cursor.getInt(0);
|
||||
mAverageTripSampleCount = cursor.getInt(1);
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
protected void registerListener(EtdServiceListener listener,
|
||||
@ -238,8 +214,7 @@ public class EtdService extends Service {
|
||||
};
|
||||
mGetDeparturesTask = task;
|
||||
Log.v(Constants.TAG, "Fetching data from server");
|
||||
task.execute(new StationPair(mStationPair.getOrigin(), mStationPair
|
||||
.getDestination()));
|
||||
task.execute(mStationPair);
|
||||
notifyListenersOfRequestStart();
|
||||
}
|
||||
|
||||
@ -271,8 +246,7 @@ public class EtdService extends Service {
|
||||
};
|
||||
Log.i(Constants.TAG, "Fetching data from server");
|
||||
mGetScheduleInformationTask = task;
|
||||
task.execute(new StationPair(mStationPair.getOrigin(), mStationPair
|
||||
.getDestination()));
|
||||
task.execute(mStationPair);
|
||||
}
|
||||
|
||||
protected void applyScheduleInformation(ScheduleInformation result) {
|
||||
@ -363,7 +337,8 @@ public class EtdService extends Service {
|
||||
departure.setEstimatedTripTime(localAverageLength);
|
||||
} else if (!departure.hasEstimatedTripTime()) {
|
||||
// Otherwise just assume the global average
|
||||
departure.setEstimatedTripTime(mAverageTripLength);
|
||||
departure.setEstimatedTripTime(mStationPair
|
||||
.getAverageTripLength());
|
||||
}
|
||||
} else if (departure.getRequiresTransfer()
|
||||
&& !departure.hasAnyArrivalEstimate()) {
|
||||
@ -381,20 +356,16 @@ public class EtdService extends Service {
|
||||
|
||||
// Update global average
|
||||
if (mLatestScheduleInfo.getTripCountForAverage() > 0) {
|
||||
int newAverageSampleCount = mAverageTripSampleCount
|
||||
int newAverageSampleCount = mStationPair
|
||||
.getAverageTripSampleCount()
|
||||
+ mLatestScheduleInfo.getTripCountForAverage();
|
||||
int newAverage = (mAverageTripLength * mAverageTripSampleCount + localAverageLength
|
||||
int newAverage = (mStationPair.getAverageTripLength()
|
||||
* mStationPair.getAverageTripSampleCount() + localAverageLength
|
||||
* mLatestScheduleInfo.getTripCountForAverage())
|
||||
/ newAverageSampleCount;
|
||||
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(RoutesColumns.AVERAGE_TRIP_LENGTH.string,
|
||||
newAverage);
|
||||
contentValues.put(
|
||||
RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string,
|
||||
newAverageSampleCount);
|
||||
|
||||
getContentResolver().update(mUri, contentValues, null, null);
|
||||
mStationPair.setAverageTripLength(newAverage);
|
||||
mStationPair.setAverageTripSampleCount(newAverageSampleCount);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user