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;
}
}