Explain Codes LogoExplain Codes Logo

Android WebView & localStorage

android
localStorage
webview
database-management
Anton ShumikhinbyAnton Shumikhin·Aug 29, 2024
TLDR

To utilize localStorage within WebView, activate DOM storage via the setDomStorageEnabled(true) method on WebSettings:

WebView webView = findViewById(R.id.webview); webView.getSettings().setDomStorageEnabled(true);

Enable JavaScript with setJavaScriptEnabled(true) and define a database path for APIs before KitKat using setDatabasePath("/data/data/package_name/databases/"). Don't forget to consider API level compatibility.

Treating API level considerations

Compatibility should always be checked. For API levels < 19 (KitKat), it's necessary to indicate where WebView should store database files:

// Feel old yet? This runs only on devices older than KitKat! if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { webView.getSettings().setDatabasePath("/data/data/" + getPackageName() + "/databases/"); }

APIs aren't forever; methods do get deprecated. Regularly check developer guides to ensure your code is running on fresh legs.

Advanced interaction with convenient methods

Starting from API 19 and above, you can comfortably use evaluateJavascript() for manipulating localStorage post-page load:

// Look, ma, no hands! Retrieving data from WebView. webView.evaluateJavascript("localStorage.setItem('key', 'value');", null);

Leverage WebChromeClient for database management

Effective database management comes through WebChromeClient, which paired with onExceededDatabaseQuota method, can help to handle database quota and permissions:

webView.setWebChromeClient(new WebChromeClient() { public void onExceededDatabaseQuota(String url, String databaseIdentifier, long quota, long estimatedDatabaseSize, long totalQuota, WebStorage.QuotaUpdater quotaUpdater) { // Not this time, dear quota! quotaUpdater.updateQuota(estimatedDatabaseSize * 2); } });

Managing cross-version challenges

Each solution should be assessed based on its cross-version effectiveness:

  1. Your code should work for various Android versions providing a consistent user experience.
  2. Consider welcoming alternatives to deprecated storage methods to ensure your database remains accessible.

While targeting recent Android versions, utilize the application's package name to define the database path accurately for directory isolation.

Applying localStorage after page loading

One topic of interest could be how to use localStorage after the page has finished loading. Accomplish this within the WebViewClient's onPageFinished():

webView.setWebViewClient(new WebViewClient() { public void onPageFinished(WebView view, String url) { // Aha! Here it is! Our precious payload. view.evaluateJavascript("localStorage.getItem('key');", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { // Do something with this newly-found treasure. } }); } });

Exploring alternative storage options

Finally, consider alternatives to localStorage such as SharedPreferences for native app data or modern web technologies like the IndexedDB. These provide a wider range of features and flexibility compared to localStorage.