Ian Leslie Ian Leslie - 1 month ago 8
Android Question

How do I get a Uri to an image in my Assets that will work for the SearchManager.SUGGEST_COLUMN_ICON_1 column?

I have successfully integrated my app's country search into the global search facility and now I am trying to display each country's flag next to the search suggestions. Search inside my app works this way but of course I have control of the list and its view binding myself. So I know the flags are all there and I can use them in the rest of my app.

The trouble comes when I try to supply a Uri to a .gif file in my Assets. According to the search documentation the value of the column with the key

should be a Uri to the image.

Below is what the code looks like. In response to the
public Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
I am creating a
that maps columns from my country database to those required by the search facility. The country names show up fine and I can select them and correctly respond in my application.

I have tried forming the Uri three different ways:

// String flagUri = "file:///android_asset/" + flagPath;
// String flagUri = "file:///assets/" + flagPath;
String flagUri = "android.resource://com.lesliesoftware.worldinfo.WorldInfoActivity/assets/" + flagPath;
columnValues.add (flagUri);

They all lead to the same thing - my application icon next to each suggestion which I can get by using a value of empty string.

Is there a Uri that will work? How can I get the country flag icon next to the search suggestions?

Thanks Ian

The full source:

private Cursor search (String query, int limit) {
query = query.toLowerCase ();
String[] requestedColumns = new String[] {
String[] queryColumns = new String[] {

return packageResults (query, requestedColumns, queryColumns, limit);

private Cursor packageResults (String query, String[] requestedColumns, String[] queryMappedColumns, int limit) {
if (requestedColumns.length != queryMappedColumns.length)
throw new IllegalArgumentException ("Internal error: requested columns do not map to query columns");

MatrixCursor results = new MatrixCursor (requestedColumns);

// Query the country list returns columns: KEY_ROWID, KEY_COUNTRYNAME, KEY_COUNTRYCODE
Cursor dbResults = myDbHelper.getCountryList (query);

// Verify that the query columns are available
for (int index = 0; index < queryMappedColumns.length; index++) {
int col = dbResults.getColumnIndex (queryMappedColumns[index]);
if (col == -1)
throw new IllegalArgumentException ("Internal error: requested column '" +
queryMappedColumns[index] + "' was not returned from the database.");

// Loop over the database results building up the requested results
int rowCount = 0;
while (dbResults.moveToNext () && rowCount < limit) {
Vector<String> columnValues = new Vector<String> ();
for (int index = 0; index < requestedColumns.length; index++) {
if (requestedColumns[index].compareTo (SearchManager.SUGGEST_COLUMN_ICON_1) == 0) {
String flagPath = "flags/small/" + dbResults.getString (
dbResults.getColumnIndexOrThrow (queryMappedColumns[index]))
+ "-flag.gif";
// String flagUri = "file:///android_asset/" + flagPath;
// String flagUri = "file:///assets/" + flagPath;
String flagUri = "android.resource://com.lesliesoftware.worldinfo.WorldInfoActivity/assets/" + flagPath;
columnValues.add (flagUri);
} else {
// Add the mapped query column values from the database
String colValue = dbResults.getString (dbResults.getColumnIndexOrThrow (queryMappedColumns[index]));
columnValues.add (colValue);

results.addRow (columnValues);

return results;

I have tried other variations including moving the images from the assets to the raw folder. Nothing worked. Here are the uri's I tried:

flagUriStr = "android.resource://com.lesliesoftware.worldinfo/raw/flags/small/" +
countryCode + "-flag.gif";

flagUriStr = "android.resource://com.lesliesoftware.worldinfo/assets/flags/small/" +
countryCode + "-flag.gif";

flagUriStr = "android.resource://com.lesliesoftware.worldinfo/assets/flags/small/" +
countryCode + "-flag";

flagUriStr = "android.resource://com.lesliesoftware.worldinfo/raw/" +
countryCode + "-flag.gif";

flagUriStr = "android.resource://com.lesliesoftware.worldinfo/raw/" +
countryCode + "-flag";

The only uri that did work was if I moved a test flag into my drawable folder:

flagUriStr = "android.resource://com.lesliesoftware.worldinfo/" +


Sadly after much searching around I have reached the conclusion that you cannot return a uri to an image asset to the search facility. What I did instead was move my flag images to the resources (so they do not clutter up my app's resources I created a library for the flag images) and use resource uri's. So, in my provider I have code that looks like this in the loop that maps database results to search results:

            if (requestedColumns[index].compareTo (SearchManager.SUGGEST_COLUMN_ICON_1) == 0)  {
                //  Translate the country code into a flag icon uri
                String countryCode = dbResults.getString (
                        dbResults.getColumnIndexOrThrow (queryMappedColumns[index]));

                int flagImageID = FlagLookup.smallFlagResourceID (countryCode);
                String flagUriStr = "android.resource://com.lesliesoftware.worldinfo/" + flagImageID;
                columnValues.add (flagUriStr);

and look up code that looks like this:

static public int smallFlagResourceID (String countryCode)  {
    if (countryCode == null || countryCode.length () == 0)
        return R.drawable.flag_small_none;

    if (countryCode.equalsIgnoreCase ("aa"))
        return R.drawable.flag_small_aa;
    else if (countryCode.equalsIgnoreCase ("ac"))
        return R.drawable.flag_small_ac;
    else if (countryCode.equalsIgnoreCase ("ae"))
        return R.drawable.flag_small_ae;

I will just have to make sure I create a test that verifies that all countries that have flags returns the expected results.