16

I have just written a function in an android app that deletes a file using the standard 'File' class in Java. i.e:

String fileName= "/mnt/Gallery/Img001.jpg";
File file = new File(fileName);
file.delete();

While the above procedure is simple enough, I have been wondering if there is any advantage to doing the same via a 'ContentResolver'. Any advice would be appreciated.

------------------------------------------ EDIT ----------------------------------------

Here's an example of deleting a file via the Content Resolver. This example assumes the file being deleted is an image and that its 'id' is known.

long mediaId = 155; // NOTE: You would normally obtain this from the content provider!
Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Uri itemUri = ContentUris.withAppendedId(contentUri, mediaId);

int rows = getContentResolver().delete(itemUri, null, null);

String path = itemUri.getEncodedPath();
if(rows == 0)
{
    Log.e("Example Code:","Could not delete "+path+" :(");
}
else
{
    Log.d("Example Code:","Deleted "+path+ " ^_^");
}
Jazza
  • 165
  • 1
  • 6
  • 2
    After a little investigation I've discovered that there is an advantage when the file being deleted is managed by Android's 'Content Provider'. Images for example are maintained in an image table to allow applications to quickly view the list of images on the device. Using "getContentResolver().delete(uri, null, null)" in your activity will automatically remove the associated entry in the content table. Simply using "file.delete()" will only remove the physical file, after which the media scanner will need to be prompted to update the content table. – Jazza Jun 12 '12 at 03:25
  • And what is the proper way to delete the file via a content provider? I've tried: getContentResolver().delete(Uri.fromFile(new File(fileName)), null, null); But I get am "Unknown URL" exception. – PerracoLabs Jun 28 '12 at 03:47
  • @Zhenya: I initially made the same mistake that you have by passing in a 'URL' to the file I was trying to delete. The delete() function requires a 'uri' which points to a row in the content provider table. This row cannot be obtained by calling Uri.fromFile()! I have edited my question above to illustrate how to construct this Uri. – Jazza Jul 02 '12 at 02:25

1 Answers1

12

Android's content provider framework has certain added advantages when compared to directly manipulating data.

You can think on the lines of 'Where does the file reside and who may be deleting it'.

Scenario 1

File resides on SD card (a path accessible by your app) and you app is deleting it.

Solution : Since the path is accessible to you, the java approach will work with a file Uri like:

file://mnt/sdcard/downloads/image.jpeg

Scenario 2

File resides in another app (say dropbox) and your app needs to delete the file.

Solution : This means that the file actually resides in the private storage of another app. A file: Uri will the above approach will give you access denied. So, your app will need to fetch a content Uri from the app containing the file and call into its content provider to delete.

fileUri = Uri.parse ("content : // " + packageContainingTheFile " + fileId); // replace this with Uri obtained from the app. getContext().getContentResolver().delete (fileUri, null, null);

Scenario 3

File resides in your app's package directory i.e, under data/data/com.yourpackage/yourfolder/yourfile.xxx and your app is the only one deleting it.

Solution : Here, either of the above approaches will work since you have the access to delete the file. Uri will look like:

file://data/data/yourpackage/folder/file.ext

The prime advantage of using content provider here is that you automatically gain the observer model. Content provider callbacks are a well defined entry point from where data is modified. Hence, its a desired place to notify others of changes using:

getContext().getContentResolver().notify(uri, null)

Assume you have views that show a listing of such file items. As soon as the delete is done, your can be notified.

Scenario 4

File resides in your app's package directory i.e, under data/data/com.yourpackage/yourfolder/yourfile.xxx and you want to expose the delete functionality to other apps.

Solution : This is similar to Scenario 1, just the other way round. Other apps cannot delete the file in your private storage with a Uri like

file://data/data/yourpackage/folder/file.ext // works just for your app

They will need to call in your content provider to do this with a Uri like.

content://providerAuthority/delete/id which your content provider will need to map to file.ext absolute path.

Summary

To conclude, the use of content provider is necessary is some scenarios while optional in others. It largely depends on your app requirements. If you have views, CursorLoaders in place and want to be informed about updates or wish to expose deletion of your app data to other apps, content provider is the cleanest approach.

Rohan
  • 428
  • 5
  • 10
  • I am using a key value pair storage which holds array of objects. Objects has paths of files stored in private storage of app. And also used provider. How would I remove or insert or update the files and object holding paths of those files and also effect on content provider so that third party apps should know the changes and also dir, key-value storage and content provider all should synced – CrackerKSR Jul 19 '22 at 13:25