Skip to content

Instantly share code, notes, and snippets.

@myamamic
Created November 7, 2013 09:01
Show Gist options
  • Save myamamic/7351405 to your computer and use it in GitHub Desktop.
Save myamamic/7351405 to your computer and use it in GitHub Desktop.
[android][java] WebViewでBasic認証入力ダイアログを出す
package com.example.sample;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
/**
* HTTP authentication dialog.
*/
public class HttpAuthenticationDialog {
private final Context mContext;
private final String mHost;
private final String mRealm;
private AlertDialog mDialog;
private TextView mUsernameView;
private TextView mPasswordView;
private OkListener mOkListener;
private CancelListener mCancelListener;
/**
* Creates an HTTP authentication dialog.
*/
public HttpAuthenticationDialog(Context context, String host, String realm) {
mContext = context;
mHost = host;
mRealm = realm;
createDialog();
}
private String getUsername() {
return mUsernameView.getText().toString();
}
private String getPassword() {
return mPasswordView.getText().toString();
}
/**
* Sets the listener that will be notified when the user submits the credentials.
*/
public void setOkListener(OkListener okListener) {
mOkListener = okListener;
}
/**
* Sets the listener that will be notified when the user cancels the authentication
* dialog.
*/
public void setCancelListener(CancelListener cancelListener) {
mCancelListener = cancelListener;
}
/**
* Shows the dialog.
*/
public void show() {
mDialog.show();
mUsernameView.requestFocus();
}
/**
* Hides, recreates, and shows the dialog. This can be used to handle configuration changes.
*/
public void reshow() {
String username = getUsername();
String password = getPassword();
int focusId = mDialog.getCurrentFocus().getId();
mDialog.dismiss();
createDialog();
mDialog.show();
if (username != null) {
mUsernameView.setText(username);
}
if (password != null) {
mPasswordView.setText(password);
}
if (focusId != 0) {
mDialog.findViewById(focusId).requestFocus();
} else {
mUsernameView.requestFocus();
}
}
private void createDialog() {
LayoutInflater factory = LayoutInflater.from(mContext);
View v = factory.inflate(R.layout.http_authentication, null);
mUsernameView = (TextView) v.findViewById(R.id.username_edit);
mPasswordView = (TextView) v.findViewById(R.id.password_edit);
mPasswordView.setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
mDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick();
return true;
}
return false;
}
});
String title = mContext.getText(R.string.sign_in_to).toString().replace(
"%s1", mHost).replace("%s2", mRealm);
mDialog = new AlertDialog.Builder(mContext)
.setTitle(title)
//.setIconAttribute(android.R.attr.alertDialogIcon)
.setView(v)
.setPositiveButton(R.string.action, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if (mOkListener != null) {
mOkListener.onOk(mHost, mRealm, getUsername(), getPassword());
}
}})
.setNegativeButton(R.string.cancel,new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if (mCancelListener != null) mCancelListener.onCancel();
}})
.setOnCancelListener(new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
if (mCancelListener != null) mCancelListener.onCancel();
}})
.create();
// Make the IME appear when the dialog is displayed if applicable.
mDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
/**
* Interface for listeners that are notified when the user submits the credentials.
*/
public interface OkListener {
void onOk(String host, String realm, String username, String password);
}
/**
* Interface for listeners that are notified when the user cancels the dialog.
*/
public interface CancelListener {
void onCancel();
}
}
package com.example.sample;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.webkit.HttpAuthHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.GeolocationPermissions.Callback;
public class MainActivity extends Activity {
private static final String TAG = "LOG";
// WEBサイト
private static final String PATH = "http://hogehoge/";
// 機種名リスト (ro.poduct.model)
// Galaxy S3のWebViewクラッシュ対策が必要な機種名
private static final String USE_SOFTWARE_LAYER_DEVICE[] = {
"SC-06D", // NTT docomo, Galaxy S3
"SC-03E", // NTT docomo, Galaxy S3 alpha
"SCL21", // au, Galaxy S3 Progre
"GT-I9300", // Global model, Galaxy S3
};
private WebView mWebView = null;
private Activity mActivity = null;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView)findViewById(R.id.webView1);
if (useSoftwareLayer()) {
Log.d(TAG, "This device has WebView crash issue. Use software layer.");
mWebView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
mWebView.getSettings().setAppCacheEnabled(true);
mWebView.getSettings().setAppCacheMaxSize(8 * 1024 * 1024);
mWebView.getSettings().setAppCachePath("/data/data/" + getPackageName() + "/cache");
// 右側のスクロールバーの隙間をなくす
mWebView.setVerticalScrollbarOverlay(true);
// WebViewに、WebViewClientとWebChromeClientを設定する。
mWebView.setWebViewClient(mWebViewClient);
mWebView.setWebChromeClient(mWebChromeClient);
mWebView.loadUrl(PATH);
mWebView.getSettings().setJavaScriptEnabled(true);
}
/**
* Galaxy S3のWebViewクラッシュ対策が必要な機種かどうかを判定する
*/
private boolean useSoftwareLayer() {
for (String model : USE_SOFTWARE_LAYER_DEVICE) {
if (Build.MODEL.contains(model)) {
return true;
}
}
return false;
}
/**
* onKeyDown()は、キーが押された時に呼ばれる
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// 戻る(Back)キーが押されたかどうか
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (mWebView != null && mWebView.canGoBack()) {
mWebView.goBack();
return true;
} else {
// 戻る履歴がない場合は、何もしない(Activityを終了する)。
}
}
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.main, menu);
return true;
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (mHttpAuthenticationDialog != null) {
mHttpAuthenticationDialog.reshow();
}
super.onConfigurationChanged(newConfig);
}
@Override
protected void onDestroy() {
// WebViewリソースの解放
if (mWebView != null) {
// ページの読み込みを停止する
mWebView.stopLoading();
// セットしたWebViewClientを解除する
mWebView.setWebViewClient(null);
// セットしたWebChromeClientを解除する
mWebView.setWebChromeClient(null);
// WebViewの終了処理
mWebView.clearCache(false);
mWebView.destroy();
mWebView = null;
}
super.onDestroy();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
}
private WebViewClient mWebViewClient = new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView webview, String url) {
return false;
}
/**
* Basic認証関連の処理
* - HTTP basic authentication が要求された時に呼び出されるメソッド
*/
@Override
public void onReceivedHttpAuthRequest(WebView view,
HttpAuthHandler handler, String host, String realm) {
//Log.d(TAG, "onReceivedHttpAuthRequest(): host=" + host + " realm=" + realm);
String username = null;
String password = null;
boolean reuseHttpAuthUsernamePassword
= handler.useHttpAuthUsernamePassword();
if (reuseHttpAuthUsernamePassword && view != null) {
String[] credentials = view.getHttpAuthUsernamePassword(host, realm);
if (credentials != null && credentials.length == 2) {
username = credentials[0];
password = credentials[1];
}
}
if (username != null && password != null) {
handler.proceed(username, password);
} else {
showHttpAuthentication(handler, host, realm);
}
}
};
private WebChromeClient mWebChromeClient = new WebChromeClient() {
/**
* JavaScriptからの位置情報取得を許可する
* 今回は、ユーザーに位置情報取得するかどうかの確認ダイアログは表示しない
*/
@TargetApi(Build.VERSION_CODES.ECLAIR)
@Override
public void onGeolocationPermissionsShowPrompt(final String origin,
final Callback callback) {
super.onGeolocationPermissionsShowPrompt(origin, callback);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
callback.invoke(origin, true, false);
}
}
};
// ***********************************************************************/
// Basic認証情報入力ダイアログの表示関連処理
// - テスト用サイトは、Basic認証がかかっているため、ユーザー名とパスワードを入力して、
// 認証を解除する必要がある。
// - 本番サイトではBasic認証は必要ないため、本コードは削除します。
// ***********************************************************************/
private HttpAuthenticationDialog mHttpAuthenticationDialog;
/**
* Displays an http-authentication dialog.
*/
void showHttpAuthentication(final HttpAuthHandler handler, String host, String realm) {
mHttpAuthenticationDialog = new HttpAuthenticationDialog(MainActivity.this, host, realm);
mHttpAuthenticationDialog.setOkListener(new HttpAuthenticationDialog.OkListener() {
public void onOk(String host, String realm, String username, String password) {
setHttpAuthUsernamePassword(host, realm, username, password);
handler.proceed(username, password);
mHttpAuthenticationDialog = null;
}
});
mHttpAuthenticationDialog.setCancelListener(new HttpAuthenticationDialog.CancelListener() {
public void onCancel() {
handler.cancel();
//mController.onUpdatedSecurityState(tab);
mHttpAuthenticationDialog = null;
}
});
mHttpAuthenticationDialog.show();
}
/**
* Set HTTP authentication password.
*
* @param host The host for the password
* @param realm The realm for the password
* @param username The username for the password. If it is null, it means
* password can't be saved.
* @param password The password
*/
public void setHttpAuthUsernamePassword(String host, String realm,
String username,
String password) {
if (mWebView != null) {
mWebView.setHttpAuthUsernamePassword(host, realm, username, password);
}
}
// Basic認証関連の処理 ここまで
// ***********************************************************************/
}
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">AppName</string>
<string name="action_settings">Settings</string>
<!-- Basic認証処理用の文字列リソース -->
<string name="sign_in_to">Sign in to <xliff:g id="hostname">%s1</xliff:g> \"<xliff:g id="realm">%s2</xliff:g>\"</string>
<string name="username">Name</string>
<string name="password">Password</string>
<string name="action">Sign in</string>
<string name="cancel">Cancel</string>
</resources>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment