我已成功将我的应用程序的国家/地区搜索整合到全局搜索工具中,现在我正在尝试在搜索建议旁边显示每个国家/地区的标记.在我的应用程序内部搜索以这种方式工作,但当然我可以控制列表及其视图绑定自己.所以我知道标志都在那里,我可以在我的应用程序的其余部分使用它们.
当我尝试将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)
遗憾的是,经过多次搜索后,我得出的结论是,您无法将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)
我只需要确保创建一个测试,验证所有有标志的国家都会返回预期的结果.
你先创建一个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)