Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android webview after onJsAlert not responding taps

I have override my WebChromeClient's onJsAlert behavior like:

WebChromeClient wvcc = new WebChromeClient() {
            @Override
            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
    //...
    return true;
    }
}

my application successfully handle the Js alerts and suppressed the original alert. However, after the alert event, I can no longer click my buttons(in list-items of listview) on the web page in my webview. I am currently using jquery mobile to build my web.

Is there anything else I should aware of?

like image 574
Abby Chau Yu Hoi Avatar asked Apr 09 '13 03:04

Abby Chau Yu Hoi


3 Answers

I just faced the exactly same problem. I wanted to generate a custom android dialog instead of the alert, to this is the final solution:

myWebView.setWebChromeClient(new WebChromeClient() {
    @Override
    public boolean onJsAlert(WebView view, final String url, String message,
            JsResult result) {

        AlertDialog.Builder builder = new AlertDialog.Builder(
                MainActivity.this);
        builder.setMessage(message)
                .setNeutralButton("OK", new OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {
                        arg0.dismiss();
                    }
                }).show();
        result.cancel();
        return true;
    }
});

The key is the result.cancel(); and return true;, I tested in several combinations, and the only one that did not fired the default JS alert AND didn't caused the touch problem was this combination

like image 110
RMalke Avatar answered Nov 14 '22 08:11

RMalke


you should call result.confirm() method, my solution is :

        public boolean onJsAlert(WebView view, String url, String message,
                final JsResult result) {
            Log.i("MainActivity", "onJsAlert url=" + url + ";message=" + message);
            Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
            result.confirm();
            return true;
        }
like image 37
yangzx Avatar answered Nov 14 '22 08:11

yangzx


I also faced the similar problem (but with onJsPrompt in my case) and the suggested solution did not work for me. I have already had the calls to result.cancel()/result.confirm() and return true from the handler. The key for the fix was found in the source code of JsDialogHelper.

This was the line which I spotted to solve my issue:

builder.setOnCancelListener(new CancelListener());

The complete handler code:

  @Override
  public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result)
  {
    final EditText data = new EditText(view.getContext());
    AlertDialog.Builder b = new AlertDialog.Builder(view.getContext())
    .setTitle(view.getTitle())
    .setView(data)
    .setMessage(message)
    .setOnCancelListener(new CancelListener(result)) // if this line is missing, WebView remains unresponsive after the dialog is shown and closed once
    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener()
    {
      @Override
      public void onClick(DialogInterface dialog, int which)
      {
        result.confirm(data.getText().toString());
      }
    })
    .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener()
    {
      @Override
      public void onClick(DialogInterface dialog, int which)
      {
        result.cancel();
      }
    });

    b.show();

    return true;
  }

where CancelListener can be defined as a simple stub class:

private class CancelListener implements DialogInterface.OnCancelListener,
DialogInterface.OnClickListener
{
  CancelListener(JsResult result)
  {
    mResult = result;
  }

  private final JsResult mResult;

  @Override
  public void onCancel(DialogInterface dialog)
  {
    mResult.cancel();
  }

  @Override
  public void onClick(DialogInterface dialog, int which)
  {
    mResult.cancel();
  }
}      

I'm not sure if this is a bug in WebView, or is it required to always have a cancel listener defined to keep webview's dialogs working properly.

like image 40
Stan Avatar answered Nov 14 '22 07:11

Stan