Too Easy - Using a ContentProvider to Send File from Assets folder

I needed to allow the user to send an image included with an app, using a ACTION_SEND intent.  The Android security framework doesn't allow one application to access the files in another application's assets folder.  However, an app can expose this information by implementing a content provider.

A content provider can do some fancy stuff, but for something as simple as allowing another application to read a particular file, it is surprisingly trivial.

Define the "Authority"

You need to define an "authority" that will cause your content provider to get queried when another apps needs the file.

In your application manifest, add the following:

        <provider android:name="yourclass.that.extendsContentProvider"                android:authorities="com.yourdomain.whatever"/>

This will cause your content provider to be called whenever any other app needs to open something with the uri "content://com.yourdomain.whatever/fileInAssetsFolder"


Extending ContentProvider

Write a class that extends ContentProvider, and implement stubs for the needed abstract methods.  Then override the openAssetFile method as below (from stackoverflow):

@Override
    public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
        AssetManager am = getContext().getAssets();
        String file_name = uri.getLastPathSegment();
        if(file_name == null)
            throw new FileNotFoundException();
        AssetFileDescriptor afd = null;
        try {
            afd = am.openFd(file_name);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return afd;//super.openAssetFile(uri, mode);
    }

Use It

To use this somewhere in your app, where you want to send a file from the assets folder, you just do this

Uri theUri = Uri.parse("content://com.yourdomain.whatever/someFileInAssetsFolder");
Intent theIntent = new Intent(Intent.ACTION_SEND);
theIntent.setType("image/*");
theIntent.putExtra(Intent.EXTRA_STREAM,theUri);
theIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Subject for message");                       
theIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Body for message");
startActivity(theIntent);

Popular Posts