问题
I'm implementing my own SearchRecentSuggestionsProvider
and everything's working except one thing: I can't get the device search to display icons for the results. I'd like to display images from my application's data folder (located at /{sdcard}/Android/data/package_name/files/
)
According to the documentation, it's achievable by using SearchManager.SUGGEST_COLUMN_ICON_1
, and it apparently supports a number of schemes, including ContentResolver.SCHEME_FILE
, which is file
. Here's a quote from the official docs:
Column name for suggestions cursor. Optional. If your cursor includes this column, then all suggestions will be provided in a format that includes space for two small icons, one at the left and one at the right of each suggestion. The data in the column must be a resource ID of a drawable, or a URI in one of the following formats:
content (
SCHEME_CONTENT
)android.resource (
SCHEME_ANDROID_RESOURCE
)file (
SCHEME_FILE
)
I've tried a number of obvious things, including manual creation of the file URI and automated creation using Uri.Builder()
. None of this worked.
I also found someone else asking about the same thing on Google Groups, and it's sadly unanswered: https://groups.google.com/forum/#!topic/android-developers/MJj7GIaONjc
Does anyone have any experience in getting the device search to display local images from the device?
UPDATE (December 15):
I've just tried using the ContentProvider
with a SearchView
as the searchable info, and it works exactly as expected - including the cover art images. Still, global search doesn't show it...
回答1:
I had a similar issue and could not make the other solutions work. I finally substituted the cursor with a new one containing the data I needed in query().
public class RecentQueriesProvider extends SearchRecentSuggestionsProvider {
public final static String AUTHORITY = "com.package.RecentQueriesProvider";
public final static int MODE = DATABASE_MODE_QUERIES;
public RecentQueriesProvider() {
setupSuggestions(AUTHORITY, MODE);
}
// We override query() to replace the history icon in the recent searches suggestions. We create a new cursor
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor superCursor = super.query(uri, projection, selection, selectionArgs, sortOrder);
Uri iconUri = Uri.parse("android.resource://" + getContext().getPackageName() + "/drawable/ic_action_time");
MatrixCursor newCursor = new MatrixCursor(superCursor.getColumnNames());
superCursor.moveToFirst();
while (superCursor.moveToNext()){
newCursor.addRow(new Object[]{
superCursor.getInt(superCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_FORMAT)),
iconUri,
superCursor.getString(superCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1)),
superCursor.getString(superCursor.getColumnIndex("suggest_intent_query")),
superCursor.getInt(superCursor.getColumnIndex("_id"))
});
}
return newCursor;
}
}
回答2:
One way is to copy source code from android.content.SearchRecentSuggestionsProvider
, place it in your class that extends ContentProvider, and customize setupSuggestions(String, int)
. Specifically, you would be changing this:
Uri uriFile = Uri.fromFile(new File("path/to/file"));
mSuggestionProjection = new String [] {
"0 AS " + SearchManager.SUGGEST_COLUMN_FORMAT,
// Here, you would return a file uri: 'uriFile'
"'android.resource://system/"
+ com.android.internal.R.drawable.ic_menu_recent_history + "' AS "
+ SearchManager.SUGGEST_COLUMN_ICON_1,
"display1 AS " + SearchManager.SUGGEST_COLUMN_TEXT_1,
"query AS " + SearchManager.SUGGEST_COLUMN_QUERY,
"_id"
};
I prefer the following though. Extend SearchRecentSuggestionsProvider
and override the query(...)
method. Here, intercept SearchManager.SUGGEST_URI_PATH_QUERY
and return a cursor.
public class SearchSuggestionProvider extends SearchRecentSuggestionsProvider {
private UriMatcher matcher;
private static final int URI_MATCH_SUGGEST = 1;
public SearchSuggestionProvider() {
super();
matcher = new UriMatcher(UriMatcher.NO_MATCH);
// Add uri to return URI_MATCH_SUGGEST
matcher.addURI(SearchSuggestionProvider.class.getName(),
SearchManager.SUGGEST_URI_PATH_QUERY, URI_MATCH_SUGGEST);
setupSuggestions(SearchSuggestionProvider.class.getName(),
DATABASE_MODE_QUERIES);
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// special case for actual suggestions (from search manager)
if (matcher.match(uri) == URI_MATCH_SUGGEST) {
// File to use
File f = new File("/path/to/file");
Uri uriFile = Uri.fromFile(f);
final String[] PROJECTION = new String[] {
"_id",
"display1 AS " + SearchManager.SUGGEST_COLUMN_TEXT_1,
"query AS " + SearchManager.SUGGEST_COLUMN_QUERY,
"'" + uriFile + "'" + " AS " + SearchManager.SUGGEST_COLUMN_ICON_1,
};
final Uri URI = Uri.parse("content://" +
SearchSuggestionProvider.class.getName() + "/suggestions");
// return cursor
return getContext().getContentResolver().query(
URI,
PROJECTION,
"display1 LIKE ?",
new String[] {selectionArgs[0] + "%"},
"date DESC");
}
// Let super method handle the query if the check fails
return super.query(uri, projection, selection, selectionArgs, sortOrder);
}
}
来源:https://stackoverflow.com/questions/19800360/using-searchmanagers-suggest-column-icon-1-to-display-a-local-file