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

前端 未结 4 1089
臣服心动
臣服心动 2020-12-18 04:01

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.

相关标签:
4条回答
  • 2020-12-18 04:38

    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.

    0 讨论(0)
  • 2020-12-18 04:40

    Just wanted to add to vidstige's answer: I wanted to serve files that I had downloaded to my temporary cache directory earlier, so I can serve external image thumbnails to the SearchView suggestions from URLs in my search ContentProvider. I used this function instead:

    @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);
            }
        }
    
    0 讨论(0)
  • 2020-12-18 04:46

    You first create an AssetProvider. We will later create uris that will be handled by this class.

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

    Lot's of boilerplate in there. The essential method is of course the openAssetFile that justs translates the path of the uri passed to it into a AssetFileDescriptor. In order for Android to be able to pass URIs to this provider, remember to include this in your AndroidManifest.xml file inside the application-tag:

        <provider
            android:name=".AssetsProvider"
            android:authorities="com.example.assets" />
    

    Now, in your search provider you can create an URI like this:

    content://com.example.assets/my_folder_inside_assets/myfile.png
    
    0 讨论(0)
  • 2020-12-18 04:54

    I was able to refer images from drawable in SearchRecentSuggestionsProvider using following uri,

    "android.resource://your.package.here/drawable/image_name
    
    0 讨论(0)
提交回复
热议问题