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 ![]()
January 15th, 2009 at 3:45 pm
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
February 16th, 2009 at 1:39 am
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;
}
February 16th, 2009 at 9:35 am
Hello Tyler,
Thanks for pointing that out and giving your code, I have added a note in point 3.
March 1st, 2009 at 5:16 am
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
April 3rd, 2009 at 4:23 am
[…] found a few posts about WebView being unable to open local files, and the need to use a ContentProvider to get around […]
August 4th, 2009 at 4:31 pm
ehh… bookmarked
November 6th, 2009 at 7:10 am
Nice post. Thanks for sharing these tips.
January 28th, 2010 at 8:28 pm
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
January 28th, 2010 at 8:36 pm
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.
February 3rd, 2010 at 8:30 pm
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
February 27th, 2010 at 10:53 pm
I think your blog need a new wordpress template. Downalod it from http://www.wpxthemes.com, The site has nice and unique wordpress templates.