17

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

MrChaz
  • 1,065
  • 1
  • 8
  • 17

2 Answers2

12

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);
MrChaz
  • 1,065
  • 1
  • 8
  • 17
4

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);
Zack Bartel
  • 3,703
  • 1
  • 18
  • 11
  • Unbelievable... On my situation, the app is using API 12, to run since Android 3.1 that do not has setAllowUniversalAccessFromFileURLs (http://stackoverflow.com/questions/19379392/jquery-mobile-not-working-in-webview-when-loading-from-local-assets) to set to true, so, blank page on 4.2. With that now it's all ok. – Karl Heinz Brehme Arredondo Feb 22 '15 at 20:50