Android 웹 보기 및 로컬 스토리지
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;
}
}
}
다음 항목이 누락되었습니다.
settings.setDomStorageEnabled(true);
setDatabasePath() 메서드가 API 수준 19에서 더 이상 사용되지 않습니다.다음과 같은 스토리지 로케일을 사용하는 것이 좋습니다.
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
webView.getSettings().setDatabasePath("/data/data/" + webView.getContext().getPackageName() + "/databases/");
}
애플리케이션을 다시 시작한 후 데이터가 손실되는 문제도 있었습니다.이 기능을 추가하면 다음과 같은 이점이 있습니다.
webView.getSettings().setDatabasePath("/data/data/" + webView.getContext().getPackageName() + "/databases/");
빌드 대상 Android 4.4로 컴파일된 내 Android 4.2.2에서 작동하는 솔루션W:
WebSettings settings = webView.getSettings();
settings.setDomStorageEnabled(true);
settings.setDatabaseEnabled(true);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
File databasePath = getDatabasePath("yourDbName");
settings.setDatabasePath(databasePath.getPath());
}
앱이 여러 웹 보기를 사용하는 경우에도 여전히 문제가 발생합니다. localStorage가 모든 웹 보기에서 올바르게 공유되지 않습니다.
여러 웹 보기에서 동일한 데이터를 공유하려면 Java 데이터베이스와 Javascript 인터페이스를 사용하여 복구하는 방법밖에 없습니다.
github의 이 페이지는 이것을 하는 방법을 보여줍니다.
이것이 도움이 되길 바랍니다!
최근 비슷한 해결책을 찾고 있을 때 이 글이 많이 올라왔습니다.webview WebSettings 개체는 API 19 이후 데이터베이스 경로 메서드를 더 이상 사용하지 않습니다. 이제 빈 값을 반환합니다. 즉, URL을 로드하기 전에 설정에서 활성화했는지 여부에 관계없이 이 메서드를 사용하여 웹 페이지 저장소를 풀링할 수 없습니다.
웹 페이지에서 localStorage 값을 읽으려면 다음과 같이 확장해야 했습니다.WebViewClient()
및 오버라이드onPageFinished()
아래와 같이 웹 뷰에서 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'
액세스할 저장된 개체의 키를 사용합니다.이렇게 하면 기존 데이터베이스와 충돌할 수 있는 데이터베이스 구현을 제공할 필요가 없습니다.웹 보기가 방금 로드를 완료한 도메인의 localStorage만 폴링합니다.제가 이해하는데 시간이 좀 걸렸기 때문에 이것이 다른 사람에게 도움이 되길 바랍니다.
이에 대한 더 나은 해결책이 있습니다. 처음으로 웹 뷰를 열 때 작동할 것입니다.
사용자 지정 콜백을 사용하면 됩니다.이것처럼.
public interface DataSavedCallback {
void onDataSaved();
}
그런 다음 이 기능을 사용하여 웹뷰 로컬 스토리지에서 키 값을 가져옵니다.
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);
}
});
}
당신은 당신의 웹 뷰를 사용하여 위의 기능을 어디서든 호출할 수 있습니다.
myWebView.post(() -> {
String[] keys = {"androidDeliveryAppStickyNotificationTitle","androidDeliveryAppStickyNotificationSubtitle","androidAppNewSoundAlertTitle"};
getLocalStorageAndSaveOnAndroidPref(keys, myWebView, new dataSavedCallback() {
@Override
public void onDataSaved() {
//do whatever you want
}
});
});
웹 보기가 여러 개인 경우 로컬 저장소가 제대로 작동하지 않습니다.
제안: 두가지제안:
- @Guillaume Gendre"가 설명한 로컬 스토리지를 웹 보기 대신 Java 데이터베이스를 사용합니다.(물론 저에게는 통하지 않습니다)
- 로컬 스토리지는 json처럼 작동하므로 값이 "key:value"로 저장됩니다. 브라우저 고유 ID를 키에 추가하고 일반 안드로이드 로컬 스토리지를 사용할 수 있습니다.
언급URL : https://stackoverflow.com/questions/5899087/android-webview-localstorage
'source' 카테고리의 다른 글
'void' 유형은 'Observable' 유형에 할당할 수 없습니다.입력 <{}> (0) | 2023.08.02 |
---|---|
현재 커서 위치의 텍스트 영역에 텍스트를 삽입하는 방법은 무엇입니까? (0) | 2023.08.02 |
Powershell Invoke-Rest 메서드가 http 500 코드 응답 본문을 반환하도록 하는 방법 (0) | 2023.08.02 |
jQuery 페이지 하단/iframe으로 스크롤 (0) | 2023.08.02 |
그런데 c 프로그램의 반환값을 명령줄에서 얻기 위해서입니까? (0) | 2023.08.02 |