package edu.purdue.app.map; import edu.purdue.app.map.MapData.Building; import android.app.SearchManager; import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.MatrixCursor; import android.net.Uri; import android.util.Log; /** Content Provider which interfaces with MapData for its data. * This only exists because Android demands a ContentProvider to provide dropdown box * search suggestions. This only supports the Query method; update/delete do nothing as * we are reading data from a JSON file. Also, this provider won't work outside of Purdue App, * as it needs to access Purdue App's resources. */ public class MapDataProvider extends ContentProvider { /** Strings for constructing URIs */ private static final String AUTH = "content://edu.purdue.app.map.MapDataProvider"; private static final String BUILDINGS_PATH = "buildings"; private static final String BIKERACKS_PATH = "bikeracks"; /** Publicly accessible URIs */ public static final Uri BUILDINGS_URI = Uri.parse(AUTH + "/" + BUILDINGS_PATH); public static final Uri BIKERACKS_URI = Uri.parse(AUTH + "/" + BIKERACKS_PATH); /** Column names for the returned cursor */ public static final String _ID = "_ID"; public static final String FULL_NAME = "FULL_NAME"; public static final String SHORT_NAME = "SHORT_NAME"; /** Class members */ MapData data; @Override public boolean onCreate() { data = null; return true; } @Override public String getType(Uri arg0) { return null; } /** Query data from the MapDataProvider. * uri : one of the URIs statically defined in this class (BUILDINGS_URI, BIKE_RACKS_URI, etc) * projection : unused * selection : unused * selection_args : unused * sortorder : unused * Wow, we really use the full power of this class, don't we? * * Returns a cursor to the data requested. Each row of the cursor is formatted as such: * _ID (int) SHORT_NAME (string) FULL_NAME (string) * With the types you'd expect for each. */ public Cursor query(Uri uri, String[] projection, String selection, String[] selection_args, String sortorder) { Log.d(MapActivity.LOG_MAP_TAG, "MapDataProvider query with uri: " + uri.toString()); data = new MapData(getContext()); // Determine which type of data the user requested. // For some reason I can't get the default UriMatcher class to work. Probably my fault. So this is more manual. String path = uri.getPathSegments().get(0); if (path.equals(BUILDINGS_PATH)) { return constructCursorBuildings(); } else if (path.equals(SearchManager.SUGGEST_URI_PATH_QUERY)) { // This request is coming from our search box. String query = uri.getLastPathSegment().toLowerCase(); return constructCursorBuildingsSearch(query); } return null; } /** Constructs and returns the cursor for all buildings recognized by the app */ private MatrixCursor constructCursorBuildings() { MatrixCursor c = new MatrixCursor(new String[]{_ID, FULL_NAME, SHORT_NAME}); int id = 0; for (Building loc : data.getBuildings()) { c.newRow().add(id++).add(loc.full_name).add(loc.short_name); } return c; } /** Constructs and returns the cursor for buildings which somehow match the query given as input */ private Cursor constructCursorBuildingsSearch(String query) { MatrixCursor c = new MatrixCursor(new String[]{"_ID", SearchManager.SUGGEST_COLUMN_TEXT_1, SearchManager.SUGGEST_COLUMN_TEXT_2, SearchManager.SUGGEST_COLUMN_INTENT_DATA}); int id = 0; for (Building loc : data.getBuildings()) { if (loc.full_name.toLowerCase().contains(query) || loc.short_name.toLowerCase().contains(query)) { c.newRow().add(id).add(loc.short_name).add(loc.full_name).add(loc.full_name); } } return c; } /** The update operating is not currently supported for this Provider, as the data is sourced from * JSON files. As such, this method does nothing. */ public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) { return -1; } /** The insert operation is not currently supported for this Provider, as it is all sourced from * JSON files. As such, this method does nothing. */ public Uri insert(Uri arg0, ContentValues arg1) { return null; } /** The delete operation is not currently supported for this Provider, as it is all sourced from * JSON files. As such, this method does nothing. */ public int delete(Uri arg0, String arg1, String[] arg2) { return -1; } }