WebView will not load from SDcache when network adapter off

Put problem concerning Views, Layouts and other XML-Resources (like AndroidManifest) here.

WebView will not load from SDcache when network adapter off

Postby turtleboy » Tue Jan 29, 2013 11:27 am

I have an app that registers with GCM for push notifications. That code works fine and is not the source of my problem. Once registered, the app somply displays a website in a WebView. So far so good all this works if the device's network adapter is switched on.

If the network adapter is switched off then the webview should load from cache. This part is not working. I have followed the tutorial below and taken parts from it in a bit to save the website pages in a cache saved on the sdcard.

If i run the app the web site is displayed. If i then turn off the network adapter and visit the site, it will not display. I check the cache directory on the sdcard and parts of the site have been written to the cache. Why doesn't the site load from cache when off-line?

http://www.devahead.com/blog/

The tutorial shows you how to create a directory on the sdcard and write to it. The directories do exist but the webview is not restored from this cache in offline mode.

below is how i call the mainactivity that displays the webview.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. Intent i = new Intent(getApplicationContext(), MainActivity.class);
  2.                 //i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
  3.                 i.putExtra("name", "hardcoded client name");
  4.                 i.putExtra("email", "hardcoded email");
  5.                 startActivity(i);
  6.                 finish();
Parsed in 0.031 seconds, using GeSHi 1.0.8.4


Here is the full MainActivity. You can ignore the first part as that's the code that handle the GCM push notification stuff, that all works. I need to know why the webview will not load from cache.


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  import static com.bmi.bmitestapp.CommonUtilities.DISPLAY_MESSAGE_ACTION;
  2. import static com.bmi.bmitestapp.CommonUtilities.EXTRA_MESSAGE;
  3. import static com.bmi.bmitestapp.CommonUtilities.SENDER_ID;
  4.  
  5. import java.io.File;
  6.  
  7. import android.app.Activity;
  8. import android.content.BroadcastReceiver;
  9. import android.content.Context;
  10. import android.content.Intent;
  11. import android.content.IntentFilter;
  12. import android.net.ConnectivityManager;
  13. import android.net.NetworkInfo;
  14. import android.os.AsyncTask;
  15. import android.os.Bundle;
  16. import android.util.Log;
  17. import android.webkit.WebChromeClient;
  18. import android.webkit.WebSettings;
  19. import android.webkit.WebView;
  20. import android.webkit.WebViewClient;
  21. import android.widget.TextView;
  22. import android.widget.Toast;
  23. import android.webkit.*;
  24.  
  25.  
  26. import com.google.android.gcm.GCMRegistrar;
  27.  
  28. public class MainActivity extends Activity {
  29.     private static final String TAG = MainActivity.class.getSimpleName();
  30.     // label to display gcm messages
  31.     TextView lblMessage;
  32.     WebView webView;
  33.     // Asyntask
  34.     AsyncTask<Void, Void, Void> mRegisterTask;
  35.  
  36.     // Alert dialog manager
  37.     AlertDialogManager alert = new AlertDialogManager();
  38.  
  39.     // Connection detector
  40.     ConnectionDetector cd;
  41.  
  42.     public static String name;
  43.     public static String email;
  44.  
  45.     @Override
  46.     public void onCreate(Bundle savedInstanceState) {
  47.         super.onCreate(savedInstanceState);
  48.         setContentView(R.layout.activity_main);
  49.  
  50.         Log.e(TAG, "in onCreate in mainactivity");
  51.         cd = new ConnectionDetector(getApplicationContext());
  52.  
  53.         // Check if Internet present
  54. //        if (!cd.isConnectingToInternet()) {
  55. //            // Internet Connection is not present
  56. //            alert.showAlertDialog(MainActivity.this,
  57. //                    "Internet Connection Error",
  58. //                    "Please connect to working Internet connection", false);
  59. //            // stop executing code by return
  60. //            return;
  61. //        }
  62.  
  63.         // Getting name, email from intent
  64.         Intent i = getIntent();
  65.  
  66.         name = i.getStringExtra("name");
  67.         email = i.getStringExtra("email");    
  68.  
  69.         // Make sure the device has the proper dependencies.
  70.         GCMRegistrar.checkDevice(this);
  71.  
  72.         // Make sure the manifest was properly set - comment out this line
  73.         // while developing the app, then uncomment it when it's ready.
  74.         GCMRegistrar.checkManifest(this);
  75.  
  76.         lblMessage = (TextView) findViewById(R.id.lblMessage);
  77.  
  78.         registerReceiver(mHandleMessageReceiver, new IntentFilter(
  79.                 DISPLAY_MESSAGE_ACTION));
  80.  
  81.         // Get GCM registration id
  82.         final String regId = GCMRegistrar.getRegistrationId(this);
  83.  
  84.         // Check if regid already presents
  85.         if (regId.equals("")) {
  86.             // Registration is not present, register now with GCM
  87.             GCMRegistrar.register(this, SENDER_ID);
  88.         } else {
  89.             // Device is already registered on GCM
  90.             if (GCMRegistrar.isRegisteredOnServer(this)) {
  91.                 // Skips registration.
  92.                 Toast.makeText(getApplicationContext(), "Already registered with GCM", Toast.LENGTH_LONG).show();
  93.             } else {
  94.                 // Try to register again, but not in the UI thread.
  95.                 // It's also necessary to cancel the thread onDestroy(),
  96.                 // hence the use of AsyncTask instead of a raw thread.
  97.                 final Context context = this;
  98.                 mRegisterTask = new AsyncTask<Void, Void, Void>() {
  99.  
  100.                     @Override
  101.                     protected Void doInBackground(Void... params) {
  102.                         // Register on our server
  103.                         // On server creates a new user
  104.                         ServerUtilities.register(context, name, email, regId);
  105.                         return null;
  106.                     }
  107.  
  108.                     @Override
  109.                     protected void onPostExecute(Void result) {
  110.                         mRegisterTask = null;
  111.                     }
  112.  
  113.                 };
  114.                 mRegisterTask.execute(null, null, null);
  115.             }
  116.         }
  117.  
  118.             webView = (WebView)findViewById(R.id.webView1);
  119.             // Initialize the WebView
  120.             webView.getSettings().setSupportZoom(true);
  121.             webView.getSettings().setBuiltInZoomControls(true);
  122.             webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
  123.             webView.setScrollbarFadingEnabled(true);
  124.             webView.getSettings().setLoadsImagesAutomatically(true);
  125.  
  126.  
  127.  
  128.  
  129.  
  130.             webView.getSettings().setDomStorageEnabled(true);
  131.  
  132.             // Set cache size to 8 mb by default. should be more than enough
  133.             webView.getSettings().setAppCacheMaxSize(1024*1024*8);
  134.  
  135.             // This next one is crazy. It's the DEFAULT location for your app's cache
  136.             // But it didn't work for me without this line.
  137.             // UPDATE: no hardcoded path. Thanks to Kevin Hawkins
  138.             String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
  139.             Log.e(TAG, "appCachePath = " + appCachePath);
  140.             webView.getSettings().setAppCachePath(appCachePath);
  141.             webView.getSettings().setAllowFileAccess(true);
  142.             webView.getSettings().setAppCacheEnabled(true);
  143.  
  144.  
  145.  
  146.  
  147.             // Load the URLs inside the WebView, not in the external web browser
  148.             webView.setWebViewClient(new WebViewClient());  
  149.  
  150.             if (savedInstanceState == null)
  151.                         {
  152.  
  153.  
  154.  
  155.         if(isNetworkAvailable() == true){
  156.             Log.e(TAG, "we have a network connection");
  157.             webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
  158.  
  159.             webView.loadUrl("http://bmi.cubecore.co.uk");
  160.  
  161.  
  162.         } else {
  163.             Log.e(TAG, "we don't have a network connection");
  164.             webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ONLY);
  165.  
  166.             webView.loadUrl("http://bmi.cubecore.co.uk");
  167.         }
  168.  
  169.  
  170.                         }
  171.  
  172.     }      //end of oncreate
  173.  
  174.  
  175.     private boolean isNetworkAvailable() {
  176.         ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
  177.         NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
  178.         return activeNetworkInfo != null;
  179.     }
  180.  
  181.  
  182.     /**
  183.      * Receiving push messages
  184.      * */
  185.     private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {
  186.         @Override
  187.         public void onReceive(Context context, Intent intent) {
  188.             String newMessage = intent.getExtras().getString(EXTRA_MESSAGE);
  189.             // Waking up mobile if it is sleeping
  190.             WakeLocker.acquire(getApplicationContext());
  191.  
  192.             /**
  193.              * Take appropriate action on this message
  194.              * depending upon your app requirement
  195.              * For now i am just displaying it on the screen
  196.              * */
  197.  
  198.             // Showing received message
  199.             lblMessage.append(newMessage + "\n");
  200.             Toast.makeText(getApplicationContext(), "New Message: " + newMessage, Toast.LENGTH_LONG).show();
  201.  
  202.             // Releasing wake lock
  203.             WakeLocker.release();
  204.         }
  205.     };
  206.  
  207.     @Override
  208.     protected void onDestroy() {
  209.         super.onDestroy();
  210.  
  211.         // Clear the cache (this clears the WebViews cache for the entire application)
  212.         //webView.clearCache(false);
  213.  
  214.         if (mRegisterTask != null) {
  215.             mRegisterTask.cancel(true);
  216.         }
  217.         try {
  218.             unregisterReceiver(mHandleMessageReceiver);
  219.             GCMRegistrar.onDestroy(this);
  220.         } catch (Exception e) {
  221.             Log.e("UnRegister Receiver Error", "> " + e.getMessage());
  222.         }
  223.  
  224.  
  225.  
  226.     }
  227.  
  228.  
  229.  
  230.     @Override
  231.     public void onBackPressed() {
  232.         super.onBackPressed();
  233.  
  234.  
  235.     }
  236.  
  237.     @Override
  238.     protected void onResume() {
  239.         super.onResume();
  240.         Log.e(TAG, "in onResume in mainactivity");
  241.  
  242.     }
  243.  
  244.  
  245.  
  246.     @Override
  247.     public File getCacheDir()
  248.     {
  249.         // NOTE: this method is used in Android 2.1
  250. Log.e(TAG, "getcachedir");
  251.         return getApplicationContext().getCacheDir();
  252.     }
  253.  
  254.     @Override
  255.     protected void onSaveInstanceState(Bundle outState)
  256.     {
  257.         super.onSaveInstanceState(outState);
  258.  
  259.         // Save the state of the WebView
  260.         webView.saveState(outState);
  261.     }
  262.  
  263.     @Override
  264.     protected void onRestoreInstanceState(Bundle savedInstanceState)
  265.     {
  266.         super.onRestoreInstanceState(savedInstanceState);
  267.  
  268.         // Restore the state of the WebView
  269.         webView.restoreState(savedInstanceState);
  270.     }
  271.  
  272. }
Parsed in 0.064 seconds, using GeSHi 1.0.8.4



Here's the code from the tutorial above that writes to the sdcard.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package com.bmi.bmitestapp;
  2.  
  3. import java.io.File;
  4.  
  5. import android.app.Application;
  6. import android.os.Environment;
  7. import android.util.Log;
  8.  
  9. public class ApplicationExt extends Application
  10. {
  11.     private static final String TAG = ApplicationExt.class.getSimpleName();
  12.     // NOTE: the content of this path will be deleted
  13.     //       when the application is uninstalled (Android 2.2 and higher)
  14.     protected File extStorageAppBasePath;
  15.  
  16.     protected File extStorageAppCachePath;
  17.  
  18.     @Override
  19.     public void onCreate()
  20.     {
  21.         super.onCreate();
  22.          Log.e(TAG, "inside appext");
  23.         // Check if the external storage is writeable
  24.         if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
  25.         {
  26.  
  27.             // Retrieve the base path for the application in the external storage
  28.             File externalStorageDir = Environment.getExternalStorageDirectory();
  29.  
  30.             if (externalStorageDir != null)
  31.             {
  32.                 // {SD_PATH}/Android/data/com.devahead.androidwebviewcacheonsd
  33.                 extStorageAppBasePath = new File(externalStorageDir.getAbsolutePath() +
  34.                     File.separator + "Android" + File.separator + "data" +
  35.                     File.separator + getPackageName());
  36.             }
  37.  
  38.             if (extStorageAppBasePath != null)
  39.             {
  40.                 // {SD_PATH}/Android/data/com.devahead.androidwebviewcacheonsd/cache
  41.                 extStorageAppCachePath = new File(extStorageAppBasePath.getAbsolutePath() +
  42.                     File.separator + "cache");
  43.  
  44.                 boolean isCachePathAvailable = true;
  45.  
  46.                 if (!extStorageAppCachePath.exists())
  47.                 {
  48.                     // Create the cache path on the external storage
  49.                     isCachePathAvailable = extStorageAppCachePath.mkdirs();
  50.                 }
  51.  
  52.                 if (!isCachePathAvailable)
  53.                 {
  54.                     // Unable to create the cache path
  55.                     extStorageAppCachePath = null;
  56.                 }
  57.             }
  58.         }
  59.     }
  60.  
  61.     @Override
  62.     public File getCacheDir()
  63.     {
  64.         // NOTE: this method is used in Android 2.2 and higher
  65.  
  66.         if (extStorageAppCachePath != null)
  67.         {
  68.             // Use the external storage for the cache
  69.             Log.e(TAG, "extStorageAppCachePath = " + extStorageAppCachePath);
  70.             return extStorageAppCachePath;
  71.         }
  72.         else
  73.         {
  74.             // /data/data/com.devahead.androidwebviewcacheonsd/cache
  75.             return super.getCacheDir();
  76.         }
  77.     }
  78. }
  79.  
  80. android caching webview
Parsed in 0.043 seconds, using GeSHi 1.0.8.4
turtleboy
Once Poster
Once Poster
 
Posts: 1
Joined: Mon Jan 30, 2012 6:49 pm

Top

Return to View, Layout & Resource Problems

Who is online

Users browsing this forum: No registered users and 5 guests