Reputation: 2287
My app can run online and offline using appcache. It also opens a link on the default browser at one point. Problem is that when it is loading offline, it could't reopen the app after linking to the default broswer.
Here is my code:
public class MainActivity extends Activity
{
private WebView wv;
private ProgressBar progress;
private static String mycaturl="*url*";
private static String helpurl="*url*";
private static String fbackurl="*url*";
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitNetwork().build();
StrictMode.setThreadPolicy(policy);
if (reachable(this))
{
buildwv( savedInstanceState, WebSettings.LOAD_DEFAULT, mycaturl );
}
else
{
eolc( savedInstanceState );
}
}
@SuppressLint({ "SetJavaScriptEnabled" })
public void buildwv(Bundle sis, int load, String url)
{
if(reachable(this))
{
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
else
{
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
}
setContentView(R.layout.activity_main);
progress=(ProgressBar) findViewById(R.id.progress);
wv=(WebView) findViewById(R.id.wv);
wv.setWebViewClient( new wvc() );
wv.setHorizontalScrollBarEnabled(false);
WebSettings ws = wv.getSettings();
ws.setAppCacheMaxSize( 100 * 1024 * 1024 ); // 100MB
ws.setAppCachePath( this.getCacheDir().getAbsolutePath() );
ws.setAllowFileAccess( true );
ws.setAppCacheEnabled( true );
ws.setJavaScriptEnabled( true );
ws.setCacheMode(load);
if(sis==null)
{ wv.loadUrl(url); }
}
public void eolc(final Bundle sis)
{
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
AlertDialog.Builder ad = new AlertDialog.Builder( MainActivity.this );
ad.setTitle("Unreachable Host");
ad.setMessage("Host is unreachable. Load from cache or exit.");
ad.setIcon(R.drawable.tick);
ad.setCancelable(false);
ad.setPositiveButton( "Load from Cache", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog,int which)
{
buildwv( sis, WebSettings.LOAD_CACHE_ELSE_NETWORK, mycaturl );
}
});
ad.setNeutralButton( "Help", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
buildwv( sis, WebSettings.LOAD_CACHE_ELSE_NETWORK, helpurl );
}
});
ad.setNegativeButton( "Exit", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
finish();
}
});
ad.create();
ad.show();
}
public void alertprep(String set)
{
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
if( set=="def")
{
String a = "Connection Lost";
String b = "Connection to host was lost. Restart and load cache or exit.";
alert(a,b);
}
else if( set=="cac" )
{
String a = "Page Not Cached";
String b = "Page you're trying to view is not yet cached. Please visit help to learn how to cache.";
alert(a,b);
}
}
public void alert(String a,String b)
{
AlertDialog.Builder ad = new AlertDialog.Builder( MainActivity.this );
ad.setTitle(a);
ad.setMessage(b);
ad.setIcon(R.drawable.tick);
ad.setCancelable(false);
ad.setPositiveButton( "Restart", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog,int which)
{
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
startActivity(i);
}
});
ad.setNeutralButton( "Help", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
wv.stopLoading();
wv.loadUrl( helpurl );
}
});
ad.setNegativeButton( "Exit", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
finish();
}
});
ad.create();
ad.show();
}
private class wvc extends WebViewClient
{
public void onPageStarted(WebView view, String url, Bitmap favicon)
{
super.onPageStarted(view, url, favicon);
progress.setVisibility(View.VISIBLE);
if (url.contains(mycaturl))
{
WebSettings ws = wv.getSettings();
if ( !reachable(getApplicationContext()) )
{
if ( ws.getCacheMode() == WebSettings.LOAD_DEFAULT )
{
alertprep("def");
}
}
}
}
@Override
public void onPageFinished(WebView view, String url)
{
super.onPageFinished(view, url);
progress.setVisibility(View.GONE);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
{
super.onReceivedError(view, errorCode, description, failingUrl);
wv.loadUrl(helpurl);
WebSettings ws = wv.getSettings();
if ( ws.getCacheMode() == WebSettings.LOAD_DEFAULT )
{
alertprep("def");
}
else
{
alertprep("cac");
}
}
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
if (url != null && url.contains("dgcrfdbck"))
{
jumptofback();
return true;
} else {
return false;
}
}
}
public void jumptofback()
{
wv.getContext().startActivity(
new Intent(Intent.ACTION_VIEW, Uri.parse(fbackurl)));
}
public static boolean reachable(Context context)
{
final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo netInfo = connMgr.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected())
{
try
{
URL url = new URL(mycaturl);
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(5000);
urlc.connect();
if (urlc.getResponseCode() == 200)
{ return true; } else { return false; }
}
catch (IOException e)
{ return false; }
}
else
{ return false; }
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onBackPressed ()
{
if (wv.isFocused() && wv.canGoBack())
{ wv.goBack(); } else { finish(); }
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.item1:
wv.loadUrl( helpurl );
break;
case R.id.item2:
jumptofback();
break;
case R.id.item3:
String currurl=wv.getUrl();
wv.loadUrl(currurl);
break;
case R.id.item4:
Intent i = getBaseContext().getPackageManager()
.getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
break;
case R.id.item5:
finish();
break;
default:
break;
}
return true;
}
@Override
protected void onSaveInstanceState(Bundle outState )
{
super.onSaveInstanceState(outState);
wv.saveState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onSaveInstanceState(savedInstanceState);
wv.restoreState(savedInstanceState);
}
}
Here's the error part in the logcat:
09-30 18:25:04.375: D/AndroidRuntime(15930): Shutting down VM
09-30 18:25:04.375: W/dalvikvm(15930): threadid=1: thread exiting with uncaught exception (group=0x41b352a0)
09-30 18:25:04.380: E/AndroidRuntime(15930): FATAL EXCEPTION: main
09-30 18:25:04.380: E/AndroidRuntime(15930): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.msiecsapps.mycatlog/com.msiecsapps.mycatlog.MainActivity}: java.lang.NullPointerException
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2100)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.ActivityThread.access$600(ActivityThread.java:140)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.os.Handler.dispatchMessage(Handler.java:99)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.os.Looper.loop(Looper.java:137)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.ActivityThread.main(ActivityThread.java:4898)
09-30 18:25:04.380: E/AndroidRuntime(15930): at java.lang.reflect.Method.invokeNative(Native Method)
09-30 18:25:04.380: E/AndroidRuntime(15930): at java.lang.reflect.Method.invoke(Method.java:511)
09-30 18:25:04.380: E/AndroidRuntime(15930): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
09-30 18:25:04.380: E/AndroidRuntime(15930): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
09-30 18:25:04.380: E/AndroidRuntime(15930): at dalvik.system.NativeStart.main(Native Method)
09-30 18:25:04.380: E/AndroidRuntime(15930): Caused by: java.lang.NullPointerException
09-30 18:25:04.380: E/AndroidRuntime(15930): at com.msiecsapps.mycatlog.MainActivity.onRestoreInstanceState(MainActivity.java:305)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.Activity.performRestoreInstanceState(Activity.java:944)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1134)
09-30 18:25:04.380: E/AndroidRuntime(15930): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2078)
09-30 18:25:04.380: E/AndroidRuntime(15930): ... 11 more
Thanks in advance.
Upvotes: 0
Views: 155
Reputation: 152817
Your buildwv()
initialized the wv
variable that is used in onRestoreInstanceState()
. However, if the eolc()
branch is taken, wv
is still uninitialized i.e. null
at the end of onCreate()
since buildwv()
is only called as a response to a dialog click event.
Looks like you should initialize wv
unconditionally in onCreate()
, e.g.
setContentView(R.layout.activity_main);
wv = (WebView) findViewById(R.id.wv);
Upvotes: 2