Android/App개발2010. 7. 6. 22:17

원문 : http://developer.android.com/resources/articles/using-webviews.html

 

링크 : http://silence2.tistory.com/entry/Using-WebViews


번역 : 이상훈 (calm1979@gmail.com)

2010년 6월 30일

 

WebViewDemo는 어플리케이션에 웹 컨텐츠를 붙일 수 있는 방법을 보여주는 간단한 어플리케이션이다. 이것은 apps-for-android 프로젝트에서 찾을 수 있다. 이 어플리케이션은 액티비티 내에 WebView를 붙일 수 있는 방법과 어플리케이션과 웹 컨텐츠 사이에 서로 통신할 수 있는 방법을 보여준다.

 

WebView는 브라우저와 동일한 렌더링 엔진과 자바 스크립트 엔진을 사용하지만, 당신의 어플리케이션의 제어하에 동작한다. WebView는 전체 화면으로 동작할 수도 있고, 다른 View들과 섞여서 동작할 수도 있다. WebView의 컨텐츠는 어디서든지 올 수 있다. WebView는 웹에서 컨텐츠를 다운로드 하거나, 당신의 assets 디렉토리 내에 저장된 로컬 파일에서 컨텐츠를 얻을 수도 있다. 심지어 어플리케이션 코드 상에서 동적으로 생성된 컨텐츠를 사용할 수도 있다. 이 예제에서는 demo.html 이라는 로컬 파일을 표시한다.

 

이 어플리케이션은 많은 것을 하지는 않는다: 당신이 안드로이드를 클릭하면 팔을 들어줄 뿐이다.


물론 이것은 간단한 자바 스크립트로 처리할 수 있다. 하지만, WebViewDemo는 WebView의 매우 강력한 두 가지 기능을 알려주기 위해 약간 복잡한 방법을 사용했다.

 

첫 째, WebView 내에 돌고 있는 자바 스크립트에서 액티비티의 코드를 호출할 수 있다. 당신은 이런 것을 자바 스크립트가 새로운 액티비티를 시작하는 액션을 발생시키거나, 데이터베이스나 ContentProvider에서 데이터를 얻어내는 경우 등에 사용할 수 있다. 이를 위한 API는 매우 간단하다: WebView의 addJavascriptInterface()만 호출하면 된다. 자바 스크립트에 노출시킬 메소드를 가진 객체와 자바 스크립트에서 호출할 때 사용할 이름을 넘겨주면 된다. 정확한 문법은 WebViewDemo.java에서 확인할 수 있다. 여기에서는 자바 스크립트에서 "window.demo"로 호출해서 사용될 DemoJavascriptInterface 객체를 만들었다.

 

둘 째, 액티비티에서 자바 스크립트 메소드를 호출할 수 있다. 이것은 모두 loadUrl 메소드를 통해 적절한 자바 스크립트를 호출 해야한다.

1 mWebView.loadUrl("javascript:wave()");


WebViewDemo 는 두 가지 기술을 사용하고 있다: 당신이 안드로이드를 클릭하면, 액티비티로 호출을 하고 다시 자바 스크립트를 호출한다. WebViews는 매우 강력하고, 어플리케이션을 만드는데 충분히 도움이될 만한 툴이다. - 특히 많은 양의 HTML 컨텐츠를 가지고 있는 경우에 도움이 될 것 이다. 마침, 우리는 우리가 만들고 있는 어플리케이션의 일부에서 정확히 이 방식을 사용했었다.


Posted by 삼스
Android/정리2010. 5. 31. 14:39

Gestures

터치스크린은 모바일장치에서 애플리케이션과 연동하기 위한 대단한 방법이 있다. 터치스크린을 통해 사용자는 tab, drag, fling또는 slide 통해 애플리케이션을 빠르게 액션을 수행할 있다. 개발자를 위해서 안드로이는 framework swite같은 간단한 액션을 인식할 있는 방법을 제공한다. 하지만 복잡한 제스쳐는 다루기 어렵다 간혹 개발자는 이런 복잡한 처리를 위해 추가적으로 많은 코딩을 해야 수도 있다.

Android 1.6(Donut)에서부터 새로운 제스쳐API 제공한다. Android.gesture 패키지가 제공되며, 인식가능한 제스쳐들을 store, load, draw할수 있다. 문서는 패키지의 사용방법을 설명한다. 시작하기 전에 예제를 먼저 다운받아라(download the source code of the examples).

Creating a gestures library

Android 1.6이후 버전에는 Gestures Builder라는 어플이 설치된다. 어플로 미리정의된 당신만의 제스쳐를 만들 있다. 예제가 함께 제공되는데 제스쳐셋을 만들 있다. 아래 그림은 가지 제스쳐를 추가한 이후의 화면을 보여준다.

위에서 보는바와 같이 제스쳐는 연관된 이름을 갖는다. 이름은 앱에서 각각 제스쳐를 구분하는데 사용되므로 아주 중요하다. 이름이 유일할 필요는 없다. 동일명하에 여러가지 제스쳐가 사용될 있다. 제스쳐빌더를 이용하여 제스쳐를 추가하거나 수정할 있으며 SD Card gestures폴더에 저장된다. 파일에는 제스쳐에 대한 정보가 저장되어 있으며 앱에서 /res/raw폴더에 위치시켜서 사용할 있다.

Loading the gestures library

이제 미리정의된 제스쳐를 갖게 되었다. 이제 에서 반드시 로드하여 사용해야 한다. 몇가지 방법이 있으며 가장 간단한 방법은 GestureLibraries 클래스를 사용하는 방법이다.

mLibrary = GestureLibraries.fromRawResource(this, R.raw.spells);
if (!mLibrary.load()) {
    finish
();
}

예에서, /res/raw/spells파일로부터 제스쳐가 로드되었다. SD card같은 다른 소스로부터 로드할 수도 있으며 앱에서 파일을 저장할 수도 있으며 변경할수 없더록 읽기전용으로 로드할수도 있다. 아래는 하나의 라이브러리의 구조를 다이어그램으로 보여준다.

Recognizing gestures

To start recognizing gestures in your application, all you have to do is add a GestureOverlayView to your XML layout:

앱에서 제스쳐를 인식하기 위해서 해야 하는 일은 XML layout GestureOverlayView 추가하는 뿐이다.

<android.gesture.GestureOverlayView
   
android:id="@+id/gestures"
   
android:layout_width="fill_parent"
   
android:layout_height="0dip"
   
android:layout_weight="1.0" />

GestureOverlayView 일반적인 android.widget package 일부가 아니란걸 알아야 한다. 그러므로 full name 사용해야 한다. Gesture overlay 사용자가 제스쳐를 그리는 영역에서 동작한다. 몇가지 visual 속성들을 변경할 있다. 색상이나 stroke 두께, 그리고 액션이 진행동안의 사용되는 다양한 listener등을 변경할 있다. 가장 일반적으로 많이 사용되는 listener GestureOverlayView.OnGesturePerformedListener이다. gesture 그려질때마다 호출된다.

GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
gestures
.addOnGesturePerformedListener(this);

Listener 호출될 GestureLibrary 제스쳐를 인식하기 위한 질의를 보낼 있다. 리턴값에서 예측된값들의 리스트와 score 얻게 될것이다. 리스트는 core 역순으로 정렬되어 있다. 가장 고득점에 해당하는 gesture 사용자가 그리길 원하는 것일것이다. 아래 코드는 첫번째 예측값의 이름을 검색하는 방법을 보여준다.

public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
   
ArrayList<prediction> predictions = mLibrary.recognize(gesture);

   
// We want at least one prediction
   
if (predictions.size() > 0) {
       
Prediction prediction = predictions.get(0);
       
// We want at least some confidence in the result
       
if (prediction.score > 1.0) {
           
// Show the spell
           
Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show();
       
}
   
}
}

예제에서는 예측값이 1.0이상인경우만 고려하였다. 1.0이하는 낮은 일치율을 의미하며 코드가 앱에서 미리정의된 제스쳐를 인식하는 코드의 전부이다.

 

Gestures overlay

예제코드에서 GestureOverlayView LinearLayout 안에 들어간 일반적인 뷰로 사용되었다. 하지만 이름에서 느껴지는 처럼, 다른뷰들의 최상위에 overlay 사용될 수도 있다. 이는 게임이나 앱의 어느곳에서든 사용될 있는 유용한 방법이다. 두번째 데모인 GetstureListDemo에서는 Contacts list 최상위에 overlay 생성할것이다. 그리고 Getsture builder 새로운 제스쳐를 정의할 것이다.

And here is what the XML layout looks like:

<android.gesture.GestureOverlayView
   
xmlns:android="http://schemas.android.com/apk/res/android"
   
android:id="@+id/gestures"
   
android:layout_width="fill_parent"
   
android:layout_height="fill_parent"
   
   
android:gestureStrokeType="multiple"
   
android:eventsInterceptionEnabled="true"
   
android:orientation="vertical">

   
<ListView
       
android:id="@android:id/list"  
       
android:layout_width="fill_parent"
       
android:layout_height="fill_parent"  />

</android.gesture.GestureOverlayView>

앱에서 일반적인 ListView 최상위에 gesture overlay 있다. 그리고 overlay에는 전에 본적없는 속성들이 몇가지 있다.

·         gestureStrokeType: single stroke 사용할지 또는 multiple stroke 사용할 지정한다.

·         eventsInterceptionEnabled: true 설정하면 gesture 처리할 있는 child view 있는 경우 child 이벤트가 전달되도록 한다. Scroll 가능한 view 있는경우 유용하며 scroll이벤트와 충돌이 발생하지 않는다.

·         orientation: scroll orientation 지정한다. 여기서는 vertical 하였으며 이것은 가로제스쳐인 action_delete 바로 제스쳐로 인식될수 있음을 의미한다. 세로 제스쳐의 경우 반드시 가로제스쳐를 하나이상 가져야만 인식이 가능하게 된다. 다른 의미로 세로로 그려진 라인은 스크롤과 오인될 있으므로 이런 옵션이 필요하게 된다.

·          

Gesture library load하고 setup하는것과 overlay 설정하는 것은 위에서 설명한 코드와 동일하다. 오직 한가지 다른 점은 이제 예측의 이름값을 이용하여 무엇을 했는지 알아낸다는 것이다.

public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
   
ArrayList<Prediction> predictions = mLibrary.recognize(gesture);
   
if (predictions.size() > 0 && predictions.get(0).score > 1.0) {
       
String action = predictions.get(0).name;
       
if ("action_add".equals(action)) {
           
Toast.makeText(this, "Adding a contact", Toast.LENGTH_SHORT).show();
       
} else if ("action_delete".equals(action)) {
           
Toast.makeText(this, "Removing a contact", Toast.LENGTH_SHORT).show();
       
} else if ("action_refresh".equals(action)) {
           
Toast.makeText(this, "Reloading contacts", Toast.LENGTH_SHORT).show();
       
}
   
}
}

사용자는 이제 리스트의 위에 스크롤과 충돌없이 제스쳐의 입력이 가능해진다.

Overlay 세로스크로크만 입력했을 경우 반투명한 컬러로 표시하여 유효하지 않은 제스쳐임을 표시한다.

It's your turn

당신의 앱에 제스쳐를 추가하는 것은 쉬우면서도 가치있는 추가기능이 될 수 있다. 현재는 아주 쉬운 입력만 가능하나 활용하기에 따라 여러가지 모양을 인식하게 할수도 있다.. 알아서 잘 활용하길..

 

Posted by 삼스
Android/App개발2010. 5. 24. 21:20
java.util.Timer와 java.util.TimerTask를 이용한 타이머스레드를 사용할 때 

import java.util.Timer;
import java.util.TimerTask;

// 1. Timer생성
private Timer mTimer = new Timer();

// 2. TimerTask연결 하여 기동
//     INTERVAL시간마다 run()함수가 수행된다.
mTimer.schedule(
new TimerTask(){
public void run() {
mHandler.post(new Runnable(){
public void run(){
Log.d(TAG, "running Timer...");
}
});
}        
   }, INTERVAL,INTERVAL);

// 3. Timer의 제거
mTimer.cancel();

주의>>
** 생명주기의 관리에 주의해야 한다.
  BACK시에는 cancel후 재진입시 schedule을 호출시 정상동작하나..
  HOME시에는 cancel후 재진입시 schedule을 호출하면 IllegalStateException이 발생하면서 타이머가 동작하지 않는다.
  따라서 Timer는 이런식으로 사용하는것을 지양해야 할듯!!!!
  원인은 찾지 못함.

Posted by 삼스