Android tip #1 ContentProvider , Accessing local file system from WebView / showing image in webview using content://

ok, this was a tough one.
First be informed that this is something Google (Android people) are trying to prevent i.e. letting browser (WebView) have access to the local file system. In earlier releases of SDK you could access local files using ‘file://’ but it is stopped now. Then there was an option where you can provide a WebViewClient and implement shouldOverrideUrlLoading to make it work. This was also removed.
The way to make it work now is by implementing your own ContentProvider, there is lot of discussion and documentation on implementing ContentProvider but all that is completely redundant (not needed). The solution is very simple, create your own ContentProvider and only override


public android.os.ParcelFileDescriptor openFile(android.net.Uri uri, java.lang.String mode) throws java.io.FileNotFoundException

Rest of the code in ContentProvder is not needed for this problem.

Step 1:
Declare your Content Provider in AndroidManifest.xml


<provider android:name="MyDataContentProvider"  android:authorities="com.techjini" />

Step 2:
Create your ContentProvider and implement openFile
All you have to do is get real path from uri, open it and return the descriptor


URI uri = URI.create("file:///data/data/com.techjini/files/myImage.jpeg");
File file = new File(uri);
ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
return parcel;

Step 3:
(You need this step only if file is not already present on the device/sdcard)
Save your content to the file. Following is an example to store a Bitmap


FileOutputStream fos = openFileOutput("myImage.jpeg", Activity.MODE_WORLD_WRITEABLE);
imageView.getBitmap().compress(Bitmap.CompressFormat.JPEG, 100, fos);

fos.flush();
fos.close();

You can find out where your image is stored using


System.out.println(getFilesDir().getAbsolutePath());

Step 4:
Access the file in WebView


myWebView.loadUrl("content://com.techjini/myImage.jpeg");
//com.techjini is what you mentioned in 'android:authorities' in your AndroidManifest.xml

Looks simple :)

11 Responses to “Android tip #1 ContentProvider , Accessing local file system from WebView / showing image in webview using content://”

  1. vinay Says:

    hi,
    I am not familiar to Java stuff and got into making webview display /sdcard/index.html file. This index.html has got some website links (www.amazon.com) as my board does not have keypad.
    Can you provide me the above mentioned complete code and compile procedue.
    -vinay

  2. Tyler Says:

    Thanks for this, it was a BIG help! You may want to clarify that step #3 isn’t necessary if a file already exists; it’s just to provide a sample. Also, here’s an override of openFile that points to any Uri you pass it (i.e. passing “file://sdcard/foo/bar/anything.jpeg” will be reachable via “content://com.yourauthority/sdcard/foo/bar/anything.jpeg”):

    // SDK v. 1.0_r2
    @Override
    public ParcelFileDescriptor openFile( Uri uri, String mode ){
    URI fileURI = URI.create( “file://” + uri.getPath() );
    File file = new File( fileURI );

    ParcelFileDescriptor parcel = null;
    try {
    parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
    } catch (FileNotFoundException e) {
    Log.e( TAG, “Error finding: ” + fileURI + “\n” + e.toString() );
    }

    return parcel;
    }

  3. Amit Says:

    Hello Tyler,
    Thanks for pointing that out and giving your code, I have added a note in point 3.

  4. ATrubka Says:

    Hi, guys. I thought it might be helpful to have a complete working example.

    It’s on my blog with some explanations around it:
    http://blog.tourizo.com/2009/02/how-to-display-local-file-in-android.html

  5. Android, NetBeans, and the Assets directory | Yet Another Programming Blog Says:

    […] found a few posts about WebView being unable to open local files, and the need to use a ContentProvider to get around […]

  6. Rokka Says:

    ehh… bookmarked :)

  7. Santori Says:

    Nice post. Thanks for sharing these tips.

  8. Schorsch Says:

    Hi Amit,

    as i am not a coder, but only a project manager (for a small startup) i have a general question. Does your workaround also work with a simple web/xhtml page or is it neccessary to create a piece of software that needs to be installed on each individual handset that wants to access the local file system? I am asking because we want to give the users of our not yet released community the possibility to upload pictures stored on their devices from within the browser. We dont have any app and also dont want our users to install any apps (unless theres sth like firefox plugins, that would actually be great!)

    Do you have any idea on how to make that happen from a pure browsers environment? Or does your idea already work from a pure xhtml site?

    Thanks alot in advance!
    Schorsch

  9. Amit Says:

    Hello Schorsch,

    Couple of things, the solution above was for android 1.0/1.1 earlier, with the new 2.1 api this is supported out of the box. Now if I am embedding webkit in my app I can load local files easily.

    Now coming to your situation, if you do not want an app and just have a web page which android users will open in their app it would not be a problem to access pictures from device.

    You can easily try it by making a simple html, putting it on your server and trying to access it from android browser.

  10. Yaya Says:

    Hi,
    can you explain how do access the file in the html code ?

    i’ve tryed and i having “Failed to find provider info for com.myCompany.myPackageName”.
    For more explanation see:
    http://groups.google.com/group/android-developers/browse_thread/thread/d105f5194d843861#

    Thanks a lot in advance !

    Yaya

  11. Android Apps Says:

    I think your blog need a new wordpress template. Downalod it from http://www.wpxthemes.com, The site has nice and unique wordpress templates.

Leave a Reply