Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

recent searches are not displayed, custom suggestions are

I have a search widget (SearchView), displaying custom suggestions while typing. I've followed official guide to add recent queries to suggestions, but I still have custom suggestions ONLY.
For each search, my fragment call this function (verified) :

private void addQueryToRecent(String query) {
    SearchRecentSuggestions suggestions = new SearchRecentSuggestions(getActivity(),
            MyCustomSuggestionProvider.AUTHORITY,
            MyCustomSuggestionProvider.MODE);
    suggestions.saveRecentQuery(query, "recent");
}

My suggestion provider seems ok :

public class MyCustomSuggestionProvider extends SearchRecentSuggestionsProvider {

public final static String AUTHORITY = "com.zgui.musicshaker.provider.MyCustomSuggestionProvider";
public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;

public MyCustomSuggestionProvider() {
    setupSuggestions(AUTHORITY, MODE);
}

@Override
public Cursor query(Uri uri, String[] projection, String sel,
        String[] selArgs, String sortOrder) {
    //retrieves a custom suggestion cursor and returns it
}
}

searchable.xml :

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="artist, track informations..."
android:label="@string/app_name"
android:queryAfterZeroResults="true"
android:searchSuggestAuthority="com.zgui.musicshaker.provider.MyCustomSuggestionProvider"
android:searchSuggestSelection=" ?" />

manifest :

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>

        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />
    </activity>
<provider
        android:name=".provider.MyCustomSuggestionProvider"
        android:authorities="com.zgui.musicshaker.provider.MyCustomSuggestionProvider"
        android:enabled="true" >
    </provider>

Acording to that post, I'm supposed to have a recent search db at data/data/app.package.name/databases/databasename.db, but I don't seem to...
Or maybe am I supposed to add the "recent search suggestions" myself in the cursor that MyCustomSuggestionProvider.query() returns ? Any idea is welcome...

like image 673
elgui Avatar asked Jul 04 '12 12:07

elgui


3 Answers

Found it: it wasn't clear at all on Android Documentation, but I need to make the request myself and merge cursors in MyCustomSuggestionProvider.query():

Cursor recentCursor = super.query(uri, projection, sel, selArgs,
            sortOrder);
Cursor[] cursors = new Cursor[] { recentCursor, customCursor};
return new MergeCursor(cursors);

Make sure you have the same columns in both though...

like image 139
elgui Avatar answered Nov 12 '22 01:11

elgui


private static final String[] SEARCH_SUGGEST_COLUMNS = {
        SearchManager.SUGGEST_COLUMN_FORMAT,
        SearchManager.SUGGEST_COLUMN_ICON_1,
        SearchManager.SUGGEST_COLUMN_TEXT_1,
        SearchManager.SUGGEST_COLUMN_INTENT_DATA,
        BaseColumns._ID };

Above is the list of columns used in recent search suggestions db, use same list for your custom search suggestions to avoid clashes

like image 2
Sachin Avatar answered Nov 12 '22 02:11

Sachin


To expand on elgui's answer, here's an example of how I matched up the columns:

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        final Cursor recentsCursor = super.query(uri, projection, selection, selectionArgs, sortOrder);
        final Cursor customResultsCursor = queryCache(recentsCursor, selectionArgs[0]);
        return new MergeCursor(new Cursor[]{recentsCursor, customResultsCursor});
    }

    private Cursor queryCache(Cursor recentsCursor, String userQuery) { 
        final MatrixCursor arrayCursor = new MatrixCursor(recentsCursor.getColumnNames());

        final int formatColumnIndex = recentsCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_FORMAT);
        final int iconColumnIndex = recentsCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1);
        final int displayColumnIndex = recentsCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1);
        final int queryColumnIndex = recentsCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_QUERY);
        final int idIndex = recentsCursor.getColumnIndex("_id");

        final int columnCount = recentsCursor.getColumnCount();

        // Populate data here
        int startId = Integer.MAX_VALUE;

        for (String customSearchResult : customSearchResults) {
            final Object[] newRow = new Object[columnCount];
            if (formatColumnIndex >= 0) newRow[formatColumnIndex] = 0;
            if (iconColumnIndex >= 0) newRow[iconColumnIndex] = R.drawable.invisible;
            if (displayColumnIndex >= 0) newRow[displayColumnIndex] = customSearchResult;
            if (queryColumnIndex >= 0) newRow[queryColumnIndex] = customSearchResult;
            newRow[idIndex] = startId--;
            arrayCursor.addRow(newRow);
        }       

        return arrayCursor;
    }

Since this is based on the implementation details of SearchRecentSuggestionsProvider, it could still fail in other situations and it might be more worthwhile to write your own recents history and do them together.

like image 2
Learn OpenGL ES Avatar answered Nov 12 '22 01:11

Learn OpenGL ES