如何在我的资产中获取适用于SearchManager.SUGGEST_COLUMN_ICON_1列的图像的Uri?

Ian*_*lie 6 search android

我已成功将我的应用程序的国家/地区搜索整合到全局搜索工具中,现在我正在尝试在搜索建议旁边显示每个国家/地区的标记.在我的应用程序内部搜索以这种方式工作,但当然我可以控制列表及其视图绑定自己.所以我知道标志都在那里,我可以在我的应用程序的其余部分使用它们.

当我尝试将Uri提供给我的Assets中的.gif文件时出现问题.根据搜索文档,带有键的列的值SearchManager.SUGGEST_COLUMN_ICON_1应该是图像的Uri.

下面是代码的样子.为了响应这种ContentProvider方法,public Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)我正在创建一个MatrixCursor将我的国家数据库中的列映射到搜索工具所需的列.国家名称显示正常,我可以选择它们并在我的申请中正确回复.

我试过用三种不同的方式形成Uri:

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

它们都导致了同样的事情 - 我的每个建议旁边的应用程序图标,我可以通过使用空字符串的值获得.

有没有可行的Uri?如何在搜索建议旁边显示国家/地区标志图标?

谢谢伊恩

完整来源:

private Cursor search (String query, int limit)  {
    query = query.toLowerCase ();
    String[] requestedColumns = new String[]  {
            BaseColumns._ID, 
            SearchManager.SUGGEST_COLUMN_TEXT_1,
            SearchManager.SUGGEST_COLUMN_ICON_1,
    };
    String[] queryColumns = new String[]  {
            WorldInfoDatabaseAdapter.KEY_ROWID, 
            WorldInfoDatabaseAdapter.KEY_COUNTRYNAME,
            WorldInfoDatabaseAdapter.KEY_COUNTRYCODE
    };

    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);
        rowCount++;
    }

    return results;
}
Run Code Online (Sandbox Code Playgroud)

编辑:我尝试过其他变体,包括将图像从资源移动到原始文件夹.没有任何效果.这是我试过的uri:

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";
Run Code Online (Sandbox Code Playgroud)

唯一可行的工作是如果我将测试标志移动到我的drawable文件夹中:

flagUriStr = "android.resource://com.lesliesoftware.worldinfo/" + 
    R.drawable.small_ca_flag;
Run Code Online (Sandbox Code Playgroud)

Ian*_*lie 7

遗憾的是,经过多次搜索后,我得出的结论是,您无法将uri返回到搜索工具的图像资源.我所做的是将我的旗帜图像移动到资源(因此它们不会混乱我的应用程序的资源,我为标志图像创建了一个库)并使用资源uri.因此,在我的提供程序中,我在循环中将代码看起来像这样,将数据库结果映射到搜索结果:

            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);
            }  
Run Code Online (Sandbox Code Playgroud)

并查找如下所示的代码:

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;
    ...
Run Code Online (Sandbox Code Playgroud)

我只需要确保创建一个测试,验证所有有标志的国家都会返回预期的结果.


vid*_*ige 5

你先创建一个AssetProvider.我们稍后将创建将由此类处理的uris.

public class AssetsProvider extends ContentProvider {

    private AssetManager assetManager;
    public static final Uri CONTENT_URI = 
            Uri.parse("content://com.example.assets");

    @Override
    public int delete(Uri arg0, String arg1, String[] arg2) { return 0; }

    @Override
    public String getType(Uri uri) { return null; }

    @Override
    public Uri insert(Uri uri, ContentValues values) { return null; }

    @Override
    public boolean onCreate() {
        assetManager = getContext().getAssets();
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; }

    @Override
    public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
        String path = uri.getPath().substring(1);
        try {
            AssetFileDescriptor afd = assetManager.openFd(path);
            return afd;
        } catch (IOException e) {
            throw new FileNotFoundException("No asset found: " + uri, e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

很多样板在那里.当然,必要的方法是openAssetFile将传递给它的uri的路径翻译成一个AssetFileDescriptor.为了让Android能够将URI传递给此提供程序,请记住将其包含在application-tag内的AndroidManifest.xml文件中:

    <provider
        android:name=".AssetsProvider"
        android:authorities="com.example.assets" />
Run Code Online (Sandbox Code Playgroud)

现在,在您的搜索提供程序中,您可以创建如下的URI:

content://com.example.assets/my_folder_inside_assets/myfile.png
Run Code Online (Sandbox Code Playgroud)