[Android, Hybrid] JavascriptInterface 사용법.

Posted by Find my true self Fimtrus
2014.06.24 14:21 Programming/Hybrid App

아이폰의 경우 Native와 Web간의 통신을 위해서 scheme를 이용하지만 


안드로이드에서는 JavascriptInterface를 이용하여 더욱 편하게 데이터를 주고 받을 수 있다.

예제로 간단한 Toast를 보여주는 인터페이스를 만들어 보겠다.


먼저 웹뷰에 추가 시킬 JavascriptInterface 클래스를 만든다.


public class WebViewInterface {

	private WebView mAppView;
	private Activity mContext;

	/**
	 * 생성자.
	 * @param activity : context
	 * @param view : 적용될 웹뷰
	 */
	public WebViewInterface(Activity activity, WebView view) {
		mAppView = view;
		mContext = activity;
	}
	/**
	 * 안드로이드 토스트를 출력한다. Time Long.
	 * @param message : 메시지
	 */
	@JavascriptInterface
	public void toastLong (String message) {
		Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();
	}
	/**
	 * 안드로이드 토스트를 출력한다. Time Short.
	 * @param message : 메시지
	 */
	@JavascriptInterface
	public void toastShort (String message) { // Show toast for a short time
		Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
	}
}

안드로이드 4.3.X 젤리빈 이상부터 "@JavascriptInterface" annotation을 붙이지 않을 경우

해당 메쏘드는 동작하지 않기 때문에 반드시 붙여줘야한다.(킷캣이상인가??;;)



그리고 Activity의 onCreate 혹은 Fragment의 onCreateView 에서 loadUrl이 불리기전에

WebView 객체의 addJavascriptInterface 메쏘드를 이용해 연결시켜 주면 바로 사용할 수 있다.

무지 간단하다!

public class MainActivity {

	private WebView mWebView = null;
	private WebViewInterface mWebViewInterface;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getWindow().requestFeature(Window.FEATURE_PROGRESS);
		setContentView(R.layout.activity_main);
		mWebView = (WebView) findViewById(R.id.webview); //웹뷰 객체
		mWebViewInterface = new WebViewInterface(MainActivity.this, mWebView); //JavascriptInterface 객체화
		mWebView.addJavascriptInterface(mWebViewInterface, "Android"); //웹뷰에 JavascriptInterface를 연결
	}
}

addJavascriptInterface를 보면 인터페이스 객체와, 웹에서 사용될 객체 명을 넣어준다.

위와 같이 연결을 하게 되면, 웹페이지에 window.Android 객체가 생성되고, WebViewInterface에 정의된

모든 메쏘드를 사용할 수 있게 된다.


웹페이지에 아래와 같이 입력하게 되면, 안드로이드 Toast를 통해 "JavascriptInterface Test"라는 문구가 보이게 된다.

window.Android.toastShort( "JavscriptInterface Test" );


이 댓글을 비밀 댓글로

[Web] window.print() 로 원하는 영역 인쇄하기.

Posted by Find my true self Fimtrus
2014.06.19 10:47 Programming/Web

window.print 함수를 사용하여 인쇄할 때의 영역은 

document.body 의 innerHTML이 잡히게 된다.

흔히 많이 사용하는 것중에 하나로,

원하는 영역의 html을 body에 넣어서 인쇄하는 방법이다.

하지만 single page 기반이나, jsp를 사용하지 않는 순수한 html의 경우

이방법을 사용하였을 때, 페이지가 거침없이 깨지는 경우가 대부분이다.

그래서 새창을 통해 인쇄하는 방법을 사용한다.


먼저 팝업 윈도우하나를 선언한다.

이때 새창이 생기게 되고, 정상적으로 열렸다면 popupWindow에는

새창에 대한 window 객체가 들어오게 된다. 팝업 차단으로 인해 열리지 않았을 경우

popupWindow 에는 undefined가 리턴되게 된다.



var popupWindow = window.open("", "_blank" );


대부분 개발자들은 jquery를 사용한다.(아마도??)

그 중에 jquery ui를 쓰는 사람도 적지 않다.

그러면 당연히 새창에서도 화면 구성에 필요한 js, css 등

plugin 들을 importing 해줘야 정상적으로 화면이 뜰 것이다.

그래서 아래의 코드로 헤더를 추가해준다.

- write 함수의 경우 document 객체에 직접 html을 추가해주는 역할을 한다.

- $('head')를 통해 헤더 객체를 얻고, html 함수를 사용하여 모든 헤더정보를 불러온다.



popupWindow.document.write( "<헤드태그>"); //head 제대로 쓰니까..티스토리 에러가...
popupWindow.document.write( $('head').html() );
popupWindow.document.write( '<헤드태그 닫기>' ); 


헤더를 추가한 후, 실제 표시될 컨텐츠를 추가해주면

새창에 원하는 컨텐츠가 추가되게 된다.


var $table = $("화면에 표시할 컨텐츠");

popupWindow.document.write( '<바디태그>' );
popupWindow.document.write( '
' ); popupWindow.document.write( $table.html() ); popupWindow.document.write( '
<바디태그 닫기>' );


컨텐츠 추가 완료 후 document를 close 시킨 후(반드시 close 함수를 호출해야한다)

새 창에서 print 함수를 호출해주면 인쇄창이 뜬다.


popupWindow.document.close();

//popupWindow 의 print 이다. 가끔 document.print 를 치시는 분들이..
popupWindow.print();


위의 코드들은 크롬 기반에서 테스트 하였으며, 익스플로러의 경우 정상적으로 동작하지 않을 수 있다.

이 댓글을 비밀 댓글로

My UserAgent 유저에이전트 알아내기

Posted by Find my true self Fimtrus
2014.05.08 14:18 Programming

한줄 끝!

window.navigator.userAgent



UserAgent is :


이 댓글을 비밀 댓글로

[HTML5] audio, video tag 지원 유무 확인

Posted by Find my true self Fimtrus
2014.04.28 18:17 Programming/Hybrid App

if ( document.createElement("video").canPlayType ) {console.log("true")} //지원
else { console.log( "false" );} //미지원
이 댓글을 비밀 댓글로

[Javascript] 정규식. 전화번호, 휴대폰 번호 추출. 검증

Posted by Find my true self Fimtrus
2013.12.20 10:20 Programming/Hybrid App

웹페이지를 제작시, 전화번호를 입력받는 화면이 있다.

아래와 같은 화면...

운전자 연락처(숫자만 입력) (필수입력)


파라미터, 화면 디스플레이시 하이픈(-)을 요구할 때,

정규식을 사용하면 편하다.


//가운데가 4자리
"01012345678".replace(/^(01[016789]{1}|02|0[3-9]{1}[0-9]{1})-?([0-9]{3,4})-?([0-9]{4})$/, "$1-$2-$3")
//가운데가 3자리
"0101234567".replace(/^(01[016789]{1}|02|0[3-9]{1}[0-9]{1})-?([0-9]{3,4})-?([0-9]{4})$/, "$1-$2-$3")

이렇게 정규식을 사용하면 가운데가 3자리든 4자리든 010-1234-5678, 010-123-4567 의 형태로 변경하여 사용할 수 있다.

* $1, $2, $3 : 괄호 순서대로 값들을 들고 올 수 있다.

* 시작부분 ^ : [] 안의 ^ 는 부정을 의미하지만, [] 밖의 ^는 시작을 의미한다.

* 끝 부붙 $ : 끝을 의미한다. 위의 정규식으로 보자면 끝에 4자리 라고 표현된다.

이 댓글을 비밀 댓글로

[Javascript] 아이폰에서 브라우저 백버튼 클릭시 새로고침 안되는 문제.

Posted by Find my true self Fimtrus
2013.12.18 15:32 Programming/Hybrid App

크롬기반 브라우저 및 안드로이드에서는 

브라우저 백버튼을 클릭하였을 때, 이전 페이지 정보를 refresh 한다.

하지만 IOS 사파리의 경우 그렇지 않다.

페이지에 대한 모든 정보를 사파리에서 저장하고 있기 때문이다.

흔히 Hybrid App, Single Page Web 을 구현하게 되면(일반 web도 마찬가지...),

간혹 로그인 체크라던가, 필요한 데이터를 받기 위해 document 의 ready에서 ajax를 통해 API들을 요청하게 된다.

 하지만 아이폰(사파리)에서 브라우저 백버튼을 눌렀을 때, ready 내의 fuction이 정상 동작하지 않게 된다.

이를 해결하기 위해선 

window 객체의 onpageshow라는 이벤트를 구현해야 아이폰에서 브라우저 백버튼을 눌렀을 때도, 원하는 결과를 얻을 수 있다.


//javascript 만을 이용한 방법
window.onpageshow =  function(event) {
			
			//back 이벤트 일 경우
	if ( event.persisted) {
				
		//====TODO : 
	}
			
}
//jQuery를 이용한 방법
$(window).bind("pageshow", function(event) {
	
	//back 이벤트 일 경우
	if ( event.originalEvent && event.originalEvent.persisted) {
		
		//TODO : ======
	}
	
});


jQuery를 이용할 때, event.originalEvent를 체크하는 이유는

브라우저에서 발생시킨 event 내에 event.originalEvent 가 없을 수 있기 때문에

존재하는지 체크를 먼저하게 된다.

그리고 persisted 를 통해, 이 이벤트가 백버튼(실제로는 continue의 느낌이 강함..)에 대한

이벤트인지 확인 할 수 있다(boolean 형태)


이 댓글을 비밀 댓글로

[HTML5] 안드로이드 및 아이폰에서 input file 사용시 카메라 호출하기.

Posted by Find my true self Fimtrus
2013.12.09 11:09 Programming/Hybrid App

오랜만에 글쓰네요.

요즘 하이브리드 웹을 많이 사용하시는데요.

네이티브 코딩없이 카메라 호출하는 법에 대해 쓰겠습니다.

안드로이드의 경우 2.2버전 이하는 카메라를 호출 할 수 없습니다.(4.0이상, 2.2 이하 에서만 확인해봤습니다.ㅠ 2.3단말기가 없어서)

아이폰은...IOS 6 이상에서만 확인해 봤습니다.(아마 5이하는 안될듯 하네요)

흔히 input file을 사용할때


<input type="file"/>


type만 file로 옵션을 주는데요.

이러면 lg단말기나, 베가 단말에서는 카메라 라는 항목이 보이지 않을 수 있습니다.(삼성은 카메라 라는 항목이 뜨더군요. 얼마나 뜯어 고친건지...;)

하지만 

<input type="file" accept="image/*;capture=camera"/>

또는

<input type="file" accept="image/*" capture="camera"> 

accept 에 파일 형식을 쓰고, capture 항목에 camera 라고 써주면 

직접 카메라가 호출되는 것을 볼 수 있습니다.

안드로이드의 경우 둘다 잘되는데요.

아이폰에서는 후자의 경우에만 카메라로 연결되더군요.(전자의 경우 카메라 및 비디오로 연결됩니다)

전 후자의 방법을 추천합니다.

많은 도움이 되셨길 바라면서...


이 댓글을 비밀 댓글로
    • 2017.04.04 13:31
    비밀댓글입니다
    • 지나가던협객
    • 2018.07.04 10:35
    이럴수가... 사랑합니다....

[jQuery] mobiscroll 에 타이틀 넣기.

Posted by Find my true self Fimtrus
2013.07.16 11:32 Programming/Hybrid App

센차에서는 datepicker를 자체 제공하지만, jQuery 에서는 따로 지원을 하지 않는다.

그래서 mobiscroll을 많이 사용한다.

jquery와 mobiscroll...

하지만 mobiscroll에는 치명적인 단점이 있는데, 

picker 타이틀을 지원하지 않는다.

그래서 core를 수정해 봤다.


mobiscroll.core.js

Line : 675

 html += '</div>' + (s.display != 'inline' ? '<div style="display : -webkit-box;" class="dwbc' + (s.button3 ? ' dwbc-p' : '') + '">'

            + '<span class="dwbw dwb-c"><span class="dwb dwb-e">' + s.cancelText + '</span></span>'

            + '<div style="-webkit-box-flex : 1; display: -webkit-box; -webkit-box-align : center; -webkit-box-pack : center; font-size : 1.4em; overflow: hidden;"><span>' + s.titleText + '</span></div>' 

            + (s.button3 ? '<span class="dwbw dwb-n"><span class="dwb dwb-e">' + s.button3Text + '</span></span>' : '')

            + '<span class="dwbw dwb-s"><span class="dwb dwb-e">' + s.setText + '</span></span>' 

             + '</div></div>' : '') + '</div></div></div>';


위의 코드를 merge 하고, mobiscroll 생성시 옵션으로 "titleText" 를 지정해주면 된다.


이 댓글을 비밀 댓글로

[Javascript] input file 이미지 미리보기, 썸네일 보기, Thumbnail

Posted by Find my true self Fimtrus
2013.07.10 14:11 Programming/Hybrid App
/**
  * 이미지 썸네일을 불러오는 function
  * @param html : input 필드의 dom을 인자로 받는다. 물론 타입은 file
  * @param $target : 불러온 이미지를 적용할 jquery 객체.
  **/
function getThumbnail(html, $target) {
	if (html.files && html.files[0]) {
		var reader = new FileReader();
		reader.onload = function (e) {
			$target.css('background-image', 'url(\"' + e.target.result + '\")');
		}
		reader.readAsDataURL(html.files[0]);
	}
}


냉무.
이 댓글을 비밀 댓글로
  1. 안녕하세요 혹시 위 소스 사용법좀 알수있을까요?
    아래와 같이 코딩해서 테스트해보니 html.files 에서 에러가 발생하더라구여
    dom 객체를 어떤식으로 넘겨 주어야 하나요?
    감사합니다. 좋은하루되세요.
    ===============================================
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    function getThumbnail(html, $target) {
    if (html.files && html.files[0]) {

    var reader = new FileReader();
    reader.onload = function (e) {
    $target.css('background-image', 'url(\"' + e.target.result + '\")');
    }
    reader.readAsDataURL(html.files[0]);
    }
    }
    function filechange(){
    var $target = $("#test");
    var html = document.getElementById("file1");
    getThumbnail(html,$target);

    }
    </script>
    <div id="test"></div>
    <input id="file1" type="file" onchange="javascript:filechange();">
    • 제가 이제 봤네요...한동안 너무 바쁘게 지내서 블로그를 돌볼 시간이 없었어요.

      해결하셨다고 생각하지만 답변드릴께요.

      getThumbnail 이라는 function은 두개의 인자를 받습니다.

      첫번째는 input tag의 input document 객체, 즉 document.querySelector('input') 하였을때 나오는 객체를 말합니다.
      file dom을 말하는거죠..
      두번째인자인 target은 jquery 객체를 말하는건데....
      소스 보시면 알겠지만 읽어 들인 파일의 thumbnail을 표시할 객체입니다.
      img tag일수도 있고, background를 주기 위한 division일 수도 있습니다.
      저는 division에 background-image로 적용하였습니다.

      결론을 말씀드리면, html은 input tag의 dom 객체를 넘기면 됩니다.

      더 궁금하신게 있으시다면 답변바랍니다.

[Javascript] // 주석제거 정규식.

Posted by Find my true self Fimtrus
2013.06.19 17:58 Programming/Hybrid App

언어마다 정규식 표현방식이 다르다.

특히 Javascript의 경우, RegExp라는 function을 사용하여 만든다. ( 물론 사용하지 않고도 만들 수 있다. 하지만 Syntax Error 를 경험하게 될것이다.)

기본적인 문법은 다음과 같다.

/**
 * 1.권장하는 방법..
 **/
var regExp = new RegExp(pattern,modifiers);

//또는.
/**
 * 2.같은 정규식을 만들더라도..Syntax Error가 많이 발생하는 것을 경험했다.
 **/
var regExp = /pattern/modifiers;


1번방법을 이용하여, 주석을 제거하는 정규식을 만들어 보겠다.("//" 에 해당하는 주석만 삭제된다.)



/**
 * "//"로 시작하고, "\n"(줄바꿈)으로 끝나는 글자(문장?)를 찾는다. 
 * modifier로 gm 을 지정. g 는 global(전체검색), m은 multiline(여러줄 찾기)
 */
var regExp = new RegExp("//.*\n", "gm");
/**
 * 그리고 제거하고자 하는 String value의 replace를 사용하면된다.
 * trim은 양 끝의 공백, 줄바꿈 등을 제거하기 위해 사용.
 * str은 임의의 문자.
 */
str = str.replace(regExp, "").trim()

위의 코드대로 검색하면, "//"에 해당하는 주석은 모두 제거된다.

"/* */"도 제거하는 코드는 다음에....업데이트.,,

이 댓글을 비밀 댓글로