How to Load Cache Page in Webview
Asked Answered
E

4

7

I have Cache Manifest applied on HTML Page.

On Chrome Browser when Internet connection goes off, it redirects to cache mode. Well, this is not the case with Android-Webview. It gives following error:

Webpage could not be loaded

net:ERR_NAME_NOT_RESOLVED

Have gone through various resources but none seems to help.

Below is the code am using:

package com.example.page;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

import com.google.firebase.iid.FirebaseInstanceId;

public class MainActivity extends Activity {
    public static WebView mWebview;
    private android.content.Context Context;
    private static String getIntentValue = null;
    public static SharedPreferences sharedPreferences;
    private ProgressDialog mProgressDialog;
    private String mCM;
    private ValueCallback<Uri> mUM;
    private ValueCallback<Uri[]> mUMA;
    private final static int FCR=1;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent){
        super.onActivityResult(requestCode, resultCode, intent);
        mWebview.setWebViewClient(new Callback());

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        Context = this;
        String regId = FirebaseInstanceId.getInstance().getToken();

        getIntentValue = getIntent().getStringExtra("value");

        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);

        if (!DetectConnection.checkInternetConnection(this)) {
            Toast.makeText(getApplicationContext(), "No Internet Connection!", Toast.LENGTH_LONG).show();
            finish(); //Calling this method to close this activity when internet is not available.

        } else {

            mWebview = (WebView) findViewById(R.id.webview1);
            WebSettings webSettings = mWebview.getSettings();
            mWebview.getSettings().setJavaScriptEnabled(true);
            mWebview.setWebChromeClient(new WebChromeClient());
            mWebview.setWebViewClient(new CustomWebViewClient());

            //improve WebView Performance
            mWebview.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
            mWebview.getSettings().setAppCacheEnabled(false);
            mWebview.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);


            if(Build.VERSION.SDK_INT >=23 && (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)) {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA}, 1);
            }

            mWebview.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
            webSettings.setDomStorageEnabled(true);
            webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
            webSettings.setUseWideViewPort(true);
            webSettings.setAllowFileAccess(true);
            webSettings.setSavePassword(true);
            webSettings.setSaveFormData(true);
            webSettings.setEnableSmoothTransition(true);

            // progress dialog
            mProgressDialog = new ProgressDialog(Context);

            if (sharedPreferences.getBoolean("isKeyGenerated", true)) {

                if (getIntentValue != null) {
                    mWebview.loadUrl("http://www.example.com/page");
                    getIntentValue = null;

                } else {
                    mWebview.loadUrl("http://www.example.com/page2");
                }
            }
        }


    }



    public class Callback extends WebViewClient{
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){
            Toast.makeText(getApplicationContext(), "Failed loading app!", Toast.LENGTH_SHORT).show();
        }
    }


    // Function to load all URLs in same webview
    private class CustomWebViewClient extends WebViewClient {
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if (url.contains(".pdf")) {
                Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(i);
            } else {
                view.loadUrl(url);
            }
            return true;
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            // TODO Auto-generated method stub
            super.onPageStarted(view, url, favicon);

            //on page started, show loading page
            mProgressDialog.setCancelable(true);
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            mProgressDialog.show();

        }

        @Override
        public void onPageFinished(WebView view, String url)
        {
            String currentPage= mWebview.getUrl();

            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putString("currentpage",currentPage);
            editor.commit();

            //after loading page, remove loading page

            // TODO Auto-generated method stub
            super.onPageFinished(view, url);
            mProgressDialog.dismiss();
        }

        @Override
        public void onReceivedError(WebView view, int errorCode,
                                    String description, String failingUrl) {
            view.loadUrl("http://example.com/page");
        }

    }

    @Override
    public void onBackPressed() {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        String currenturl = sharedPreferences.getString("currentpage", null);

        mWebview.requestFocus();

        if (currenturl.contains("http://example.com/page")){
            moveTaskToBack(true);
        }else{
            mWebview.goBack();
        }

        if (mWebview.canGoBack()) {
            if (!DetectConnection.checkInternetConnection(Context)) {
                Toast.makeText(Context, "No Internet Connection!", Toast.LENGTH_SHORT).show();
            }

        }
    }


    public static void loadUrl(String key) {

        if (getIntentValue != null) {
            mWebview.loadUrl("http://example.com/page");
            getIntentValue = null;
        } else {
            mWebview.loadUrl("http://example.com/page");
        }

    }


    public static void reLoad() {
        mWebview.reload();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig){
        super.onConfigurationChanged(newConfig);
    }
}
Englebert answered 19/1, 2018 at 12:3 Comment(0)
E
6

Just include enableHTML5AppCache()

private void enableHTML5AppCache() {
        mWebview.getSettings().setDomStorageEnabled(true);
        mWebview.getSettings().setAppCachePath("/data/data/" + getPackageName() + "/cache");
        mWebview.getSettings().setAppCacheEnabled(true);
        mWebview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
    }
Englebert answered 13/4, 2018 at 5:6 Comment(1)
Good answer. However, instead of mWebview.getSettings().setAppCachePath("/data/data/" + getPackageName() + "/cache");, you may consider using more versatile path like: settings.setAppCachePath(getCacheDir().getAbsolutePath());Lammergeier
M
3
mWebview.getSettings().setCacheMode( WebSettings.LOAD_CACHE_ELSE_NETWORK)

This will tell the WebView to load the page from cache, but if it needs anything that isn't in the cache, it looks to the network, and when you have no connection, it will just give you the "page could not be loaded error." This is because sadly not everything is stored in the cache and even with this setting, you will notice the browser using the network.

Use WebSettings.LOAD_CACHE_ONLY

mWebview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ONLY);
Mulligatawny answered 19/1, 2018 at 12:24 Comment(0)
W
2

2021 update things have changed : Deprecated The Application Cache API is deprecated and this method will become a no-op on all Android versions once support is removed in Chromium. Consider using Service Workers instead. See https://web.dev/appcache-removal/ for more information. Read about service workers instead :) Happy Coding :P

Webby answered 17/9, 2021 at 5:37 Comment(0)
S
1

Change this line:

mWebview.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);

To:

mWebview.getSettings().setCacheMode( WebSettings.LOAD_CACHE_ELSE_NETWORK)
Schizothymia answered 19/1, 2018 at 12:7 Comment(2)
Did you try to open it when there is internet connection then make the connection off and reload the webview ?Schizothymia
yes, I did that. I think its looking for path which is not foundEnglebert

© 2022 - 2024 — McMap. All rights reserved.