I'm having trouble getting the hardware back key on an android phone to work with a webView. The following is the code I'm using. Every time I run the app it force closes.
package com.knowideas.transithub;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class WebViewDemo extends Activity {
private static final String LOG_TAG = "WebViewDemo";
private WebView mWebView;
private Handler mHandler = new Handler();
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Check if the key event was the BACK key and if there's history
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
// If it wasn't the BACK key or there's no web page history, bubble up to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event);
}
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
mWebView = (WebView) findViewById(R.id.webView);
WebSettings webSettings = mWebView.getSettings();
webSettings.setSavePassword(false);
webSettings.setSaveFormData(false);
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportZoom(false);
mWebView.setWebChromeClient(new WebChromeClient());
mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
mWebView.loadUrl("file:///android_asset/demo.html");
}
final class DemoJavaScriptInterface {
DemoJavaScriptInterface() {
}
/**
* This is not called on the UI thread. Post a runnable to invoke
* loadUrl on the UI thread.
*/
public void clickOnAndroid() {
mHandler.post(new Runnable() {
public void run() {
mWebView.loadUrl("javascript:wave()");
}
});
}
}
}
Here's my guess:
Your trying to catch the key event too late. You need to grab it before it gets to the webview. You do that by setting an onKeyListener.
here's how:
mWebView.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
// ignore the back key
return true;
}
// process normally
return false;
}
});
I can't to do more that just 'block' it -- and that's what I'm trying to find out in another question.
Best
-Yaakov
ON BACK PRESSED
//So links stay inside webview
webview.setWebViewClient(new WebViewClient());
webview.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View view, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
WebView webView = (WebView) view;
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
if (webView.canGoBack()) {
webView.goBack();
return true;
}
break;
}
}
return false;
}
});
Related
I have created a webview app. On pressing volume keys, my app crashes. This is the error in logcat
W/ViewRootImpl[MainActivity]: Cancelling event due to no window focus:
KeyEvent { action=ACTION_UP, keyCode=KEYCODE_VOLUME_DOWN,
scanCode=114, metaState=0, flags=0x28, repeatCount=0,
eventTime=196583031, downTime=196582864, deviceId=9, source=0x101 }
Below is my MainActivity.java file:
package app.freeairdrop.io;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
public class MainActivity extends Activity{
private ProgressBar progressBar;
private WebView webView;
private SwipeRefreshLayout mySwipeRefreshLayout;
#SuppressLint("SetJavaScriptEnabled")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setMax(100);
webView = (WebView) findViewById(R.id.webView);
webView.setWebViewClient(new WebViewClientDemo());
webView.setWebChromeClient(new WebChromeClientDemo());
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
webView.loadUrl("http://freeairdrop.io/");
mySwipeRefreshLayout = (SwipeRefreshLayout)this.findViewById(R.id.swipeContainer);
mySwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
webView.reload();
mySwipeRefreshLayout.setRefreshing(false);
}
}
);
}
private class WebViewClientDemo extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Uri uri = Uri.parse(url);
if (uri.getHost() != null && (url.startsWith("https://freeairdrop.io/") || url.startsWith("https://www.freeairdrop.io/"))) {
return false;
}
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
view.getContext().startActivity(intent);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
progressBar.setProgress(100);
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(0);
}
}
private class WebChromeClientDemo extends WebChromeClient {
public void onProgressChanged(WebView view, int progress) {
progressBar.setProgress(progress);
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
else {
finish();
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
#Override
// This method is used to detect back button
public void onBackPressed() {
if(webView.canGoBack()) {
webView.goBack();
} else {
// Let the system handle the back button
super.onBackPressed();
}
}
}
Remove
finish();
from here :
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
else {
finish();
}
add focus to webview using:
<WebView android:id="#+id/webview"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:focusable="true"/>
Or
webview.requestFocus(View.FOCUS_DOWN|View.FOCUS_UP);
Remove call to finish() from here,
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
webView.goBack();
return true;
}
else {
finish(); // Remove this, onBackPressed() should handle it.
}
return super.onKeyDown(keyCode, event);
}
I am using Navigation drawer activity and have 5 fragments, each and every fragment uses WebView to open webpage. Before I was using just one MainActivity which just opened one site and was able to go back to previous opened page easily but now I can't find anything that will let me do this. I am using this code currently in my fragments, I am using the code to go back from here and whenever I open a fragment, app just force-closes.
package com.science.s11;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
public class ask extends Fragment {
public WebView mWebView;
public ProgressBar progressBar;
public LinearLayout layoutProgress;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.ampproject, container, false);
mWebView = (WebView) v.findViewById(R.id.aboutuswebViewask);
progressBar = (ProgressBar) v.findViewById(R.id.progressBarask);
layoutProgress = (LinearLayout) v.findViewById(R.id.layoutProgressask);
mWebView.setVisibility(View.GONE);
mWebView.setOnKeyListener(new View.OnKeyListener()
{
#Override
public boolean onKey(View v, int keyCode, KeyEvent event)
{
if(event.getAction() == KeyEvent.ACTION_DOWN)
{
WebView webView = (WebView) v;
switch(keyCode)
{
case KeyEvent.KEYCODE_BACK:
if(webView.canGoBack())
{
webView.goBack();
return true;
}
break;
}
}
return false;
}
});
mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
WebSettings settings = mWebView.getSettings();
settings.setSupportMultipleWindows(true);
settings.setBuiltInZoomControls(false);
settings.setSupportZoom(false);
settings.setDisplayZoomControls(false);
mWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
mWebView.setVisibility(View.VISIBLE);
layoutProgress.setVisibility(View.GONE);
progressBar.setIndeterminate(true);
super.onPageFinished(view, url);
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
layoutProgress.setVisibility(View.VISIBLE);
progressBar.setIndeterminate(false);
super.onPageStarted(view, url, favicon);
}
});
if (isOnline()) {
mWebView.loadUrl("http://google.com");
} else {
mWebView.loadUrl("file:///android_asset/cti.html");
}
return v;
}
public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return (netInfo != null && netInfo.isConnected());
}}
Can you guys please help me?
Try this, its simple and works fine.
In all of your 5 Fragments, set the variable to public static:
public static WebView mWebView;
In your Mainactivity:
#Override
public void onBackPressed() {
if (Fragment_1.mWebView!= null) {
if (Fragment_1.mWebView.canGoBack()) {
Fragment_1.mWebView.goBack();
} else {
// do when mWebView cant go back anymore
}
}
if (Fragment_2.mWebView!= null){
if (Fragment_2.mWebView.canGoBack()) {
Fragment_2.mWebView.goBack();
} else {
// do when mWebView cant go back anymore
}
}
if (Fragment_3.mWebView!= null){
if (Fragment_3.mWebView.canGoBack()) {
Fragment_3.mWebView.goBack();
} else {
// do when mWebView cant go back anymore
}
}
if (Fragment_4.mWebView!= null){
if (Fragment_4.mWebView.canGoBack()) {
Fragment_4.mWebView.goBack();
} else {
// do when mWebView cant go back anymore
}
}
//and so on......
}
Try this:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
if (mWebView.canGoBack()) {
mWebView.goBack();
} else {
finish();
}
return true;
}
}
return super.onKeyDown(keyCode, event);
}
you can make a base fragment like this
public abstract class BaseFragments extends Fragment {
abstract public int setContentView();
public void replaceFragment(Context context, Fragment fragment) {
((BaseActivity) context).getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment).commit();
}
#Override
public void onResume() {
super.onResume();
// preferencesUtility.setuserData(context, userdata);
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP
&& keyCode == KeyEvent.KEYCODE_BACK) {
// Toast.makeText(context, "clicked", Toast.LENGTH_LONG)
// .show();
backPressed();
return true;
}
return false;
}
});
}
protected abstract void backPressed();
}
and override onBackPressed()in your fragment something like this
public class TestFragment extends BaseFragments {
#Override
public int setContentView() {
return R.layout.weblayout;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.weblayout, container, false);
cabmoneyview = (WebView) rootView.findViewById(R.id.webview);
return rootView;
}
#Override
protected void backPressed() {
// TODO Auto-generated method stub
}
}
Ok, so I get theses errors
i dont know why i get this but it seems the for the rest of the world it works for them if theres another way i have to go about doing this i will change the code but it seems as of right now my eclipse doesn't like me very much
The method onKeyDown(int, KeyEvent) of type XvGForm.XvGFormClient must override or implement a supertype method
and
The method onKeyDown(int, KeyEvent) is undefined for the type WebViewClient
CODE
#Override
public boolean onKeyDown (int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.canGoBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
ok so here is the full code
package com.xtremevisiongaming.xtremevisiongamingformapp;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.KeyEvent;
import android.view.Menu;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.view.Window;
public class XvGForm extends Activity {
private WebView mWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_xv_gform);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.loadUrl("http://www.xtremevisiongaming.com/forum/forum.php");
mWebView.setWebViewClient(new XvGFormClient());
}
private class XvGFormClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView webview, String url)
{
webview.loadUrl(url);
return true;
}
#Override
public boolean onKeyDown (int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.canGoBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_xv_gform, menu);
return true;
}
}
Your problem is that right now the onKeyDown function is declared inside the private class XvGFormClient extends WebViewClient
You just need to move one closing brackets up by one function. I add some indentation, maybe that will help you see it:
private class XvGFormClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView webview, String url)
{
webview.loadUrl(url);
return true;
}
}
#Override
public boolean onKeyDown (int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack(); // go back in only the web view
return true;
}
return super.onKeyDown(keyCode, event);
}
hi i am facing android Webview orientation issue, when change orientation then application restart and show the page from start. I am reading different answere but no solution work me that why i am giving the my code here. kindly any android developer help me and tell me where i edit my code or add something
package com.example.edarabia;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;
#SuppressLint("SetJavaScriptEnabled")
public class MainActivity extends Activity{
WebView mywebview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(isNetworkConnected() == true){
setContentView(R.layout.activity_main);
mywebview = (WebView) findViewById(R.id.webview);
mywebview.getSettings().setJavaScriptEnabled(true);
mywebview.setWebViewClient(new myWebClient());
mywebview.loadUrl("http://www.grafdom.com/operations/projects/ma/edarabiaapp/");
mywebview.getSettings().setBuiltInZoomControls(true);
mywebview.getSettings().setLoadWithOverviewMode(false);
mywebview.getSettings().setUseWideViewPort(false);
}else{
setContentView(R.layout.splash);
showBuyDialog();
}
}
// #Override
// public boolean onKeyDown(int keyCode, KeyEvent event) {
// Check if the key event was the Back button and if there's history
// if ((keyCode == KeyEvent.KEYCODE_BACK) && mywebview.canGoBack()) {
// mywebview.goBack();
// return true;
// }
// return super.onKeyDown(keyCode, event);
// }
// To handle "Back" key press event for WebView to go back to previous screen.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && mywebview.canGoBack()) {
mywebview.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public void onBackPressed() {
finish();
}
public class myWebClient extends WebViewClient
{
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
//// This method will retun boolean value if net conect then value will be true otherwise false
private boolean isNetworkConnected() {
ConnectivityManager connectivity = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null)
for (int i = 0; i < info.length; i++)
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
return false;
}
public void showBuyDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Unable to connect");
builder.setMessage("You Must have an Internet connection to use Edarabia. Please connect and try again.");
builder.setCancelable(false);
builder.setNegativeButton("Close", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
finish();
}
});
builder.show();
}
}
Add android:configChanges="keyboard|keyboardHidden|screenSize|orientation" to your activity on the AndroidManifest.xml file. It should look like this
<activity
android:name=".MainActivity"
android:configChanges="keyboard|keyboardHidden|screenSize|orientation"
android:label="#string/app_name" >
as seen here - Android WebView handling orientation changes
I'm trying to sort out a web app but cannot find a possible way to include the use of a back button via the phone's soft keys. How can I go about doing this?
i.e I want to use the back button on my phone to return to the previous viewed web page.
Thank you
Jordan
package com.wear2gym;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
public class Wear2gym extends Activity
{
final Activity activity = this;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
setContentView(R.layout.main);
WebView webView = (WebView) findViewById(R.id.WebView);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress)
{
activity.setTitle("Pumping some iron...");
activity.setProgress(progress * 100);
if(progress == 100)
activity.setTitle(R.string.app_name);
}
});
webView.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
{
Toast.makeText(activity, "Sorry but there is no internet connection! " , Toast.LENGTH_LONG).show();
view.loadUrl("file:///android_asset/nointernet.html");
// Handle the error
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl(url);
return true;
}
});
webView.loadUrl("http://wear2gym.co.uk");
webView.canGoBack();
}
}
I wouldn't recommand onBackPressed() as thatÅ› only available since API level 5
You will find great info here: http://developer.android.com/guide/webapps/webview.html
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// Check if the key event was the Back button and if there's history
if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack() {
myWebView.goBack();
return true;
}
// If it wasn't the Back key or there's no web page history, bubble up to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event);
}
override the onBackPressed() method:
#Override
public void onBackPressed() {
if(mWebView.canGoBack()) {
mWebView.goBack();
}
else {
super.onBackPressed();
}
}
This will go back on the WebView until it can't go back, in which case it will exit the Activity