To get Places Autocomplete API results in a SearchView, you'll first need a ContentProvider for the API.
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.provider.BaseColumns;
import android.util.Log;
public class PlacesSuggestionProvider extends ContentProvider {
private static final String LOG_TAG = "ExampleApp";
public static final String AUTHORITY = "com.example.google.places.search_suggestion_provider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/search");
// UriMatcher constant for search suggestions
private static final int SEARCH_SUGGEST = 1;
private static final UriMatcher uriMatcher;
private static final String[] SEARCH_SUGGEST_COLUMNS = {
BaseColumns._ID,
SearchManager.SUGGEST_COLUMN_TEXT_1,
SearchManager.SUGGEST_COLUMN_TEXT_2,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID
};
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);
uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST);
}
@Override
public int delete(Uri uri, String arg1, String[] arg2) {
throw new UnsupportedOperationException();
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case SEARCH_SUGGEST:
return SearchManager.SUGGEST_MIME_TYPE;
default:
throw new IllegalArgumentException("Unknown URL " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues arg1) {
throw new UnsupportedOperationException();
}
@Override
public boolean onCreate() {
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
Log.d(LOG_TAG, "query = " + uri);
// Use the UriMatcher to see what kind of query we have
switch (uriMatcher.match(uri)) {
case SEARCH_SUGGEST:
Log.d(LOG_TAG, "Search suggestions requested.");
MatrixCursor cursor = new MatrixCursor(SEARCH_SUGGEST_COLUMNS, 1);
cursor.addRow(new String[] {
"1", "Search Result", "Search Result Description", "content_id"
});
return cursor;
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
}
@Override
public int update(Uri uri, ContentValues arg1, String arg2, String[] arg3) {
throw new UnsupportedOperationException();
}
}
Then add your Places Autocomplete API client code into the query method on the content provider. You extract the user input as follows:
String query = uri.getLastPathSegment().toLowerCase();
Add the PlacesSuggestionProvider to your AndroidManifest, and make sure your activity has a searchable configuration.
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity android:name=".PlacesSearchViewActivity" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
<provider
android:name="com.example.google.places.PlacesSuggestionProvider"
android:authorities="com.example.google.places.search_suggestion_provider"
android:syncable="false" />
</application>
</manifest>
And make sure your searchable configuration (res/xml/searchable.xml) has a search suggest authority.
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search_hint"
android:searchSuggestAuthority="com.example.google.places.search_suggestion_provider">
</searchable>
The authority should be the same in AndroidManifest.xml, searchable.xml, and your content provider.
Create a options menu for your ActionBar that includes a SearchView (/res/menu/options_menu.xml).
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_search"
android:title="@string/menu_search"
android:icon="@drawable/ic_menu_search"
android:showAsAction="collapseActionView|ifRoom"
android:actionViewClass="android.widget.SearchView" />
</menu>
Configure your Activity with a SearchView that's associated with your searchable configuration/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the options menu from XML
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
// Tells your app's SearchView to use this activity's searchable configuration
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
return true;
}
A few key docs are:
Adding Custom Suggestions:
http://developer.android.com/guide/topics/search/adding-custom-suggestions.html
Creating a Content Provider:
http://developer.android.com/guide/topics/providers/content-provider-creating.html
Using a Search Widget:
http://developer.android.com/guide/topics/search/search-dialog.html#UsingSearchWidget