Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Load Cache Page in Webview

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);
    }
}
like image 759
Observer Avatar asked Jan 19 '18 12:01

Observer


3 Answers

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);
    }
like image 146
Observer Avatar answered Nov 08 '22 12:11

Observer


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);
like image 31
ibhavikmakwana Avatar answered Nov 08 '22 10:11

ibhavikmakwana


Change this line:

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

To:

mWebview.getSettings().setCacheMode( WebSettings.LOAD_CACHE_ELSE_NETWORK)
like image 1
TREAF ALSHEMERI Avatar answered Nov 08 '22 12:11

TREAF ALSHEMERI