diff options
author | Christopher Baines <cbaines8@gmail.com> | 2012-03-09 10:49:50 +0000 |
---|---|---|
committer | Christopher Baines <cbaines8@gmail.com> | 2012-03-09 10:49:50 +0000 |
commit | c2b3891c783dee1b4ef6fd70432aa7ef5e55c0d7 (patch) | |
tree | 69ba7ee4c132b2bf6ec138fdcaf0988309b40e56 /src/net | |
parent | a32b31c29d45b68918ec2a28fff7d87e675c6768 (diff) | |
parent | 4a45362d8823a84cf9c3c805c006331303a0da33 (diff) | |
download | southamptonuniversitymap-c2b3891c783dee1b4ef6fd70432aa7ef5e55c0d7.tar southamptonuniversitymap-c2b3891c783dee1b4ef6fd70432aa7ef5e55c0d7.tar.gz |
Merge branch 'dev-search' into dev
Conflicts:
gen/net/cbaines/suma/R.java
res/values/strings.xml
src/net/cbaines/suma/DataManager.java
src/net/cbaines/suma/MapActivity.java
src/net/cbaines/suma/POI.java
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/cbaines/suma/Bus.java | 7 | ||||
-rw-r--r-- | src/net/cbaines/suma/BusActivity.java | 3 | ||||
-rw-r--r-- | src/net/cbaines/suma/BusSpecificStopView.java | 1 | ||||
-rw-r--r-- | src/net/cbaines/suma/BusStopActivity.java | 1 | ||||
-rw-r--r-- | src/net/cbaines/suma/DataManager.java | 2 | ||||
-rw-r--r-- | src/net/cbaines/suma/MapActivity.java | 10 | ||||
-rw-r--r-- | src/net/cbaines/suma/MapContentProvider.java | 299 | ||||
-rw-r--r-- | src/net/cbaines/suma/POI.java | 3 | ||||
-rw-r--r-- | src/net/cbaines/suma/SearchActivity.java (renamed from src/net/cbaines/suma/FindActivity.java) | 15 |
9 files changed, 321 insertions, 20 deletions
diff --git a/src/net/cbaines/suma/Bus.java b/src/net/cbaines/suma/Bus.java index 865384f..9894e6b 100644 --- a/src/net/cbaines/suma/Bus.java +++ b/src/net/cbaines/suma/Bus.java @@ -115,7 +115,7 @@ public class Bus { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + gid; + result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @@ -128,7 +128,10 @@ public class Bus { if (getClass() != obj.getClass()) return false; Bus other = (Bus) obj; - if (id != other.id) + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) return false; return true; } diff --git a/src/net/cbaines/suma/BusActivity.java b/src/net/cbaines/suma/BusActivity.java index 336d336..04fe6cf 100644 --- a/src/net/cbaines/suma/BusActivity.java +++ b/src/net/cbaines/suma/BusActivity.java @@ -352,9 +352,6 @@ public class BusActivity extends ToastHelperActivity implements Preferences { private void displayTimetable(Timetable timetable) { visibleTimetable = (Timetable) timetable.clone(); - // Log.i(TAG, "Displaying timetable, it contains " + - // visibleTimetable.size() + " stops"); - if (timetable.size() == 0) { busContentMessage.setText("No Busses"); busContentMessage.setVisibility(View.VISIBLE); diff --git a/src/net/cbaines/suma/BusSpecificStopView.java b/src/net/cbaines/suma/BusSpecificStopView.java index 6502a5f..777d031 100644 --- a/src/net/cbaines/suma/BusSpecificStopView.java +++ b/src/net/cbaines/suma/BusSpecificStopView.java @@ -193,5 +193,4 @@ public class BusSpecificStopView extends LinearLayout implements OnClickListener } return false; } - } diff --git a/src/net/cbaines/suma/BusStopActivity.java b/src/net/cbaines/suma/BusStopActivity.java index 429f103..b80d5b4 100644 --- a/src/net/cbaines/suma/BusStopActivity.java +++ b/src/net/cbaines/suma/BusStopActivity.java @@ -394,7 +394,6 @@ public class BusStopActivity extends ToastHelperActivity implements OnCheckedCha e.printStackTrace(); } } - Log.i(TAG, "stops " + busStops); if (busStops.size() == 1) { diff --git a/src/net/cbaines/suma/DataManager.java b/src/net/cbaines/suma/DataManager.java index 7f94662..082631c 100644 --- a/src/net/cbaines/suma/DataManager.java +++ b/src/net/cbaines/suma/DataManager.java @@ -510,8 +510,6 @@ public class DataManager { Dao<RouteStop, Integer> routeStopsDao = null; if (routeStopsDao == null) routeStopsDao = helper.getRouteStopsDao(); - if (busDao == null) - busDao = helper.getBusDao(); if (busStopDao == null) busStopDao = helper.getBusStopDao(); diff --git a/src/net/cbaines/suma/MapActivity.java b/src/net/cbaines/suma/MapActivity.java index 374f568..8ed8e9e 100644 --- a/src/net/cbaines/suma/MapActivity.java +++ b/src/net/cbaines/suma/MapActivity.java @@ -857,8 +857,7 @@ public class MapActivity extends ToastHelperActivity implements MapViewConstants // Handle item selection switch (item.getItemId()) { case R.id.menu_find: - Intent i = new Intent(MapActivity.this, FindActivity.class); - startActivityForResult(i, 0); + onSearchRequested(); return true; case R.id.menu_preferences: Intent settingsActivity = new Intent(getBaseContext(), PreferencesActivity.class); @@ -958,13 +957,6 @@ public class MapActivity extends ToastHelperActivity implements MapViewConstants } } - @Override - public boolean onSearchRequested() { - Intent i = new Intent(MapActivity.this, FindActivity.class); - startActivityForResult(i, 0); - return false; - } - protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.i(TAG, "Got activity result"); if (resultCode == RESULT_OK) { diff --git a/src/net/cbaines/suma/MapContentProvider.java b/src/net/cbaines/suma/MapContentProvider.java new file mode 100644 index 0000000..a2b42c3 --- /dev/null +++ b/src/net/cbaines/suma/MapContentProvider.java @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.cbaines.suma; + +import java.sql.SQLException; +import java.util.List; + +import android.app.SearchManager; +import android.content.ContentProvider; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.net.Uri; +import android.provider.BaseColumns; +import android.util.Log; + +import com.j256.ormlite.android.AndroidCompiledStatement; +import com.j256.ormlite.android.apptools.OpenHelperManager; +import com.j256.ormlite.dao.Dao; +import com.j256.ormlite.stmt.PreparedQuery; +import com.j256.ormlite.stmt.QueryBuilder; +import com.j256.ormlite.stmt.StatementBuilder.StatementType; + +/** + * Provides access to the dictionary database. + */ +public class MapContentProvider extends ContentProvider { + String TAG = "MapContentProvider"; + + public static String AUTHORITY = "net.cbaines.suma.provider"; + // public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + // + "/building"); + + // MIME types used for searching words or looking up a single definition + public static final String BUILDINGS_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + + "/vnd.net.cbaines.suma.provider.building"; + public static final String BUILDING_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + + "/vnd.net.cbaines.suma.provider.building"; + public static final String BUS_STOPS_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + + "/vnd.net.cbaines.suma.provider.bus-stop"; + public static final String BUS_STOP_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + + "/vnd.net.cbaines.suma.provider.bus-stop"; + public static final String SITES_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + + "/vnd.net.cbaines.suma.provider.site"; + public static final String SITE_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + + "/vnd.net.cbaines.suma.provider.site"; + public static final String BUSES_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + + "/vnd.net.cbaines.suma.provider.bus"; + public static final String BUS_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + + "/vnd.net.cbaines.suma.provider.bus"; + + private DatabaseHelper helper; + + // UriMatcher stuff + private static final int SEARCH_BUILDINGS = 0; + private static final int GET_BUILDING = 1; + private static final int SEARCH_BUS_STOPS = 2; + private static final int GET_BUS_STOP = 3; + private static final int SEARCH_SITES = 4; + private static final int GET_SITE = 5; + private static final int SEARCH_BUSES = 6; + private static final int GET_BUS = 7; + private static final int SEARCH_SUGGEST = 8; + private static final int REFRESH_SHORTCUT = 9; + private static final UriMatcher sURIMatcher = buildUriMatcher(); + + /** + * Builds up a UriMatcher for search suggestion and shortcut refresh + * queries. + */ + private static UriMatcher buildUriMatcher() { + UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); + // to get definitions... + matcher.addURI(AUTHORITY, "building", SEARCH_BUILDINGS); + matcher.addURI(AUTHORITY, "building/*", GET_BUILDING); + matcher.addURI(AUTHORITY, "bus-stop", SEARCH_BUS_STOPS); + matcher.addURI(AUTHORITY, "bus-stop/*", GET_BUS_STOP); + matcher.addURI(AUTHORITY, "site", SEARCH_SITES); + matcher.addURI(AUTHORITY, "site/*", GET_SITE); + matcher.addURI(AUTHORITY, "bus", SEARCH_BUSES); + matcher.addURI(AUTHORITY, "bus/*", GET_BUS); + + // to get suggestions... + matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST); + matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST); + + /* + * The following are unused in this implementation, but if we include + * {@link SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} as a column in our + * suggestions table, we could expect to receive refresh queries when a + * shortcutted suggestion is displayed in Quick Search Box, in which + * case, the following Uris would be provided and we would return a + * cursor with a single item representing the refreshed suggestion data. + */ + matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT, REFRESH_SHORTCUT); + matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/*", REFRESH_SHORTCUT); + return matcher; + } + + @Override + public boolean onCreate() { + helper = OpenHelperManager.getHelper(this.getContext(), DatabaseHelper.class); + return true; + } + + /** + * Handles all the dictionary searches and suggestion queries from the + * Search Manager. When requesting a specific word, the uri alone is + * required. When searching all of the dictionary for matches, the + * selectionArgs argument must carry the search query as the first element. + * All other arguments are ignored. + */ + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { + + // Use the UriMatcher to see what kind of query we have and format the + // db query accordingly + switch (sURIMatcher.match(uri)) { + case SEARCH_SUGGEST: + if (selectionArgs == null) { + throw new IllegalArgumentException("selectionArgs must be provided for the Uri: " + uri); + } + try { + return getSuggestions(selectionArgs[0]); + } catch (SQLException e1) { + e1.printStackTrace(); + } + case SEARCH_BUILDINGS: + if (selectionArgs == null) { + throw new IllegalArgumentException("selectionArgs must be provided for the Uri: " + uri); + } + try { + return searchBuildings(selectionArgs[0]); + } catch (SQLException e) { + e.printStackTrace(); + } + case GET_BUILDING: + try { + return getBuilding(uri); + } catch (SQLException e) { + e.printStackTrace(); + } + case REFRESH_SHORTCUT: + try { + return refreshShortcut(uri); + } catch (SQLException e) { + e.printStackTrace(); + } + default: + throw new IllegalArgumentException("Unknown Uri: " + uri); + } + } + + private Cursor getSuggestions(String query) throws SQLException { + Log.v(TAG, "Got query for " + query); + + Dao<Building, String> buildingDao = helper.getBuildingDao(); + + QueryBuilder<Building, String> qb = buildingDao.queryBuilder(); + qb.where().like(Building.ID_FIELD_NAME, "%" + query + "%").or() + .like(Building.NAME_FIELD_NAME, "%" + query + "%"); + PreparedQuery<Building> preparedQuery = qb.prepare(); + + List<Building> buildings = buildingDao.query(preparedQuery); + Log.v(TAG, "Returning " + buildings.size() + " buildings"); + + String[] columnNames = { BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1 }; + + MatrixCursor cursor = new MatrixCursor(columnNames, buildings.size()); + + int id = 0; + for (Building building : buildings) { + Log.v(TAG, "Building " + id + ", " + building.name); + Object[] values = { id++, building.name }; + cursor.addRow(values); + } + + return cursor; + } + + private Cursor searchBuildings(String query) throws SQLException { + Dao<Building, String> buildingDao = helper.getBuildingDao(); + + QueryBuilder<Building, String> qb = buildingDao.queryBuilder(); + qb.where().eq(Building.ID_FIELD_NAME, "%" + query + "%").or().eq(Building.NAME_FIELD_NAME, "%" + query + "%"); + PreparedQuery<Building> preparedQuery = qb.prepare(); + + AndroidCompiledStatement compiledStatement = (AndroidCompiledStatement) preparedQuery.compile(helper + .getConnectionSource().getReadOnlyConnection(), StatementType.SELECT); + Cursor cursor = compiledStatement.getCursor(); + + return cursor; + } + + private Cursor getBuilding(Uri uri) throws SQLException { + String buildingID = uri.getLastPathSegment(); + Dao<Building, String> buildingDao = helper.getBuildingDao(); + + QueryBuilder<Building, String> qb = buildingDao.queryBuilder(); + qb.where().eq(Building.ID_FIELD_NAME, buildingID); + PreparedQuery<Building> preparedQuery = qb.prepare(); + + AndroidCompiledStatement compiledStatement = (AndroidCompiledStatement) preparedQuery.compile(helper + .getConnectionSource().getReadOnlyConnection(), StatementType.SELECT); + Cursor cursor = compiledStatement.getCursor(); + + return cursor; + } + + private Cursor refreshShortcut(Uri uri) throws SQLException { + /* + * This won't be called with the current implementation, but if we + * include {@link SearchManager#SUGGEST_COLUMN_SHORTCUT_ID} as a column + * in our suggestions table, we could expect to receive refresh queries + * when a shortcutted suggestion is displayed in Quick Search Box. In + * which case, this method will query the table for the specific word, + * using the given item Uri and provide all the columns originally + * provided with the suggestion query. + */ + String buildingID = uri.getLastPathSegment(); + Dao<Building, String> buildingDao = helper.getBuildingDao(); + + QueryBuilder<Building, String> qb = buildingDao.queryBuilder(); + qb.where().eq(Building.ID_FIELD_NAME, buildingID); + PreparedQuery<Building> preparedQuery = qb.prepare(); + + AndroidCompiledStatement compiledStatement = (AndroidCompiledStatement) preparedQuery.compile(helper + .getConnectionSource().getReadOnlyConnection(), StatementType.SELECT); + Cursor cursor = compiledStatement.getCursor(); + + return cursor; + } + + /** + * This method is required in order to query the supported types. It's also + * useful in our own query() method to determine the type of Uri received. + */ + @Override + public String getType(Uri uri) { + switch (sURIMatcher.match(uri)) { + case SEARCH_BUILDINGS: + return BUILDINGS_MIME_TYPE; + case GET_BUILDING: + return BUILDING_MIME_TYPE; + case SEARCH_BUS_STOPS: + return BUS_STOPS_MIME_TYPE; + case GET_BUS_STOP: + return BUS_STOP_MIME_TYPE; + case SEARCH_SITES: + return SITES_MIME_TYPE; + case GET_SITE: + return SITE_MIME_TYPE; + case SEARCH_BUSES: + return BUSES_MIME_TYPE; + case GET_BUS: + return BUS_MIME_TYPE; + case SEARCH_SUGGEST: + return SearchManager.SUGGEST_MIME_TYPE; + case REFRESH_SHORTCUT: + return SearchManager.SHORTCUT_MIME_TYPE; + default: + throw new IllegalArgumentException("Unknown URL " + uri); + } + } + + // Other required implementations... + + @Override + public Uri insert(Uri uri, ContentValues values) { + throw new UnsupportedOperationException(); + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + throw new UnsupportedOperationException(); + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/net/cbaines/suma/POI.java b/src/net/cbaines/suma/POI.java index c84f90e..f8c1f89 100644 --- a/src/net/cbaines/suma/POI.java +++ b/src/net/cbaines/suma/POI.java @@ -47,7 +47,8 @@ public abstract class POI { @DatabaseField(id = true) public String id; - public int distTo = -1; // Used by the comparator to store distances, then later by the gui to display them. + public int distTo = -1; // Used by the comparator to store distances, then + // later by the gui to display them. public String type; diff --git a/src/net/cbaines/suma/FindActivity.java b/src/net/cbaines/suma/SearchActivity.java index 669249c..f7f5e55 100644 --- a/src/net/cbaines/suma/FindActivity.java +++ b/src/net/cbaines/suma/SearchActivity.java @@ -27,6 +27,7 @@ import java.util.List; import org.osmdroid.util.GeoPoint; +import android.app.SearchManager; import android.content.Context; import android.content.Intent; import android.location.Location; @@ -52,11 +53,14 @@ import com.j256.ormlite.dao.Dao; import com.j256.ormlite.stmt.PreparedQuery; import com.j256.ormlite.stmt.QueryBuilder; -public class FindActivity extends OrmLiteBaseActivity<DatabaseHelper> implements Runnable, TextWatcher, +public class SearchActivity extends OrmLiteBaseActivity<DatabaseHelper> implements Runnable, TextWatcher, OnItemClickListener, LocationListener, OnItemLongClickListener { final static String TAG = "FindActivity"; + public static final String ORIGIN = "o"; + public static final int MAP_ACTIVITY = 0; + private EditText searchBar; private ListView listItems; private ProgressBar progBar; @@ -243,9 +247,18 @@ public class FindActivity extends OrmLiteBaseActivity<DatabaseHelper> implements super.onCreate(savedInstanceState); setContentView(R.layout.find_activity); + Log.i(TAG, "FindActivity started"); + searchBar = (EditText) findViewById(R.id.searchBar); searchBar.addTextChangedListener(this); + Intent intent = getIntent(); + if (Intent.ACTION_SEARCH.equals(intent.getAction())) { + String query = intent.getStringExtra(SearchManager.QUERY); + Log.i(TAG, "Searching for " + query); + searchBar.setText(query); + } + listItems = (ListView) findViewById(R.id.findListItems); listItems.setOnItemClickListener(this); listItems.setOnItemLongClickListener(this); |