【问题标题】:keep localstorage data when app closes in android studio webview当应用程序在 android studio webview 中关闭时保留本地存储数据
【发布时间】:2018-01-22 20:19:57
【问题描述】:

我使用 android studio 从我的网站制作一个应用程序,我真的需要localstorage,但每次我关闭应用程序时它都会完全删除。我该如何解决?

<uses-permission android:name="android.permission.INTERNET" />

我使用这段代码来启用 javascript 和本地存储:

 myWebView = (WebView)findViewById(R.id.webView);
        WebSettings webSettings = myWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        myWebView.getSettings().setDomStorageEnabled(true);
        myWebView.getSettings().setDatabaseEnabled(true);

我看到其他人问同样的问题,我使用了这个答案:

 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            myWebView.getSettings().setDatabasePath("/data/data/" + myWebView.getContext().getPackageName() + "/databases/");
        }

但它说它已被弃用并且仍然无法正常工作(每次我重新启动我的应用程序时都会删除本地存储)。

请帮我解决这个问题,我想保存我的本地存储!

【问题讨论】:

  • "此错误实际上不是由于缺少任何 Java 端权限,而是由于改进了较新 WebView 版本的 Web 安全模型。您尝试从不同来源的页面访问 localStorage。例如,如果您正在为初始页面使用 loadData,然后从服务器加载其他部分,该代码可以具有不同的来源。”见here。还有here
  • 还有一个here
  • 那么它可以以某种方式修复吗?喜欢让它不那么安全吗?
  • 我会下载你的代码并做一些测试...
  • 谢谢,它是否适用于 cookie?

标签: javascript android html android-studio webview


【解决方案1】:

不太了解您的问题,但尝试添加:

CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);

String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
myWebView.setAllowFileAccess(true);
myWebView.setAppCachePath(appCachePath);


<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

【讨论】:

  • 我现在试过了,还是不行,好解释一下,我用这个(HTML5中的localstorage)w3schools.com/html/html5_webstorage.asp
  • 如果您有任何其他想法,请告诉我,非常感谢您的帮助
  • 我在我的网站中使用 localstorage,当我在 webview 中打开我的网站时它工作正常,它将数据保存到 localstorage,但是当我关闭应用程序并再次打开它时,应该在页面上的数据消失了
  • 它在浏览器中运行良好,我可以试试 cookie,现在更改我的网站需要做很多工作,但如果没有其他办法,我会尝试,谢谢
  • 看胎面;一个解决方案:“我终于设法解决了这个问题。无论我尝试什么,我都能让它工作的唯一方法是将 html 文件包含在应用程序中,而不是通过 Buzztouch 的控制面板进行,并且加载它。这个 html 文件现在可以正确加载,并且没有 localStorage 错误。” [stackoverflow.com/questions/31812066/…
【解决方案2】:

我设法在我的一个使用 WebView 的应用程序的本地存储中缓存音频文件。这意味着音频文件被截取,如果缓存中不可用,则下载它们,然后从缓存中提供。缓存在手机在 Android 10 上重新启动后仍然存在。

这些是我用于 WebView 的设置:

@SuppressLint("SetJavaScriptEnabled")
public static void setupWebview(WebView webView) {
    WebSettings settings = webView.getSettings();
    settings.setLoadWithOverviewMode(true);
    settings.setUseWideViewPort(true);
    settings.setAllowFileAccess(true);
    settings.setAllowContentAccess(true);
    settings.setAllowFileAccessFromFileURLs(true);
    settings.setAllowUniversalAccessFromFileURLs(true);
    settings.setBlockNetworkImage(false);
    settings.setBlockNetworkLoads(false);
    settings.setLoadsImagesAutomatically(true);
    settings.setMediaPlaybackRequiresUserGesture(false);
    settings.setDomStorageEnabled(true);
    settings.setLoadWithOverviewMode(true);
    settings.setJavaScriptEnabled(true);
    settings.setAllowUniversalAccessFromFileURLs(true);
    settings.setDatabaseEnabled(true);
    settings.setAppCacheEnabled(true);
    settings.setAppCachePath("/beezone");
}

我已经为同一个WebView使用了自定义的WebClient

所以基本上自定义的WebClient 看起来像这样:

    mWebView.setWebViewClient(new WebViewClient() {

        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        @Nullable
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
            return cacheM4a(request, context);
        }

        @Nullable
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
            return cacheM4a(Uri.parse(url), context);
        }
    });

方法cacheM4a的相关代码如下:

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Nullable
public static WebResourceResponse cacheM4a(WebResourceRequest request, Context context) {
    Uri source = request.getUrl();
    return cacheM4a(source, context);
}

@Nullable
public static WebResourceResponse cacheM4a(Uri source, Context context) {
    String sourceStr = source.toString();
    if (sourceStr.endsWith(CacheHelper.MAIN_AUDIO_FORMAT)) {
        String language = LanguageHelper.INSTANCE.getLanguage();
        String absolutePath = context.getCacheDir().getAbsolutePath();
        String langPath = String.format("%s/%s", absolutePath, language);
        boolean folderExists = createLanguageCachePath(langPath);
        if(!folderExists) {
            try {
                return new WebResourceResponse("audio/mp4", "binary", new URL(sourceStr).openStream());
            } catch (IOException e) {
                Log.e(TAG, "Failed to read directly from the web", e);
                return null;
            }
        }
        String targetPath = String.format("%s/%s", langPath, source.getLastPathSegment());
        File file = new File(targetPath);
        if (!file.exists()) {
            if (saveToCache(sourceStr, targetPath)) return null;
        }
        // Always read from cache.
        try  {
            FileInputStream fis = new FileInputStream(new File(targetPath));
            WebResourceResponse response = new WebResourceResponse("audio/mp4", "binary", fis);
            return response;
        } catch (IOException e) {
            Log.e(TAG, "Failed to read cache", e);
            return null;
        }
    }
    return null;
}

private static boolean saveToCache(String sourceStr, String targetPath) {
    // File is not present in cache and thus needs to be downloaded
    try (InputStream in = new URL(sourceStr).openStream();
         FileOutputStream fos = new FileOutputStream(new File(targetPath))) {
        ByteStreams.copy(in, fos);
    } catch (IOException e) {
        Log.e(TAG, "Failed to save in cache", e);
        return true;
    }
    return false;
}

private static boolean createLanguageCachePath(String langPath) {
    File langPathFile = new File(langPath);
    if(!langPathFile.exists()) {
        if(!langPathFile.mkdirs()) {
            Log.e(TAG, String.format("Could not create %s", langPathFile));
            return false;
        };
    }
    return true;
}

这些是我使用的权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-11
    • 2021-11-14
    • 2012-11-26
    • 2017-08-21
    • 2012-11-12
    • 2010-11-27
    • 1970-01-01
    相关资源
    最近更新 更多