반응형

 

    private void onWebViewSet() {
        wvMainWebview.addJavascriptInterface(new AndroidBridge(), Common.ANDROID_BRIDGE_NAME);
        wvMainWebview.setWebViewClient(new mMainWebviewClient());
        wvMainWebview.setWebChromeClient(new mMainWebChromeClient());
    }

 

JavascriptInterface 

AndroidBridge이름으로 웹과 통신하는 클래스를 만들어줍니다.

이녀석의 역할은 웹에서 앱으로 문자열을 전달합니다. (문자열을 이용해 원하는 기능을 구현할수있습니다.)

 

private class AndroidBridge {
    @JavascriptInterface
    public void executeMobile(final String arg) {
        mAndroidBridgeHandler.post(new Runnable() {
            @Override
            public void run() {
                //arg를 string type으로 받아와 데이터 처리한다.
            }
        }
    }
}

 

 

 

WebViewClient

페이지가 로드를 시작했을때 , 오류가 났을때, 로드가 완료 했을때 등 ... 현 페이지에 load상태를 알수있다.

 

   private class mMainWebviewClient extends WebViewClient {
        private static final String TAG ="mMainWebviewClient";

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            L.i("shouldOverrideUrlLoading(), url : " + url);

            setUrlNameAndSetLogListener(url);

            if( url.startsWith("http:") || url.startsWith("https:") ) {
                return false;
            }

            if (url.startsWith("tel:")) {
                Intent tel = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
                startActivity(tel);
                return true;
            }

            else if (url.startsWith("mailto:")) {
                String body = "Enter your Question, Enquiry or Feedback below:\n\n";
                Intent mail = new Intent(Intent.ACTION_SEND);
                mail.setType("application/octet-stream");
                mail.putExtra(Intent.EXTRA_EMAIL, new String[]{"email address"});
                mail.putExtra(Intent.EXTRA_SUBJECT, "Subject");
                mail.putExtra(Intent.EXTRA_TEXT, body);
                startActivity(mail);
                return true;
            }

            else if (url.startsWith("intent:")) {
                try {
                    Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    Intent existPackage = getPackageManager().getLaunchIntentForPackage(intent.getPackage());
                    if (existPackage != null) {
                        startActivity(intent);
                    } else {
                        Intent marketIntent = new Intent(Intent.ACTION_VIEW);
                        marketIntent.setData(Uri.parse("market://details?id=" + intent.getPackage()));
                        startActivity(marketIntent);
                    }
                    return true;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }


            return true;
        }

        @TargetApi(Build.VERSION_CODES.M)
        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            onReceivedError(view, error.getErrorCode(), error.getDescription().toString(), request.getUrl().toString());
        }
        @SuppressWarnings("deprecation")
        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            String message = getResources().getString(R.string.webview_error_unkown);
            switch(errorCode) {
                case ERROR_AUTHENTICATION:            // 서버에서 사용자 인증 실패
                    message = getResources().getString(R.string.webview_error_authentication);
                    break;
                case ERROR_BAD_URL:                    // 잘못된 URL
                    message = getResources().getString(R.string.webview_error_bad_url);
                    break;
                case ERROR_CONNECT:                    // 서버로 연결 실패
                    message = getResources().getString(R.string.webview_error_connect);
                    break;
                case ERROR_FAILED_SSL_HANDSHAKE:     // SSL handshake 수행 실패
                    message = getResources().getString(R.string.webview_error_failed_ssl_handshake);
                    break;
                case ERROR_FILE:                        // 일반 파일 오류
                    message = getResources().getString(R.string.webview_error_file);
                    break;
                case ERROR_FILE_NOT_FOUND:            // 파일을 찾을 수 없습니다
                    message = getResources().getString(R.string.webview_error_file_not_found);
                    break;
                case ERROR_HOST_LOOKUP:               // 서버 또는 프록시 호스트 이름 조회 실패
                    message = getResources().getString(R.string.webview_error_host_lookup);
                    break;
                case ERROR_IO:                         // 서버에서 읽거나 서버로 쓰기 실패
                    message = getResources().getString(R.string.webview_error_io);
                    break;
                case ERROR_PROXY_AUTHENTICATION:    // 프록시에서 사용자 인증 실패
                    message = getResources().getString(R.string.webview_error_proxy_auttentication);
                    break;
                case ERROR_REDIRECT_LOOP:            // 너무 많은 리디렉션
                    message = getResources().getString(R.string.webview_error_redirect_loop);
                    break;
                case ERROR_TIMEOUT:                   // 연결 시간 초과
                    message = getResources().getString(R.string.webview_error_timeout);
                    break;
                case ERROR_TOO_MANY_REQUESTS:       // 페이지 로드중 너무 많은 요청 발생
                    message = getResources().getString(R.string.webview_error_too_many_requests);
                    break;
                case ERROR_UNKNOWN:                   // 일반 오류
                    message = getResources().getString(R.string.webview_error_unkown);
                    break;
                case ERROR_UNSUPPORTED_AUTH_SCHEME: // 지원되지 않는 인증 체계
                    message = getResources().getString(R.string.webview_error_unsupported_auth_scheme);
                    break;
                case ERROR_UNSUPPORTED_SCHEME:       // URI가 지원되지 않는 방식
                    message = getResources().getString(R.string.webview_error_unsupported_scheme);
                    break;
            }
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            super.onPageStarted(view, url, favicon);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
        }
    }​

string.xml

<string name="webview_error_authentication">서버에서 사용자 인증 실패</string>
<string name="webview_error_bad_url">잘못된 URL</string>
<string name="webview_error_connect">서버로 연결 실패</string>
<string name="webview_error_failed_ssl_handshake">SSL handshake 수행 실패</string>
<string name="webview_error_file">일반 파일 오류</string>
<string name="webview_error_file_not_found">파일을 찾을 수 없습니다</string>
<string name="webview_error_host_lookup">서버 또는 프록시 호스트 이름 조회 실패</string>
<string name="webview_error_io">서버에서 읽거나 서버로 쓰기 실패</string>

<string name="webview_error_proxy_auttentication">프록시에서 사용자 인증 실패</string>
<string name="webview_error_redirect_loop">너무 많은 리디렉션</string>
<string name="webview_error_timeout">연결 시간 초과</string>
<string name="webview_error_too_many_requests">페이지 로드중 너무 많은 요청 발생</string>
<string name="webview_error_unkown">일반 오류</string>
<string name="webview_error_unsupported_auth_scheme">지원되지 않는 인증 체계</string>
<string name="webview_error_unsupported_scheme">URI가 지원되지 않는 방식</string>

WebChromeClient

 

javascript의 기본적인기능인 alert이나 confirm등을 제어해 ui를 입혀줄수있는 녀석이다.

   public class mMainWebChromeClient extends WebChromeClient {
        @Override
        public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
            callback.invoke(origin, true, false);
        }

        @Override
        public void onProgressChanged(WebView view, int progress) {
            L.d("onProgressChanged, progress : " + progress);
            if ( progress == 100 ) {
                showLoading( false );
                mEventHandler.removeMessages( Common.HANDLER_WEBVIEW_CONNECTION_CANCEL );
            }
        }

        @Override
        public boolean onJsAlert(WebView view, String url, String message, final android.webkit.JsResult result) {
            new AlertDialog.Builder(view.getContext())
                    .setTitle(getText(R.string.notice))
                    .setTitle("")
                    .setMessage(message)
                    .setPositiveButton(android.R.string.ok,
                            new AlertDialog.OnClickListener() {
                                public void onClick(DialogInterface dialog, int which) {
                                    result.confirm();
                                }
                            })
                    .setCancelable(false)
                    .create()
                    .show();
            return true;
        }

        @Override
        public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
            new AlertDialog.Builder(view.getContext())
                    .setTitle(getText(R.string.notice))
                    .setTitle("")
                    .setMessage(message)
                    .setPositiveButton(android.R.string.ok,
                            new AlertDialog.OnClickListener(){
                                public void onClick(DialogInterface dialog, int which) {
                                    result.confirm();
                                }
                            })
                    .setNegativeButton(android.R.string.cancel,
                            new AlertDialog.OnClickListener(){
                                public void onClick(DialogInterface dialog, int which) {
                                    result.cancel();
                                }
                            })
                    .setCancelable(false)
                    .create()
                    .show();
            return true;
        }
    }

// 자바 스크립트 사용
webSettings.setjavaScriptEnabled(true);



// mixed content 처리 여부

webSettings.setMixedContentMode(int)

MIXED_CONTENT_ALWAYS_ALLOW

MIXED_CONTENT_COMPATIBILITY_MODE

MIXED_CONTENT_NEVER_ALLOW



// DOM Storage Api 허용 여부

webSettings.setDomStorageEnabled(true);

이 부분이 중요한게 특정 사이트의 경우 메뉴 버튼을 이 API 를 사용하는 경우가 있어 이것을 허용해주지 않으면 버튼을 눌렀는데 반응이 없는 경우가 있다. 

예시 > rakuten.co.jp



// 기본 인코딩 설정

webSettings.setDefaultTextEncodingName("UTF-8");

// 웹 뷰에 맞게 출력

webSettings.setLoadWithOverviewMode(true);

webSettings.setUseWideViewPort(true);



// 플러그인 사용

webSettings.setPluginState(PluginState.ON);



// 화면 줌 컨트롤과 제스처를 사용하여 확대

webSettings.setSupportZoom(true);



// 내장 줌 컨트롤 사용

webSettings.setBuildInZoomControls(true);

// 내장 줌 컨트롤 표시 여부

webSettings.setDisplayZoomControls(false);



// 앱 캐시 사용 여부 설정

webSettings.setAppCacheEnabled(true);

// 앱 캐시 크기 설정

webSettings.setAppCacheMaxsize(1024*1024*8);

// 캐시 파일 경로 설정

webSettings.setAppCachePath(path);

// 캐시 방식 설정

webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);



// 암호 저장

webSettings.setSavepassword(true);



// 양식 데이터 저장

webSettings.setSaveFormData(true);



// 웹 뷰 내에서 파일 액세스 활성화

webSettings.setAllowFileAccess(true); API 3

파일에 접근하는 것을 허용

webSettings.getAllowFileAccessFromFileURLs(true); API 16

파일 구성표 URL의 컨텍스트에서 실행중인 JavaScript가 다른 파일 구성표 URL의 콘텐츠에 액세스 할 수 있는지 여부를 가져옵니다.

webSettings.getAllowUniversalAccessFromFileURLS(true); API 16

파일 구성표 URL의 컨텍스트에서 실행되는 JavaScript가 모든 출처의 콘텐츠에 액세스 할 수 있는지 여부를 가져옵니다. 여기에는 다른 파일 구성표 URL의 내용에 대한 액세스가 포함됩니다.



// 마우스 오버를 활성화 하기 위해 Light Touch를 사용 여부 설정

webSettings.setLighttouchEnabled(true);
반응형

+ Recent posts