source

Android 웹 보기 및 로컬 스토리지

nicesource 2023. 8. 2. 09:12
반응형

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
        }
    });
});

웹 보기가 여러 개인 경우 로컬 저장소가 제대로 작동하지 않습니다.
제안: 두가지제안:

  1. @Guillaume Gendre"가 설명한 로컬 스토리지를 웹 보기 대신 Java 데이터베이스를 사용합니다.(물론 저에게는 통하지 않습니다)
  2. 로컬 스토리지는 json처럼 작동하므로 값이 "key:value"로 저장됩니다. 브라우저 고유 ID를 키에 추가하고 일반 안드로이드 로컬 스토리지를 사용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/5899087/android-webview-localstorage

반응형