Hi guys,
today, I'm going to demonstrate how to make a ContentProvider which supports ContentResolver.openFileDescriptor(Uri, String) and both ContentResolver.openOutputStream(Uri) and ContentResolver.openInputStream(Uri). I'm not going to demonstrate how to make a basic ContentProvider as the Notepad example in the Sample dir of the SDK already does this.
I assume you have a basic content provider working, so retrieving, adding, deleting and updating data in the ContentProvider works. The thing we are going to do now is implement the ContentProvider.openFile(Uri, String), the default implementation is throwing a FileNotFoundExceptio("No files supported by provider at "+ uri) and thus we can't use it.
So start with putting this in your ContentProvider:
Using java Syntax Highlighting
- @Override
- public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
- throw new IllegalArgumentException();
- }
Parsed in 0.031 seconds, using GeSHi 1.0.8.4
Step 2 is making sure the user is querying for a specific item, and not the list. Using the NotePadProvider this would make our openFile() method look like:
Using java Syntax Highlighting
- @Override
- public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
- if (sUriMatcher.match(uri) != NOTE_ID)
- throw new IllegalArgumentException("openFile not supported for directories");;
- throw new IllegalArgumentException();
- }
Parsed in 0.030 seconds, using GeSHi 1.0.8.4
To be able to support files we are making use of the openFileHelper() provided in the ContentProvider. This makes it very easy to implement fileOpen(), but we need to adjust the database for this. We need to add a field name _data with type TEXT to our table. In case of the NotePadProvider this will make our NotePadProvider.DatabaseHelper.onCreate() look like this:
Using java Syntax Highlighting
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE " + NOTES_TABLE_NAME + " ("
- + Notes._ID + " INTEGER PRIMARY KEY,"
- + "_data TEXT,"
- + Notes.TITLE + " TEXT,"
- + Notes.NOTE + " TEXT,"
- + Notes.CREATED_DATE + " INTEGER,"
- + Notes.MODIFIED_DATE + " INTEGER"
- + ");");
- }
Parsed in 0.035 seconds, using GeSHi 1.0.8.4
Do NOT for get to ++ the DATABASE_VERSION, because only then the new table will be created.
Now our table is ready for file support, but now we need to fill the _data field with the filename of our file. We will do this in NotePadProvider.insert(). There is a section which inserts data into the database and then checks if the insert succeeded.
Using java Syntax Highlighting
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values);
- if (rowId > 0) {
- Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId);
- getContext().getContentResolver().notifyChange(noteUri, null);
- return noteUri;
- }
Parsed in 0.036 seconds, using GeSHi 1.0.8.4
Using java Syntax Highlighting
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values);
- if (rowId > 0) {
- Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId);
- getContext().getContentResolver().notifyChange(noteUri, null);
- values.put("_data", "/data/data/my.package/file"+rowId+".extension");
- rowId = db.update(MESSAGE_TABLE_NAME, values, "_id=?", new String[]{""+rowId});
- if (rowId > 0)
- return messageUri;
- else
- return null;
- return noteUri;
- }
Parsed in 0.037 seconds, using GeSHi 1.0.8.4
Only 1 thing is left: Updating NotePadProvider.openFile() to really return a ParcelFileDescriptor. And this is pretty easy:
Using java Syntax Highlighting
- @Override
- public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
- if (sUriMatcher.match(uri) != NOTE_ID)
- throw new IllegalArgumentException("openFile not supported for directories");;
- try{
- return this.openFileHelper(uri, mode);
- catch (FileNotFoundException e) {
- Log.i(TAG, "File not found");
- throw new FileNotFoundException();
- }
- throw new IllegalArgumentException();
- }
Parsed in 0.037 seconds, using GeSHi 1.0.8.4
Usage:
Using java Syntax Highlighting
- Uri note = ContentUris.withAppendedId(Notes.CONTENT_URI, 1);
- ParcelFileDescriptor file = getContentResolver().openFileDescriptor(note, "r");
Parsed in 0.036 seconds, using GeSHi 1.0.8.4
If I missed something, or something is not clear, or just wrong, let me know.


