WebViewでBASIC認証をする時に入力ダイアログを表示する

WebViewでふつーにBASIC認証をする方法

いわゆるダイアログを表示するUI)の情報を探すのに手間取ったのでメモ。

処理

大きな流れは以下2つ。 - getHttpAuthUsernamePassword でID/PWを取得 - なければダイアログを表示して保存する setHttpAuthUsernamePassword

handler.useHttpAuthUsernamePassword の意味だけど、次ページ以降で認証を継続するため。書いておかないとページ遷移のたびに認証ダイアログがでてしまう。

ハマった点

handler は proceed()cancel() のいずれかを使って認証リクエストを完了させないといけない。よくリファレンスを見たら書いてあったのだけど、最初 cancel() を使っていなくて1回しか認証ダイアログがでてこない状態になってしまった。

private class MyWebClient extends WebViewClient {
  @Override
  public void onReceivedHttpAuthRequest(WebView view,
      final HttpAuthHandler handler, final String host, final String realm) {

    String userName = null;
    String userPass = null;

    if (handler.useHttpAuthUsernamePassword() && view != null) {
      String[] haup = view.getHttpAuthUsernamePassword(host, realm);
      if (haup != null && haup.length == 2) {
        userName = haup[0];
        userPass = haup[1];
      }
    }

    if (userName != null && userPass != null) {
      handler.proceed(userName, userPass);
    } else {
      showHttpAuthDialog(handler, host, realm, null, null, null);

      // If you hope for the state that the username/password is input.
      //showHttpAuth(handler, host, realm, null, "username", "password");
    }
  }
}


private void showHttpAuthDialog(final HttpAuthHandler handler,
          final String host, final String realm, final String title,
          final String name, final String password) {

  LayoutInflater factory = LayoutInflater.from(activity);
  final View textEntryView = factory.inflate(
      R.layout.basicauth_entry, null);

  // username/passwordを受け取った場合はダイアログに入力する処理とか

  mHttpAuthDialog = new AlertDialog.Builder(activity);
  mHttpAuthDialog.setTitle("Enter the password")
    .setView(textEntryView)
    .setCancelable(false);
  mHttpAuthDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
      EditText etUserName = (EditText) textEntryView.findViewById(R.id.username_edit);
      String userName = etUserName.getText().toString();
      EditText etUserPass = (EditText) textEntryView.findViewById(R.id.password_edit);
      String userPass = etUserPass.getText().toString();

      webview.setHttpAuthUsernamePassword(host, realm, user, pass);

      handler.proceed(userName, userPass);
      mHttpAuthDialog = null;
    }
  });
  mHttpAuthDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int whichButton) {
          handler.cancel();
      mHttpAuthDialog = null;
    }
  });

  mHttpAuthDialog.create().show();
}