Android 如何在我的资产中为SearchManager.SUGGEST\u COLUMN\u ICON\u 1 COLUMN工作的图像获取Uri?
我已经成功地将我的应用程序的国家搜索集成到全球搜索设施中,现在我正试图在搜索建议旁边显示每个国家的国旗。在我的应用程序中搜索是这样工作的,但当然我自己可以控制列表和它的视图绑定。所以我知道这些标志都在那里,我可以在我的应用程序的其余部分使用它们 当我试图为我的资产中的.gif文件提供Uri时,麻烦就来了。根据搜索文档,带有键的列的值Android 如何在我的资产中为SearchManager.SUGGEST\u COLUMN\u ICON\u 1 COLUMN工作的图像获取Uri?,android,search,Android,Search,我已经成功地将我的应用程序的国家搜索集成到全球搜索设施中,现在我正试图在搜索建议旁边显示每个国家的国旗。在我的应用程序中搜索是这样工作的,但当然我自己可以控制列表和它的视图绑定。所以我知道这些标志都在那里,我可以在我的应用程序的其余部分使用它们 当我试图为我的资产中的.gif文件提供Uri时,麻烦就来了。根据搜索文档,带有键的列的值SearchManager.SUGGEST\u column\u ICON\u 1应该是图像的Uri 下面是代码的样子。为了响应ContentProvider方法公共
SearchManager.SUGGEST\u column\u ICON\u 1
应该是图像的Uri
下面是代码的样子。为了响应ContentProvider
方法公共游标查询(Uri Uri、字符串[]投影、字符串选择、字符串[]selectionArgs、字符串排序器)
我正在创建一个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);
它们都指向同一件事——我的应用程序图标位于每个建议旁边,我可以使用空字符串值获得这些建议
有一个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;
}
唯一有效的uri是如果我将测试标志移动到我的drawable文件夹中:
flagUriStr = "android.resource://com.lesliesoftware.worldinfo/" +
R.drawable.small_ca_flag;
遗憾的是,在进行了大量搜索之后,我得出了一个结论:您无法将图像资产的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);
}
并查找如下所示的代码:
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;
...
content://com.example.assets/my_folder_inside_assets/myfile.png
我只需确保我创建了一个测试,以验证所有具有标志的国家/地区都返回了预期的结果。您首先要创建一个
AssetProvider
。稍后我们将创建将由此类处理的URI
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);
}
}
}
里面有很多样板。基本方法当然是openAssetFile
,它只是将传递给它的uri路径转换为assetfile描述符
。为了让Android能够将URI传递给此提供商,请记住将其包含在应用程序标记内的AndroidManifest.xml文件中:
<provider
android:name=".AssetsProvider"
android:authorities="com.example.assets" />
只是想补充一下vidstige的回答:我想提供我先前下载到临时缓存目录的文件,这样我就可以从我的搜索内容提供者中的URL向SearchView建议提供外部图像缩略图。我使用了这个函数:
@Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
String filename = uri.getLastPathSegment();
try {
File file = new File(getContext().getCacheDir(), filename);
// image downloading has to be done in the search results provider, since it's not on the UI thread like this guy.
//downloadAndSaveFile("http://urdomain/urfile.png", filename);
AssetFileDescriptor afd = new AssetFileDescriptor(
ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY | ParcelFileDescriptor.MODE_WORLD_READABLE),
0, AssetFileDescriptor.UNKNOWN_LENGTH);
return afd;
} catch (IOException e) {
throw new FileNotFoundException("No asset found: " + uri);
}
}
我能够使用以下uri引用SearchRecentSuggestionsProvider中drawable中的图像
"android.resource://your.package.here/drawable/image_name
谢谢,这对我有用!有一些陷阱(比如我认为CONTENT_URI必须存在?没有的时候遇到了麻烦)是的,CONTENT_URI必须存在,它将由Andoid读取,并与清单中的
android:authorities
属性匹配。嘿!回答得好!由于已加载的资产映像的大小,我遇到一些问题。我知道这是因为从资源文件夹加载的图像没有基于屏幕密度的“缩放”功能,而从资源文件夹加载的图像没有。关于如何解决这个问题有什么想法吗?@acrespo是的,你是正确的,这将不会选择不同的文件等,这取决于解决方案。但是,如果您认为合适,UI将缩放图像。如果您需要对每像素的外观和/或性能进行更多控制,我建议您改用drawables。您可能还将此逻辑添加到openAssetFile
函数中。@vidstige您将如何执行此操作?我考虑过在openAssetFile
函数中处理图像大小,但我不知道如何使用AssetFileDescriptor
。我认为这是不可能实现的:SDR和资产不是一回事
"android.resource://your.package.here/drawable/image_name