我有一个webview的问题,可以通过HTML5应用程序访问localStorage . test.html文件通知我,本地存储
我的浏览器不支持存储。webview)。如果你有什么建议…
package com.test.HelloWebView;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class HelloWebView extends Activity {
WebView webview;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebViewClient(new HelloWebViewClient());
webview.loadUrl("file:///android_asset/test.html");
WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDatabaseEnabled(true);
String databasePath = this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
settings.setDatabasePath(databasePath);
webview.setWebChromeClient(new WebChromeClient() {
public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize, long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater) {
quotaUpdater.updateQuota(5 * 1024 * 1024);
}
});
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
webview.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
private class HelloWebViewClient extends WebViewClient {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
}
我有一个更好的解决方案,它将工作的第一次打开WebView。
你只需要使用一个自定义回调。像这样
public interface DataSavedCallback {
void onDataSaved();
}
然后使用这个函数从webview本地存储中获取键的值
public static void getLocalStorageAndSaveOnAndroidPref(String[] keys,
WebView view,dataSavedCallback savedCallback) {
String JAVASCRIPT_LOCAL_STORAGE_LOOKUP = "javascript:window";
view.evaluateJavascript(JAVASCRIPT_LOCAL_STORAGE_LOOKUP.concat(".localStorage.getItem('" + keys[i] + "')"), new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.d(TAG, "getLocalStorageAndSaveOnAndroidPref: " + value);
}
});
}
你可以在任何地方使用你的webview调用上面的函数
myWebView.post(() -> {
String[] keys = {"androidDeliveryAppStickyNotificationTitle","androidDeliveryAppStickyNotificationSubtitle","androidAppNewSoundAlertTitle"};
getLocalStorageAndSaveOnAndroidPref(keys, myWebView, new dataSavedCallback() {
@Override
public void onDataSaved() {
//do whatever you want
}
});
});
我有一个更好的解决方案,它将工作的第一次打开WebView。
你只需要使用一个自定义回调。像这样
public interface DataSavedCallback {
void onDataSaved();
}
然后使用这个函数从webview本地存储中获取键的值
public static void getLocalStorageAndSaveOnAndroidPref(String[] keys,
WebView view,dataSavedCallback savedCallback) {
String JAVASCRIPT_LOCAL_STORAGE_LOOKUP = "javascript:window";
view.evaluateJavascript(JAVASCRIPT_LOCAL_STORAGE_LOOKUP.concat(".localStorage.getItem('" + keys[i] + "')"), new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.d(TAG, "getLocalStorageAndSaveOnAndroidPref: " + value);
}
});
}
你可以在任何地方使用你的webview调用上面的函数
myWebView.post(() -> {
String[] keys = {"androidDeliveryAppStickyNotificationTitle","androidDeliveryAppStickyNotificationSubtitle","androidAppNewSoundAlertTitle"};
getLocalStorageAndSaveOnAndroidPref(keys, myWebView, new dataSavedCallback() {
@Override
public void onDataSaved() {
//do whatever you want
}
});
});
最近当我在寻找类似的解决方案时,这篇文章出现了很多次。webview WebSettings对象从API 19开始就弃用了数据库路径方法,这些方法现在返回空值,这意味着我们不能依赖它们来获取网页存储,不管我们是否在加载URL之前在设置中启用了它。
为了从web页面读取localStorage值,我们需要扩展WebViewClient()并覆盖onPageFinished(),在其中,你可以在webview上评估javascript,如下所示:
const val JAVASCRIPT_LOCAL_STORAGE_LOOKUP = "javascript:window.localStorage.getItem('KEY');"
...
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
view?.let { webView ->
webView.evaluateJavascript(JAVASCRIPT_LOCAL_STORAGE_LOOKUP) { result ->
// returns value from 'KEY'
}
}
}
只需将'KEY'替换为您想要访问的存储对象的键。这样就不需要提供任何可能与现有数据库相冲突的数据库实现。注意,这只会轮询webview刚刚加载的域的localStorage。我希望这能帮助到其他人,因为我花了一些时间来弄清楚。