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" />
|
android:targetSdkVersion="14" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".BartRunnerApplication"
|
android:name=".BartRunnerApplication_"
|
||||||
android:icon="@drawable/icon"
|
android:icon="@drawable/icon"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/AppTheme" >
|
android:theme="@style/AppTheme" >
|
||||||
@ -61,17 +61,11 @@
|
|||||||
android:label="@string/system_map" >
|
android:label="@string/system_map" >
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<provider
|
|
||||||
android:name=".data.BartContentProvider"
|
|
||||||
android:authorities="com.dougkeen.bart.dataprovider"
|
|
||||||
android:exported="false"
|
|
||||||
android:label="BartRunner data provider" />
|
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".services.BoardedDepartureService"
|
android:name=".services.BoardedDepartureService"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<service
|
<service
|
||||||
android:name=".services.EtdService"
|
android:name=".services.EtdService_"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
<receiver
|
<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_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:text="@string/empty_favorites_list_message"
|
||||||
android:visibility="gone" />
|
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
|
<TextView
|
||||||
android:id="@+id/alertMessages"
|
android:id="@+id/alertMessages"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -4,6 +4,7 @@ import java.io.File;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
@ -15,9 +16,16 @@ import android.media.MediaPlayer;
|
|||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.util.Log;
|
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.Constants;
|
||||||
import com.dougkeen.bart.model.Departure;
|
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 {
|
public class BartRunnerApplication extends Application {
|
||||||
private static final int FIVE_MINUTES = 5 * 60 * 1000;
|
private static final int FIVE_MINUTES = 5 * 60 * 1000;
|
||||||
|
|
||||||
@ -33,6 +41,53 @@ public class BartRunnerApplication extends Application {
|
|||||||
|
|
||||||
private static Context context;
|
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
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
@ -59,12 +114,13 @@ public class BartRunnerApplication extends Application {
|
|||||||
InputStream inputStream = null;
|
InputStream inputStream = null;
|
||||||
try {
|
try {
|
||||||
inputStream = new FileInputStream(cachedDepartureFile);
|
inputStream = new FileInputStream(cachedDepartureFile);
|
||||||
byte[] byteArray = IOUtils.toByteArray(inputStream);
|
final byte[] byteArray = IOUtils.toByteArray(inputStream);
|
||||||
Parcel parcel = Parcel.obtain();
|
final Parcel parcel = Parcel.obtain();
|
||||||
parcel.unmarshall(byteArray, 0, byteArray.length);
|
parcel.unmarshall(byteArray, 0, byteArray.length);
|
||||||
parcel.setDataPosition(0);
|
parcel.setDataPosition(0);
|
||||||
Departure lastBoardedDeparture = Departure.CREATOR
|
Departure lastBoardedDeparture = Departure.CREATOR
|
||||||
.createFromParcel(parcel);
|
.createFromParcel(parcel);
|
||||||
|
parcel.recycle();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the cached one is relatively recent. If so,
|
* Check if the cached one is relatively recent. If so,
|
||||||
|
@ -29,6 +29,13 @@ public abstract class AbstractRouteSelectionFragment extends DialogFragment {
|
|||||||
mTitle = title;
|
mTitle = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setArguments(Bundle args) {
|
||||||
|
super.setArguments(args);
|
||||||
|
if (args.containsKey("title"))
|
||||||
|
mTitle = args.getString("title");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
package com.dougkeen.bart.activities;
|
package com.dougkeen.bart.activities;
|
||||||
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
|
|
||||||
import com.dougkeen.bart.BartRunnerApplication;
|
import com.dougkeen.bart.BartRunnerApplication;
|
||||||
import com.dougkeen.bart.R;
|
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.Station;
|
||||||
|
import com.dougkeen.bart.model.StationPair;
|
||||||
|
|
||||||
public class AddRouteDialogFragment extends AbstractRouteSelectionFragment {
|
public class AddRouteDialogFragment extends AbstractRouteSelectionFragment {
|
||||||
public AddRouteDialogFragment() {
|
public AddRouteDialogFragment() {
|
||||||
@ -16,10 +14,6 @@ public class AddRouteDialogFragment extends AbstractRouteSelectionFragment {
|
|||||||
R.string.add_route));
|
R.string.add_route));
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddRouteDialogFragment(String title) {
|
|
||||||
super(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
@ -29,22 +23,12 @@ public class AddRouteDialogFragment extends AbstractRouteSelectionFragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onOkButtonClick(Station origin, Station destination) {
|
protected void onOkButtonClick(Station origin, Station destination) {
|
||||||
ContentValues values = new ContentValues();
|
RoutesListActivity activity = (RoutesListActivity) getActivity();
|
||||||
values.put(RoutesColumns.FROM_STATION.string, origin.abbreviation);
|
activity.addFavorite(new StationPair(origin, destination));
|
||||||
values.put(RoutesColumns.TO_STATION.string, destination.abbreviation);
|
|
||||||
|
|
||||||
getActivity().getContentResolver().insert(
|
|
||||||
Constants.FAVORITE_CONTENT_URI, values);
|
|
||||||
|
|
||||||
if (((CheckBox) getDialog().findViewById(R.id.return_checkbox))
|
if (((CheckBox) getDialog().findViewById(R.id.return_checkbox))
|
||||||
.isChecked()) {
|
.isChecked()) {
|
||||||
values = new ContentValues();
|
activity.addFavorite(new StationPair(destination, origin));
|
||||||
values.put(RoutesColumns.FROM_STATION.string,
|
|
||||||
destination.abbreviation);
|
|
||||||
values.put(RoutesColumns.TO_STATION.string, origin.abbreviation);
|
|
||||||
|
|
||||||
getActivity().getContentResolver().insert(
|
|
||||||
Constants.FAVORITE_CONTENT_URI, values);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dismiss();
|
dismiss();
|
||||||
|
@ -14,10 +14,6 @@ public class QuickRouteDialogFragment extends AbstractRouteSelectionFragment {
|
|||||||
R.string.quick_departure_lookup));
|
R.string.quick_departure_lookup));
|
||||||
}
|
}
|
||||||
|
|
||||||
public QuickRouteDialogFragment(String title) {
|
|
||||||
super(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onOkButtonClick(Station origin, Station destination) {
|
protected void onOkButtonClick(Station origin, Station destination) {
|
||||||
startActivity(new Intent(Intent.ACTION_VIEW,
|
startActivity(new Intent(Intent.ACTION_VIEW,
|
||||||
|
@ -3,16 +3,10 @@ package com.dougkeen.bart.activities;
|
|||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import android.content.ContentUris;
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.LoaderManager.LoaderCallbacks;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.content.CursorLoader;
|
|
||||||
import android.support.v4.content.Loader;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
@ -29,24 +23,24 @@ import com.actionbarsherlock.view.ActionMode;
|
|||||||
import com.actionbarsherlock.view.Menu;
|
import com.actionbarsherlock.view.Menu;
|
||||||
import com.actionbarsherlock.view.MenuInflater;
|
import com.actionbarsherlock.view.MenuInflater;
|
||||||
import com.actionbarsherlock.view.MenuItem;
|
import com.actionbarsherlock.view.MenuItem;
|
||||||
|
import com.dougkeen.bart.BartRunnerApplication;
|
||||||
import com.dougkeen.bart.R;
|
import com.dougkeen.bart.R;
|
||||||
import com.dougkeen.bart.controls.Ticker;
|
import com.dougkeen.bart.controls.Ticker;
|
||||||
import com.dougkeen.bart.controls.Ticker.TickSubscriber;
|
import com.dougkeen.bart.controls.Ticker.TickSubscriber;
|
||||||
import com.dougkeen.bart.data.CursorUtils;
|
|
||||||
import com.dougkeen.bart.data.FavoritesArrayAdapter;
|
import com.dougkeen.bart.data.FavoritesArrayAdapter;
|
||||||
import com.dougkeen.bart.data.RoutesColumns;
|
|
||||||
import com.dougkeen.bart.model.Alert;
|
import com.dougkeen.bart.model.Alert;
|
||||||
import com.dougkeen.bart.model.Alert.AlertList;
|
import com.dougkeen.bart.model.Alert.AlertList;
|
||||||
import com.dougkeen.bart.model.Constants;
|
import com.dougkeen.bart.model.Constants;
|
||||||
import com.dougkeen.bart.model.Station;
|
|
||||||
import com.dougkeen.bart.model.StationPair;
|
import com.dougkeen.bart.model.StationPair;
|
||||||
import com.dougkeen.bart.networktasks.AlertsClient;
|
import com.dougkeen.bart.networktasks.AlertsClient;
|
||||||
import com.dougkeen.bart.networktasks.ElevatorClient;
|
import com.dougkeen.bart.networktasks.ElevatorClient;
|
||||||
import com.dougkeen.bart.networktasks.GetRouteFareTask;
|
import com.dougkeen.bart.networktasks.GetRouteFareTask;
|
||||||
import com.googlecode.androidannotations.annotations.AfterViews;
|
import com.googlecode.androidannotations.annotations.AfterViews;
|
||||||
|
import com.googlecode.androidannotations.annotations.App;
|
||||||
import com.googlecode.androidannotations.annotations.Background;
|
import com.googlecode.androidannotations.annotations.Background;
|
||||||
import com.googlecode.androidannotations.annotations.Click;
|
import com.googlecode.androidannotations.annotations.Click;
|
||||||
import com.googlecode.androidannotations.annotations.EActivity;
|
import com.googlecode.androidannotations.annotations.EActivity;
|
||||||
|
import com.googlecode.androidannotations.annotations.InstanceState;
|
||||||
import com.googlecode.androidannotations.annotations.ItemClick;
|
import com.googlecode.androidannotations.annotations.ItemClick;
|
||||||
import com.googlecode.androidannotations.annotations.ItemLongClick;
|
import com.googlecode.androidannotations.annotations.ItemLongClick;
|
||||||
import com.googlecode.androidannotations.annotations.UiThread;
|
import com.googlecode.androidannotations.annotations.UiThread;
|
||||||
@ -54,24 +48,25 @@ import com.googlecode.androidannotations.annotations.ViewById;
|
|||||||
import com.googlecode.androidannotations.annotations.rest.RestService;
|
import com.googlecode.androidannotations.annotations.rest.RestService;
|
||||||
|
|
||||||
@EActivity(R.layout.main)
|
@EActivity(R.layout.main)
|
||||||
public class RoutesListActivity extends SActivity implements
|
public class RoutesListActivity extends SActivity implements TickSubscriber {
|
||||||
LoaderCallbacks<Cursor>, TickSubscriber {
|
|
||||||
private static final String NO_DELAYS_REPORTED = "No delays reported";
|
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
|
private static final TimeZone PACIFIC_TIME = TimeZone
|
||||||
.getTimeZone("America/Los_Angeles");
|
.getTimeZone("America/Los_Angeles");
|
||||||
|
|
||||||
private Uri mCurrentlySelectedUri;
|
@InstanceState
|
||||||
|
StationPair mCurrentlySelectedStationPair;
|
||||||
|
|
||||||
private Station mCurrentlySelectedOrigin;
|
@InstanceState
|
||||||
private Station mCurrentlySelectedDestination;
|
String mCurrentAlerts;
|
||||||
|
|
||||||
private ActionMode mActionMode;
|
private ActionMode mActionMode;
|
||||||
|
|
||||||
private FavoritesArrayAdapter mRoutesAdapter;
|
private FavoritesArrayAdapter mRoutesAdapter;
|
||||||
|
|
||||||
|
@App
|
||||||
|
BartRunnerApplication app;
|
||||||
|
|
||||||
@RestService
|
@RestService
|
||||||
AlertsClient alertsClient;
|
AlertsClient alertsClient;
|
||||||
|
|
||||||
@ -89,16 +84,16 @@ public class RoutesListActivity extends SActivity implements
|
|||||||
|
|
||||||
@Click(R.id.quickLookupButton)
|
@Click(R.id.quickLookupButton)
|
||||||
void quickLookupButtonClick() {
|
void quickLookupButtonClick() {
|
||||||
DialogFragment dialog = new QuickRouteDialogFragment(
|
DialogFragment dialog = new QuickRouteDialogFragment();
|
||||||
getString(R.string.quick_departure_lookup));
|
|
||||||
dialog.show(getSupportFragmentManager().beginTransaction());
|
dialog.show(getSupportFragmentManager().beginTransaction());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ItemClick(android.R.id.list)
|
@ItemClick(android.R.id.list)
|
||||||
void listItemClicked(StationPair item) {
|
void listItemClicked(StationPair item) {
|
||||||
startActivity(new Intent(Intent.ACTION_VIEW,
|
Intent intent = new Intent(RoutesListActivity.this,
|
||||||
ContentUris.withAppendedId(Constants.FAVORITE_CONTENT_URI,
|
ViewDeparturesActivity.class);
|
||||||
item.getId())));
|
intent.putExtra(Constants.STATION_PAIR_EXTRA, item);
|
||||||
|
startActivity(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ItemLongClick(android.R.id.list)
|
@ItemLongClick(android.R.id.list)
|
||||||
@ -107,11 +102,7 @@ public class RoutesListActivity extends SActivity implements
|
|||||||
mActionMode.finish();
|
mActionMode.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentlySelectedUri = ContentUris.withAppendedId(
|
mCurrentlySelectedStationPair = item;
|
||||||
Constants.FAVORITE_CONTENT_URI, item.getId());
|
|
||||||
|
|
||||||
mCurrentlySelectedOrigin = item.getOrigin();
|
|
||||||
mCurrentlySelectedDestination = item.getDestination();
|
|
||||||
|
|
||||||
startContextualActionMode();
|
startContextualActionMode();
|
||||||
}
|
}
|
||||||
@ -121,9 +112,7 @@ public class RoutesListActivity extends SActivity implements
|
|||||||
setTitle(R.string.favorite_routes);
|
setTitle(R.string.favorite_routes);
|
||||||
|
|
||||||
mRoutesAdapter = new FavoritesArrayAdapter(this,
|
mRoutesAdapter = new FavoritesArrayAdapter(this,
|
||||||
R.layout.favorite_listing);
|
R.layout.favorite_listing, app.getFavorites());
|
||||||
|
|
||||||
getSupportLoaderManager().initLoader(FAVORITES_LOADER_ID, null, this);
|
|
||||||
|
|
||||||
setListAdapter(mRoutesAdapter);
|
setListAdapter(mRoutesAdapter);
|
||||||
|
|
||||||
@ -132,6 +121,9 @@ public class RoutesListActivity extends SActivity implements
|
|||||||
if (mCurrentAlerts != null) {
|
if (mCurrentAlerts != null) {
|
||||||
showAlertMessage(mCurrentAlerts);
|
showAlertMessage(mCurrentAlerts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startEtdListeners();
|
||||||
|
refreshFares();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called when the activity is first created. */
|
/** Called when the activity is first created. */
|
||||||
@ -140,58 +132,14 @@ public class RoutesListActivity extends SActivity implements
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
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")) {
|
if (savedInstanceState.getBoolean("hasActionMode")) {
|
||||||
startContextualActionMode();
|
startContextualActionMode();
|
||||||
}
|
}
|
||||||
mCurrentAlerts = savedInstanceState.getString("currentAlerts");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ticker.getInstance().addSubscriber(this, getApplicationContext());
|
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() {
|
private AdapterView<ListAdapter> getListView() {
|
||||||
return listView;
|
return listView;
|
||||||
}
|
}
|
||||||
@ -205,70 +153,59 @@ public class RoutesListActivity extends SActivity implements
|
|||||||
getListView().setAdapter(mRoutesAdapter);
|
getListView().setAdapter(mRoutesAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshFares(Cursor cursor) {
|
void addFavorite(StationPair pair) {
|
||||||
if (cursor.moveToFirst()) {
|
mRoutesAdapter.add(pair);
|
||||||
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);
|
|
||||||
|
|
||||||
Calendar now = Calendar.getInstance();
|
private void refreshFares() {
|
||||||
Calendar lastUpdate = Calendar.getInstance();
|
for (int i = getListAdapter().getCount() - 1; i >= 0; i--) {
|
||||||
lastUpdate.setTimeInMillis(lastUpdateMillis);
|
final StationPair stationPair = getListAdapter().getItem(i);
|
||||||
|
|
||||||
now.setTimeZone(PACIFIC_TIME);
|
Calendar now = Calendar.getInstance();
|
||||||
lastUpdate.setTimeZone(PACIFIC_TIME);
|
Calendar lastUpdate = Calendar.getInstance();
|
||||||
|
lastUpdate.setTimeInMillis(stationPair.getFareLastUpdated());
|
||||||
|
|
||||||
// Update every day
|
now.setTimeZone(PACIFIC_TIME);
|
||||||
if (now.get(Calendar.DAY_OF_YEAR) != lastUpdate
|
lastUpdate.setTimeZone(PACIFIC_TIME);
|
||||||
.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());
|
|
||||||
|
|
||||||
getContentResolver()
|
// Update every day
|
||||||
.update(ContentUris.withAppendedId(
|
if (now.get(Calendar.DAY_OF_YEAR) != lastUpdate
|
||||||
Constants.FAVORITE_CONTENT_URI, id),
|
.get(Calendar.DAY_OF_YEAR)
|
||||||
values, null, null);
|
|| 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
|
@Override
|
||||||
public void onError(Exception exception) {
|
public void onError(Exception exception) {
|
||||||
// Ignore... we can do this later
|
// Ignore... we can do this later
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fareTask.execute(new GetRouteFareTask.Params(orig, dest));
|
fareTask.execute(new GetRouteFareTask.Params(stationPair
|
||||||
}
|
.getOrigin(), stationPair.getDestination()));
|
||||||
} while (cursor.moveToNext());
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onSaveInstanceState(Bundle outState) {
|
protected void onSaveInstanceState(Bundle outState) {
|
||||||
super.onSaveInstanceState(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.putBoolean("hasActionMode", mActionMode != null);
|
||||||
outState.putString("currentAlerts", mCurrentAlerts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
Ticker.getInstance().startTicking(this);
|
Ticker.getInstance().startTicking(this);
|
||||||
|
startEtdListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startEtdListeners() {
|
||||||
if (mRoutesAdapter != null && !mRoutesAdapter.isEmpty()
|
if (mRoutesAdapter != null && !mRoutesAdapter.isEmpty()
|
||||||
&& !mRoutesAdapter.areEtdListenersActive()) {
|
&& !mRoutesAdapter.areEtdListenersActive()) {
|
||||||
mRoutesAdapter.setUpEtdListeners();
|
mRoutesAdapter.setUpEtdListeners();
|
||||||
@ -287,6 +224,8 @@ public class RoutesListActivity extends SActivity implements
|
|||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
Ticker.getInstance().stopTicking(this);
|
Ticker.getInstance().stopTicking(this);
|
||||||
|
app.saveFavorites();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -314,13 +253,11 @@ public class RoutesListActivity extends SActivity implements
|
|||||||
private MenuItem elevatorMenuItem;
|
private MenuItem elevatorMenuItem;
|
||||||
private View origElevatorActionView;
|
private View origElevatorActionView;
|
||||||
|
|
||||||
private String mCurrentAlerts;
|
|
||||||
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
int itemId = item.getItemId();
|
int itemId = item.getItemId();
|
||||||
if (itemId == R.id.add_favorite_menu_button) {
|
if (itemId == R.id.add_favorite_menu_button) {
|
||||||
new AddRouteDialogFragment(getString(R.string.add_route))
|
new AddRouteDialogFragment().show(getSupportFragmentManager()
|
||||||
.show(getSupportFragmentManager().beginTransaction());
|
.beginTransaction());
|
||||||
return true;
|
return true;
|
||||||
} else if (itemId == R.id.view_system_map_button) {
|
} else if (itemId == R.id.view_system_map_button) {
|
||||||
startActivity(new Intent(this, ViewMapActivity.class));
|
startActivity(new Intent(this, ViewMapActivity.class));
|
||||||
@ -393,7 +330,7 @@ public class RoutesListActivity extends SActivity implements
|
|||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
void resetElevatorMenuGraphic() {
|
void resetElevatorMenuGraphic() {
|
||||||
invalidateOptionsMenu();
|
ActivityCompat.invalidateOptionsMenu(this);
|
||||||
elevatorMenuItem.setActionView(origElevatorActionView);
|
elevatorMenuItem.setActionView(origElevatorActionView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,8 +344,9 @@ public class RoutesListActivity extends SActivity implements
|
|||||||
|
|
||||||
private void startContextualActionMode() {
|
private void startContextualActionMode() {
|
||||||
mActionMode = startActionMode(new RouteActionMode());
|
mActionMode = startActionMode(new RouteActionMode());
|
||||||
mActionMode.setTitle(mCurrentlySelectedOrigin.name);
|
mActionMode.setTitle(mCurrentlySelectedStationPair.getOrigin().name);
|
||||||
mActionMode.setSubtitle("to " + mCurrentlySelectedDestination.name);
|
mActionMode.setSubtitle("to "
|
||||||
|
+ mCurrentlySelectedStationPair.getDestination().name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class RouteActionMode implements ActionMode.Callback {
|
private final class RouteActionMode implements ActionMode.Callback {
|
||||||
@ -426,8 +364,11 @@ public class RoutesListActivity extends SActivity implements
|
|||||||
@Override
|
@Override
|
||||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||||
if (item.getItemId() == R.id.view) {
|
if (item.getItemId() == R.id.view) {
|
||||||
startActivity(new Intent(Intent.ACTION_VIEW,
|
Intent intent = new Intent(RoutesListActivity.this,
|
||||||
mCurrentlySelectedUri));
|
ViewDeparturesActivity.class);
|
||||||
|
intent.putExtra(Constants.STATION_PAIR_EXTRA,
|
||||||
|
mCurrentlySelectedStationPair);
|
||||||
|
startActivity(intent);
|
||||||
mode.finish();
|
mode.finish();
|
||||||
return true;
|
return true;
|
||||||
} else if (item.getItemId() == R.id.delete) {
|
} else if (item.getItemId() == R.id.delete) {
|
||||||
@ -439,11 +380,9 @@ public class RoutesListActivity extends SActivity implements
|
|||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog,
|
public void onClick(DialogInterface dialog,
|
||||||
int which) {
|
int which) {
|
||||||
getContentResolver().delete(
|
getListAdapter().remove(
|
||||||
mCurrentlySelectedUri, null, null);
|
mCurrentlySelectedStationPair);
|
||||||
mCurrentlySelectedUri = null;
|
mCurrentlySelectedStationPair = null;
|
||||||
mCurrentlySelectedOrigin = null;
|
|
||||||
mCurrentlySelectedDestination = null;
|
|
||||||
mActionMode.finish();
|
mActionMode.finish();
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ import android.content.Context;
|
|||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.media.RingtoneManager;
|
import android.media.RingtoneManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -18,9 +17,6 @@ import android.os.Handler;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.Vibrator;
|
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.format.DateFormat;
|
||||||
import android.text.util.Linkify;
|
import android.text.util.Linkify;
|
||||||
import android.util.Log;
|
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.Ticker;
|
||||||
import com.dougkeen.bart.controls.YourTrainLayout;
|
import com.dougkeen.bart.controls.YourTrainLayout;
|
||||||
import com.dougkeen.bart.data.DepartureArrayAdapter;
|
import com.dougkeen.bart.data.DepartureArrayAdapter;
|
||||||
import com.dougkeen.bart.data.RoutesColumns;
|
|
||||||
import com.dougkeen.bart.model.Constants;
|
import com.dougkeen.bart.model.Constants;
|
||||||
import com.dougkeen.bart.model.Departure;
|
import com.dougkeen.bart.model.Departure;
|
||||||
import com.dougkeen.bart.model.Station;
|
|
||||||
import com.dougkeen.bart.model.StationPair;
|
import com.dougkeen.bart.model.StationPair;
|
||||||
import com.dougkeen.bart.services.BoardedDepartureService;
|
import com.dougkeen.bart.services.BoardedDepartureService;
|
||||||
import com.dougkeen.bart.services.EtdService;
|
import com.dougkeen.bart.services.EtdService;
|
||||||
import com.dougkeen.bart.services.EtdService.EtdServiceBinder;
|
import com.dougkeen.bart.services.EtdService.EtdServiceBinder;
|
||||||
import com.dougkeen.bart.services.EtdService.EtdServiceListener;
|
import com.dougkeen.bart.services.EtdService.EtdServiceListener;
|
||||||
|
import com.dougkeen.bart.services.EtdService_;
|
||||||
import com.dougkeen.util.Observer;
|
import com.dougkeen.util.Observer;
|
||||||
import com.dougkeen.util.WakeLocker;
|
import com.dougkeen.util.WakeLocker;
|
||||||
|
|
||||||
public class ViewDeparturesActivity extends SActivity implements
|
public class ViewDeparturesActivity extends SActivity implements
|
||||||
EtdServiceListener {
|
EtdServiceListener {
|
||||||
|
|
||||||
private static final int LOADER_ID = 123;
|
private StationPair mStationPair;
|
||||||
|
|
||||||
private Uri mUri;
|
|
||||||
|
|
||||||
private Station mOrigin;
|
|
||||||
private Station mDestination;
|
|
||||||
|
|
||||||
private Departure mSelectedDeparture;
|
private Departure mSelectedDeparture;
|
||||||
|
|
||||||
@ -89,64 +79,8 @@ public class ViewDeparturesActivity extends SActivity implements
|
|||||||
|
|
||||||
final Intent intent = getIntent();
|
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();
|
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 = (TextView) findViewById(android.R.id.empty);
|
||||||
mEmptyView.setText(R.string.departure_wait_message);
|
mEmptyView.setText(R.string.departure_wait_message);
|
||||||
|
|
||||||
@ -155,6 +89,43 @@ public class ViewDeparturesActivity extends SActivity implements
|
|||||||
mDeparturesAdapter = new DepartureArrayAdapter(this,
|
mDeparturesAdapter = new DepartureArrayAdapter(this,
|
||||||
R.layout.departure_listing);
|
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 != null) {
|
||||||
if (savedInstanceState.containsKey("departures")) {
|
if (savedInstanceState.containsKey("departures")) {
|
||||||
for (Parcelable departure : savedInstanceState
|
for (Parcelable departure : savedInstanceState
|
||||||
@ -178,29 +149,6 @@ public class ViewDeparturesActivity extends SActivity implements
|
|||||||
startYourTrainActionMode();
|
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);
|
refreshBoardedDeparture(false);
|
||||||
|
|
||||||
getSupportActionBar().setHomeButtonEnabled(true);
|
getSupportActionBar().setHomeButtonEnabled(true);
|
||||||
@ -297,8 +245,9 @@ public class ViewDeparturesActivity extends SActivity implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setListTitle() {
|
private void setListTitle() {
|
||||||
((TextView) findViewById(R.id.listTitle)).setText(mOrigin.name + " to "
|
((TextView) findViewById(R.id.listTitle))
|
||||||
+ mDestination.name);
|
.setText(mStationPair.getOrigin().name + " to "
|
||||||
|
+ mStationPair.getDestination().name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ListView getListView() {
|
private ListView getListView() {
|
||||||
@ -399,7 +348,7 @@ public class ViewDeparturesActivity extends SActivity implements
|
|||||||
@Override
|
@Override
|
||||||
protected void onSaveInstanceState(Bundle outState) {
|
protected void onSaveInstanceState(Bundle outState) {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
if (mOrigin != null || mDestination != null) {
|
if (mStationPair != null) {
|
||||||
/*
|
/*
|
||||||
* If origin or destination are null, this thing was never
|
* If origin or destination are null, this thing was never
|
||||||
* initialized in the first place, so there's really nothing to save
|
* initialized in the first place, so there's really nothing to save
|
||||||
@ -415,15 +364,14 @@ public class ViewDeparturesActivity extends SActivity implements
|
|||||||
isDepartureActionModeActive());
|
isDepartureActionModeActive());
|
||||||
outState.putBoolean("hasYourTrainActionMode",
|
outState.putBoolean("hasYourTrainActionMode",
|
||||||
isYourTrainActionModeActive());
|
isYourTrainActionModeActive());
|
||||||
outState.putString("origin", mOrigin.abbreviation);
|
outState.putParcelable("stationPair", mStationPair);
|
||||||
outState.putString("destination", mDestination.abbreviation);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
bindService(new Intent(this, EtdService.class), mConnection,
|
bindService(EtdService_.intent(this).get(), mConnection,
|
||||||
Context.BIND_AUTO_CREATE);
|
Context.BIND_AUTO_CREATE);
|
||||||
Ticker.getInstance().startTicking(this);
|
Ticker.getInstance().startTicking(this);
|
||||||
}
|
}
|
||||||
@ -459,10 +407,8 @@ public class ViewDeparturesActivity extends SActivity implements
|
|||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
int itemId = item.getItemId();
|
int itemId = item.getItemId();
|
||||||
if (itemId == android.R.id.home) {
|
if (itemId == android.R.id.home) {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW,
|
RoutesListActivity_.intent(this)
|
||||||
Constants.FAVORITE_CONTENT_URI);
|
.flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start();
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
return true;
|
||||||
} else if (itemId == R.id.view_on_bart_site_button) {
|
} else if (itemId == R.id.view_on_bart_site_button) {
|
||||||
startActivity(new Intent(
|
startActivity(new Intent(
|
||||||
@ -471,9 +417,9 @@ public class ViewDeparturesActivity extends SActivity implements
|
|||||||
+ DateFormat.format("h:mmaa",
|
+ DateFormat.format("h:mmaa",
|
||||||
System.currentTimeMillis())
|
System.currentTimeMillis())
|
||||||
+ "&orig="
|
+ "&orig="
|
||||||
+ mOrigin.abbreviation
|
+ mStationPair.getOrigin().abbreviation
|
||||||
+ "&dest="
|
+ "&dest="
|
||||||
+ mDestination.abbreviation)));
|
+ mStationPair.getDestination().abbreviation)));
|
||||||
return true;
|
return true;
|
||||||
} else if (itemId == R.id.view_system_map_button) {
|
} else if (itemId == R.id.view_system_map_button) {
|
||||||
startActivity(new Intent(this, ViewMapActivity.class));
|
startActivity(new Intent(this, ViewMapActivity.class));
|
||||||
@ -508,13 +454,16 @@ public class ViewDeparturesActivity extends SActivity implements
|
|||||||
|
|
||||||
private void setBoardedDeparture(Departure selectedDeparture) {
|
private void setBoardedDeparture(Departure selectedDeparture) {
|
||||||
final BartRunnerApplication application = (BartRunnerApplication) getApplication();
|
final BartRunnerApplication application = (BartRunnerApplication) getApplication();
|
||||||
selectedDeparture.setPassengerDestination(mDestination);
|
selectedDeparture
|
||||||
|
.setPassengerDestination(mStationPair.getDestination());
|
||||||
application.setBoardedDeparture(selectedDeparture);
|
application.setBoardedDeparture(selectedDeparture);
|
||||||
refreshBoardedDeparture(true);
|
refreshBoardedDeparture(true);
|
||||||
|
|
||||||
// Start the notification service
|
// Start the notification service
|
||||||
startService(new Intent(ViewDeparturesActivity.this,
|
final Intent intent = new Intent(ViewDeparturesActivity.this,
|
||||||
BoardedDepartureService.class));
|
BoardedDepartureService.class);
|
||||||
|
intent.putExtra("departure", selectedDeparture);
|
||||||
|
startService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startDepartureActionMode() {
|
private void startDepartureActionMode() {
|
||||||
@ -815,9 +764,7 @@ public class ViewDeparturesActivity extends SActivity implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StationPair getStationPair() {
|
public StationPair getStationPair() {
|
||||||
if (mOrigin == null || mDestination == null)
|
return mStationPair;
|
||||||
return null;
|
|
||||||
return new StationPair(mOrigin, mDestination);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hideYourTrainSection() {
|
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) {
|
public static final Long getLong(Cursor cursor, RoutesColumns column) {
|
||||||
return cursor.getLong(cursor.getColumnIndex(column.string));
|
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;
|
package com.dougkeen.bart.data;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
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 {
|
public class DatabaseHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
private static final String DATABASE_NAME = "bart.dougkeen.db";
|
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";
|
public static final String FAVORITES_TABLE_NAME = "Favorites";
|
||||||
|
|
||||||
|
private BartRunnerApplication app;
|
||||||
|
|
||||||
public DatabaseHelper(Context context) {
|
public DatabaseHelper(Context context) {
|
||||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
|
app = (BartRunnerApplication) context.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(SQLiteDatabase db) {
|
public void onCreate(SQLiteDatabase db) {
|
||||||
createFavoritesTable(db);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createFavoritesTable(SQLiteDatabase db) {
|
private void createFavoritesTable(SQLiteDatabase db) {
|
||||||
@ -45,54 +46,24 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
|||||||
try {
|
try {
|
||||||
createFavoritesTable(db);
|
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
|
List<StationPair> favorites = new ArrayList<StationPair>();
|
||||||
+ " RENAME TO temp_" + FAVORITES_TABLE_NAME);
|
|
||||||
|
|
||||||
createFavoritesTable(db);
|
while (query.moveToNext()) {
|
||||||
|
favorites.add(StationPair.createFromCursor(query));
|
||||||
|
}
|
||||||
|
|
||||||
columns.retainAll(getColumns(db, FAVORITES_TABLE_NAME));
|
query.close();
|
||||||
|
|
||||||
String cols = StringUtils.join(columns, ",");
|
new FavoritesPersistence(app).persist(favorites);
|
||||||
db.execSQL(String.format(
|
|
||||||
"INSERT INTO %s (%s) SELECT %s from temp_%s",
|
|
||||||
FAVORITES_TABLE_NAME, cols, cols, FAVORITES_TABLE_NAME));
|
|
||||||
|
|
||||||
db.execSQL("DROP TABLE temp_" + FAVORITES_TABLE_NAME);
|
db.execSQL("DROP TABLE " + FAVORITES_TABLE_NAME);
|
||||||
|
|
||||||
db.setTransactionSuccessful();
|
db.setTransactionSuccessful();
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction();
|
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.app.Activity;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
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;
|
||||||
import com.dougkeen.bart.services.EtdService.EtdServiceBinder;
|
import com.dougkeen.bart.services.EtdService.EtdServiceBinder;
|
||||||
import com.dougkeen.bart.services.EtdService.EtdServiceListener;
|
import com.dougkeen.bart.services.EtdService.EtdServiceListener;
|
||||||
|
import com.dougkeen.bart.services.EtdService_;
|
||||||
|
|
||||||
public class FavoritesArrayAdapter extends ArrayAdapter<StationPair> {
|
public class FavoritesArrayAdapter extends ArrayAdapter<StationPair> {
|
||||||
|
|
||||||
@ -82,10 +81,11 @@ public class FavoritesArrayAdapter extends ArrayAdapter<StationPair> {
|
|||||||
return !mEtdListeners.isEmpty();
|
return !mEtdListeners.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public FavoritesArrayAdapter(Context context, int textViewResourceId) {
|
public FavoritesArrayAdapter(Context context, int textViewResourceId,
|
||||||
super(context, textViewResourceId);
|
List<StationPair> objects) {
|
||||||
|
super(context, textViewResourceId, objects);
|
||||||
mHostActivity = (Activity) context;
|
mHostActivity = (Activity) context;
|
||||||
mHostActivity.bindService(new Intent(mHostActivity, EtdService.class),
|
mHostActivity.bindService(EtdService_.intent(mHostActivity).get(),
|
||||||
mConnection, Context.BIND_AUTO_CREATE);
|
mConnection, Context.BIND_AUTO_CREATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,42 +118,6 @@ public class FavoritesArrayAdapter extends ArrayAdapter<StationPair> {
|
|||||||
clearEtdListeners();
|
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
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
View view;
|
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;
|
package com.dougkeen.bart.data;
|
||||||
|
|
||||||
|
|
||||||
public enum RoutesColumns {
|
public enum RoutesColumns {
|
||||||
_ID("_id", "INTEGER", false),
|
_ID("_id", "INTEGER", false), FROM_STATION("FROM_STATION", "TEXT", false), TO_STATION(
|
||||||
FROM_STATION("FROM_STATION", "TEXT", false),
|
"TO_STATION", "TEXT", false), FARE("FARE", "TEXT", true), FARE_LAST_UPDATED(
|
||||||
TO_STATION("TO_STATION", "TEXT", false),
|
"FARE_LAST_UPDATED", "INTEGER", true), AVERAGE_TRIP_SAMPLE_COUNT(
|
||||||
FARE("FARE", "TEXT", true),
|
"AVE_TRIP_SAMPLE_COUNT", "INTEGER", true), AVERAGE_TRIP_LENGTH(
|
||||||
FARE_LAST_UPDATED("FARE_LAST_UPDATED", "INTEGER", true),
|
"AVE_TRIP_LENGTH", "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
|
// This class cannot be instantiated
|
||||||
private RoutesColumns(String string, String type, Boolean nullable) {
|
private RoutesColumns(String string, String type, Boolean nullable) {
|
||||||
@ -24,4 +21,13 @@ public enum RoutesColumns {
|
|||||||
protected String getColumnDef() {
|
protected String getColumnDef() {
|
||||||
return string + " " + sqliteType + (nullable ? "" : " NOT NULL");
|
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 TAG = "com.dougkeen.BartRunner";
|
||||||
public static final String API_KEY = "5LD9-IAYI-TRAT-MHHW";
|
public static final String API_KEY = "5LD9-IAYI-TRAT-MHHW";
|
||||||
public static final String ACTION_ALARM = "com.dougkeen.action.ALARM";
|
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 org.apache.commons.lang3.ObjectUtils;
|
||||||
|
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
import com.dougkeen.bart.data.CursorUtils;
|
import com.dougkeen.bart.data.CursorUtils;
|
||||||
import com.dougkeen.bart.data.RoutesColumns;
|
import com.dougkeen.bart.data.RoutesColumns;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
public class StationPair implements Parcelable {
|
public class StationPair implements Parcelable {
|
||||||
public StationPair(Station origin, Station destination) {
|
@JsonCreator
|
||||||
|
public StationPair(@JsonProperty("origin") Station origin,
|
||||||
|
@JsonProperty("destination") Station destination) {
|
||||||
super();
|
super();
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
this.destination = destination;
|
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) {
|
public StationPair(Parcel in) {
|
||||||
readFromParcel(in);
|
readFromParcel(in);
|
||||||
}
|
}
|
||||||
@ -34,22 +30,22 @@ public class StationPair implements Parcelable {
|
|||||||
RoutesColumns.FROM_STATION)),
|
RoutesColumns.FROM_STATION)),
|
||||||
Station.getByAbbreviation(CursorUtils.getString(cursor,
|
Station.getByAbbreviation(CursorUtils.getString(cursor,
|
||||||
RoutesColumns.TO_STATION)));
|
RoutesColumns.TO_STATION)));
|
||||||
pair.id = CursorUtils.getLong(cursor, RoutesColumns._ID);
|
|
||||||
pair.fare = CursorUtils.getString(cursor, RoutesColumns.FARE);
|
pair.fare = CursorUtils.getString(cursor, RoutesColumns.FARE);
|
||||||
pair.fareLastUpdated = CursorUtils.getLong(cursor,
|
pair.fareLastUpdated = CursorUtils.getLong(cursor,
|
||||||
RoutesColumns.FARE_LAST_UPDATED);
|
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;
|
return pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Long id;
|
|
||||||
private Station origin;
|
private Station origin;
|
||||||
private Station destination;
|
private Station destination;
|
||||||
private String fare;
|
private String fare;
|
||||||
private Long fareLastUpdated;
|
private long fareLastUpdated;
|
||||||
|
private int averageTripLength;
|
||||||
public Long getId() {
|
private int averageTripSampleCount;
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Station getOrigin() {
|
public Station getOrigin() {
|
||||||
return origin;
|
return origin;
|
||||||
@ -67,29 +63,35 @@ public class StationPair implements Parcelable {
|
|||||||
this.fare = fare;
|
this.fare = fare;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getFareLastUpdated() {
|
public long getFareLastUpdated() {
|
||||||
return fareLastUpdated;
|
return fareLastUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFareLastUpdated(Long fareLastUpdated) {
|
public void setFareLastUpdated(long fareLastUpdated) {
|
||||||
this.fareLastUpdated = 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) {
|
public boolean isBetweenStations(Station station1, Station station2) {
|
||||||
return (origin.equals(station1) && destination.equals(station2))
|
return (origin.equals(station1) && destination.equals(station2))
|
||||||
|| (origin.equals(station2) && destination.equals(station1));
|
|| (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
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
@ -89,7 +89,7 @@ public class BoardedDepartureService extends Service implements
|
|||||||
mServiceLooper = thread.getLooper();
|
mServiceLooper = thread.getLooper();
|
||||||
mServiceHandler = new ServiceHandler(mServiceLooper, this);
|
mServiceHandler = new ServiceHandler(mServiceLooper, this);
|
||||||
|
|
||||||
bindService(new Intent(this, EtdService.class), mConnection,
|
bindService(EtdService_.intent(this).get(), mConnection,
|
||||||
Context.BIND_AUTO_CREATE);
|
Context.BIND_AUTO_CREATE);
|
||||||
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||||
|
@ -10,20 +10,15 @@ import java.util.WeakHashMap;
|
|||||||
import org.apache.commons.lang3.math.NumberUtils;
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
|
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.support.v4.content.CursorLoader;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.dougkeen.bart.BartRunnerApplication;
|
import com.dougkeen.bart.BartRunnerApplication;
|
||||||
import com.dougkeen.bart.R;
|
import com.dougkeen.bart.R;
|
||||||
import com.dougkeen.bart.data.RoutesColumns;
|
|
||||||
import com.dougkeen.bart.model.Constants;
|
import com.dougkeen.bart.model.Constants;
|
||||||
import com.dougkeen.bart.model.Departure;
|
import com.dougkeen.bart.model.Departure;
|
||||||
import com.dougkeen.bart.model.RealTimeDepartures;
|
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.model.StationPair;
|
||||||
import com.dougkeen.bart.networktasks.GetRealTimeDeparturesTask;
|
import com.dougkeen.bart.networktasks.GetRealTimeDeparturesTask;
|
||||||
import com.dougkeen.bart.networktasks.GetScheduleInformationTask;
|
import com.dougkeen.bart.networktasks.GetScheduleInformationTask;
|
||||||
|
import com.googlecode.androidannotations.annotations.EService;
|
||||||
|
|
||||||
|
@EService
|
||||||
public class EtdService extends Service {
|
public class EtdService extends Service {
|
||||||
|
|
||||||
private IBinder mBinder;
|
private IBinder mBinder;
|
||||||
@ -106,19 +103,13 @@ public class EtdService extends Service {
|
|||||||
private class EtdServiceEngine {
|
private class EtdServiceEngine {
|
||||||
private static final int UNCERTAINTY_THRESHOLD = 17;
|
private static final int UNCERTAINTY_THRESHOLD = 17;
|
||||||
|
|
||||||
private Uri mUri;
|
|
||||||
|
|
||||||
private final StationPair mStationPair;
|
private final StationPair mStationPair;
|
||||||
|
|
||||||
private boolean mIgnoreDepartureDirection = false;
|
private boolean mIgnoreDepartureDirection = false;
|
||||||
|
|
||||||
private boolean mPendingEtdRequest = false;
|
private boolean mPendingEtdRequest = false;
|
||||||
|
|
||||||
private int mAverageTripLength;
|
private Map<EtdServiceListener, Boolean> mListeners;
|
||||||
private int mAverageTripSampleCount;
|
|
||||||
|
|
||||||
// We'll only use the keys
|
|
||||||
private WeakHashMap<EtdServiceListener, Boolean> mListeners;
|
|
||||||
|
|
||||||
private boolean mLimitToFirstNonDeparted = true;
|
private boolean mLimitToFirstNonDeparted = true;
|
||||||
|
|
||||||
@ -134,24 +125,9 @@ public class EtdService extends Service {
|
|||||||
|
|
||||||
public EtdServiceEngine(final StationPair route) {
|
public EtdServiceEngine(final StationPair route) {
|
||||||
mStationPair = route;
|
mStationPair = route;
|
||||||
mListeners = new WeakHashMap<EtdService.EtdServiceListener, Boolean>();
|
mListeners = new HashMap<EtdService.EtdServiceListener, Boolean>();
|
||||||
mRunnableQueue = new Handler();
|
mRunnableQueue = new Handler();
|
||||||
mLatestDepartures = new ArrayList<Departure>();
|
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,
|
protected void registerListener(EtdServiceListener listener,
|
||||||
@ -238,8 +214,7 @@ public class EtdService extends Service {
|
|||||||
};
|
};
|
||||||
mGetDeparturesTask = task;
|
mGetDeparturesTask = task;
|
||||||
Log.v(Constants.TAG, "Fetching data from server");
|
Log.v(Constants.TAG, "Fetching data from server");
|
||||||
task.execute(new StationPair(mStationPair.getOrigin(), mStationPair
|
task.execute(mStationPair);
|
||||||
.getDestination()));
|
|
||||||
notifyListenersOfRequestStart();
|
notifyListenersOfRequestStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,8 +246,7 @@ public class EtdService extends Service {
|
|||||||
};
|
};
|
||||||
Log.i(Constants.TAG, "Fetching data from server");
|
Log.i(Constants.TAG, "Fetching data from server");
|
||||||
mGetScheduleInformationTask = task;
|
mGetScheduleInformationTask = task;
|
||||||
task.execute(new StationPair(mStationPair.getOrigin(), mStationPair
|
task.execute(mStationPair);
|
||||||
.getDestination()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void applyScheduleInformation(ScheduleInformation result) {
|
protected void applyScheduleInformation(ScheduleInformation result) {
|
||||||
@ -363,7 +337,8 @@ public class EtdService extends Service {
|
|||||||
departure.setEstimatedTripTime(localAverageLength);
|
departure.setEstimatedTripTime(localAverageLength);
|
||||||
} else if (!departure.hasEstimatedTripTime()) {
|
} else if (!departure.hasEstimatedTripTime()) {
|
||||||
// Otherwise just assume the global average
|
// Otherwise just assume the global average
|
||||||
departure.setEstimatedTripTime(mAverageTripLength);
|
departure.setEstimatedTripTime(mStationPair
|
||||||
|
.getAverageTripLength());
|
||||||
}
|
}
|
||||||
} else if (departure.getRequiresTransfer()
|
} else if (departure.getRequiresTransfer()
|
||||||
&& !departure.hasAnyArrivalEstimate()) {
|
&& !departure.hasAnyArrivalEstimate()) {
|
||||||
@ -381,20 +356,16 @@ public class EtdService extends Service {
|
|||||||
|
|
||||||
// Update global average
|
// Update global average
|
||||||
if (mLatestScheduleInfo.getTripCountForAverage() > 0) {
|
if (mLatestScheduleInfo.getTripCountForAverage() > 0) {
|
||||||
int newAverageSampleCount = mAverageTripSampleCount
|
int newAverageSampleCount = mStationPair
|
||||||
|
.getAverageTripSampleCount()
|
||||||
+ mLatestScheduleInfo.getTripCountForAverage();
|
+ mLatestScheduleInfo.getTripCountForAverage();
|
||||||
int newAverage = (mAverageTripLength * mAverageTripSampleCount + localAverageLength
|
int newAverage = (mStationPair.getAverageTripLength()
|
||||||
|
* mStationPair.getAverageTripSampleCount() + localAverageLength
|
||||||
* mLatestScheduleInfo.getTripCountForAverage())
|
* mLatestScheduleInfo.getTripCountForAverage())
|
||||||
/ newAverageSampleCount;
|
/ newAverageSampleCount;
|
||||||
|
|
||||||
ContentValues contentValues = new ContentValues();
|
mStationPair.setAverageTripLength(newAverage);
|
||||||
contentValues.put(RoutesColumns.AVERAGE_TRIP_LENGTH.string,
|
mStationPair.setAverageTripSampleCount(newAverageSampleCount);
|
||||||
newAverage);
|
|
||||||
contentValues.put(
|
|
||||||
RoutesColumns.AVERAGE_TRIP_SAMPLE_COUNT.string,
|
|
||||||
newAverageSampleCount);
|
|
||||||
|
|
||||||
getContentResolver().update(mUri, contentValues, null, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user