Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 4.0.1 breaks WebView HTML 5 local storage?

I have a simple html5 test page which uses LocalStorage to display / save / redisplay a piece of data.

This code works perfectly in Android 2.3.x but logs an exception in 4.0.1 on line 18 of the html which is the frist localStorage.getItem() call and at this point the JS stops.

Exception: Uncaught Error: SECURITY_ERR: DOM Exception 18 at /data/data/my.app.name/app_htmlData:18 I've also tried setting the database path to getCacheDir() with the same result.

String htmlContent = "HTML content listed below";    
File sharedDir = getActivity().getDir("htmlData", Context.MODE_PRIVATE);
WebView browser = (WebView)v.findViewById(R.id.wvBrowser);

browser.setWebChromeClient(new WebChromeClient(){
    public void onExceededDatabaseQuota(String url, String databaseIdentifier, long  currentQuota, long estimatedSize,   long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) { 
            quotaUpdater.updateQuota(estimatedSize * 2); 
        }
    });       
browser.setWebViewClient(new WebViewClient(){
    @Override
    public void onPageFinished(WebView view, String url){

        view.loadUrl("javascript:doTest()");

    });

browser.getSettings().setDatabaseEnabled(true);
browser.getSettings().setDatabasePath(sharedDir.getPath());
browser.getSettings().setDomStorageEnabled(true);
browser.loadDataWithBaseURL(mSharedDir.getPath(), 
            htmlContent, 
            "text/html", 
            "utf-8", 
            null);

The HTML that the page is rendering is as follows:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Simple localStorage test</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script type="text/javascript">

        function doTest() {
            $('#stuff').append('<p>reading</p>');
            var item = read();

            $('#stuff').append('<p>writing</p>');
            localStorage['bar'] = new Date().toUTCString();

            $('#stuff').append('<p>&nbsp;</p><p>reading again</p>');
            read();
        }
        function read() {
            var item = localStorage.getItem('bar');
            if (item == null || (item == undefined)) {
                item = '';
            }
            $('#stuff').append('<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item: ' + item + '</p>');

         return item;
        }
    </script>
</head>
<body>
    <p>-Simple localStorage test-</p>
    <div id="stuff"></div>
</body>
</html>

Source available here

like image 568
MrChaz Avatar asked Dec 05 '11 19:12

MrChaz


2 Answers

Via some discussion with a Google engineer it seems that they've made the decision that the file:// scheme is insecure.

A work around for this is to do the following

browser.loadDataWithBaseURL("http://www.example.com", 
            htmlContent, 
            "text/html", 
            "utf-8", 
            null);
like image 55
MrChaz Avatar answered Sep 25 '22 21:09

MrChaz


For android versions less than 4.4, loading data into a webview with a file scheme as a directory:

browser.loadDataWithBaseUrl("file:///android_asset/", html, "text/html", "UTF-8", null);

wont work with localStorage. If I add a filename it does work on older OS versions

browser.loadDataWithBaseUrl("file:///android_asset/test.html", html, "text/html", "UTF-8", null);
like image 26
Zack Bartel Avatar answered Sep 25 '22 21:09

Zack Bartel