'Android'에 해당되는 글 15건

  1. 2010.04.03 [android] MapView와 ItemizedOverlay 사용 시 NullPointerException이 발생하는 경우 (5)
  2. 2009.12.08 [Android] SDK Build시 SDCard 인식 오류 문제 (1)
  3. 2009.06.12 [android] Android Virutal Device 생성하기
  4. 2009.06.11 [android] Wizard에서 Android XML File 생성 시 오류 발생 문제
  5. 2009.06.08 [android] Application, Activity 그리고 Task (2)
  6. 2009.06.03 [android] SDK v1.5 r2 릴리즈
  7. 2009.05.28 [android] Android Dev Phone Firmware 복구 하기 (2)
  8. 2009.05.07 [android] Linux에서 Android 단말 USB 인식하기
  9. 2009.05.07 [android] Android Dev Phone Firmware Upgrade 하기 (2)
  10. 2009.04.30 [android] 에뮬레이터에서 외장 메모리 사용하기
2010.04.03 19:29

[android] MapView와 ItemizedOverlay 사용 시 NullPointerException이 발생하는 경우

Android SDK에는 Open Source를 이용한 API와 함께 Google에서 제공하는 서비스를 이용 할 수 있는 별도의 API가 포함된 SDK가 있다. 이를 이용한 것 중 대표적인 것이 바로 MapView일 것이다.

MapView는 사용자가 만드는 Android Activity에 Google Map을 보여주는 View 클래스이다. 이를 이용하면 Google Map 서버에서 지도와 함께 다양한 정보를 얻을 수 있으므로 꽤나 유용하다. 물론 Google이 직접 만든 Google Map App과는 차이가 있지만 거의 비슷하게나마 사용 할 수 있다.

Google Map App에서 검색을 할 경우 화면에 보여지는 것은 ItemizedOverlay라는 것을 이용한다. 이는 지도 화면 위에 아이템을 투영하여 보여주는 것으로 검색 좌표 결과를 지도와 함께 표시해 줄 때 사용하곤 한다. ItemizedOverlay를 사용 할 때 간혹 지도 화면을 Touch하면 바로 아래와 같은 NullPointerException이 발생하는 경우가 있다.

WARN/dalvikvm(661): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
ERROR/AndroidRuntime(661): Uncaught handler: thread main exiting due to uncaught exception
ERROR/AndroidRuntime(661): java.lang.NullPointerException
ERROR/AndroidRuntime(661):     at com.google.android.maps.ItemizedOverlay.getItemsAtLocation(ItemizedOverlay.java:617)
ERROR/AndroidRuntime(661):     at com.google.android.maps.ItemizedOverlay.getItemAtLocation(ItemizedOverlay.java:586)
ERROR/AndroidRuntime(661):     at com.google.android.maps.ItemizedOverlay.handleMotionEvent(ItemizedOverlay.java:498)
ERROR/AndroidRuntime(661):     at com.google.android.maps.ItemizedOverlay.onTouchEvent(ItemizedOverlay.java:572)
ERROR/AndroidRuntime(661):     at com.google.android.maps.OverlayBundle.onTouchEvent(OverlayBundle.java:63)
ERROR/AndroidRuntime(661):     at com.google.android.maps.MapView.onTouchEvent(MapView.java:625)
ERROR/AndroidRuntime(661):     at android.view.View.dispatchTouchEvent(View.java:3709)
ERROR/AndroidRuntime(661):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:851)
ERROR/AndroidRuntime(661):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:821)
ERROR/AndroidRuntime(661):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:821)
ERROR/AndroidRuntime(661):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:821)
ERROR/AndroidRuntime(661):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:821)

이 Exception은 MapView에 등록한 ItemizedOverlay에 OverlayItem이 하나도 없는 경우 발생하는 경우이다.  Open source가 아닌 Google API에서 발생하는 것으로 명확한 오류는 잘 모르지만 짐작컨데 다음과 같은 원인이 있는 것 같아 다음과 같은 상황을 생각해 볼 수 있다.

1. 화면을 Touch 할 경우만 발생하므로 Touch에 관련된 것이다.
2. ItemizedOverlay를 사용할 경우만 발생하므로 ItemizedOverlay에 대한 정보가 더 필요할 것이다.

즉,  ItemizedOverlay를 좀 더 살펴 볼 필요가 있다. ItemizedOverlay는 MapView에 추가하여 MapView 보다 먼저 Touch 이벤트를 받아 처리하며 일반적인 경우는 ItemizedOverlay에 등록된 Item이 선택이 되었는지 확인하고 선택된 Item의 정보를 callback한다. 이런 점을 미루어 볼 때 Empty item에 대한 처리가 되어 있지 않다는 것을 알 수 있었다.

이와 관련된 정보를 찾다보니 이런 오류가 발생하는 사람들이 꽤 있었는데 ItemizedOverlay를 상속받은 후 Constructor에서 무조건 populate()를 한 번 호출하는 방법으로 오류를 피할 수 있다고 한다.

참고 : http://code.google.com/p/android/issues/detail?id=2035

Google에서 제공하는 MapView 예제에는 다음과 같이 ItemizedOverlay에 OverlayItem을 추가할 때 마다 populate()를 호출하도록 되어 있다.

public void addOverlay(OverlayItem overlay) {

    mOverlays
.add(overlay);

    populate
();

}

Java Document에는 다음과 같이 populate() method에 대한 설명이 되어 있다.

void com.google.android.maps.ItemizedOverlay.populate()

protected final void populate()
Utility method to perform all processing on a new ItemizedOverlay. Subclasses provide Items through the createItem(int) method. The subclass should call this as soon as it has data, before anything else gets called.

번역해 보면 이런 내용이다.

새로운 ItemziedOverlay에 대한 모든 처리를 수행하는 유틸리티 메소드. 상속받은 클래스는 Items들을 createItem(int) 메소드를 통해 제공하다. 이 클래스에서는 데이터를 갖은 후 어떤 것을 호출하기 전에 가능한 한 빨리 이 메소드를 호출 해야만 한다.

ItemizedOverlay에 OverlayItem을 등록하거나 변경되면 그 정보를 ItemizedOverlay가 처리하도록 populate()를 호출해야 하는 것인데, 만약 Overlay 생성 후 Item을 하나도 추가하지 않으면 populate()가 아예 호출되지 않게 된다. 그렇기 때문에 Touch 시 잘못된 정보로 인한 오류가 발생한다.

어찌보면 ItemizedOverlay의 구현에 문제가 있는 것일 수도 있지만 그 내부는 알 수 없으니 이를 회피하기 위해 Constructor에서 아예 한 번은 populate()를 호출하는 방법을 이용해 이 오류를 회피하면 Touch 시에도 오류가 발생하지 않게 된다.
Trackback 0 Comment 5
2009.12.08 15:41

[Android] SDK Build시 SDCard 인식 오류 문제

Custom SDK로 Build한 경우 SDcard를 지정했음에도 불구하고 SDCard가 인식되지 않는 경우가 있는데 target의 경우 sdcard의 삽입이나 분리를 통해 mount를 인식하게 되어 있다. SDK는 해당 이미지를 로딩하도록 되어 있는데 초기에 mount를 하지 않아 sdcard의 인식이 되지 않는 문제가 있다. (cupcake 기준) 이럴 경우 Emulator를 실행 후 ADB shell에서 다음과 같이 sdcard를 mount 해 주면 된다.

1. Root 권한으로 adb 실행

> cd android-sdk-windows-1.5_r2\tools
> adb root

2. Shell 진입

> adb shell

3. Mount 정보 확인

# mount
mount
rootfs / rootfs ro 0 0
tmpfs /dev tmpfs rw,mode=755 0 0
devpts /dev/pts devpts rw,mode=600 0 0
proc /proc proc rw 0 0
sysfs /sys sysfs rw 0 0
tmpfs /sqlite_stmt_journals tmpfs rw,size=4096k 0 0
/dev/block/mtdblock0 /system yaffs2 ro 0 0
/dev/block/mtdblock1 /data yaffs2 rw,nosuid,nodev 0 0
/dev/block/mtdblock2 /cache yaffs2 rw,nosuid,nodev 0 0

4. SDcard Mount

#mount -rw -t vfat /dev/block//vold/179:0 /sdcard

마운트가 되었는지 다시 확인 해 보면 다음과 같이 나온다

# mount
mount
rootfs / rootfs ro 0 0
tmpfs /dev tmpfs rw,mode=755 0 0
devpts /dev/pts devpts rw,mode=600 0 0
proc /proc proc rw 0 0
sysfs /sys sysfs rw 0 0
tmpfs /sqlite_stmt_journals tmpfs rw,size=4096k 0 0
/dev/block/mtdblock0 /system yaffs2 ro 0 0
/dev/block/mtdblock1 /data yaffs2 rw,nosuid,nodev 0 0
/dev/block/mtdblock2 /cache yaffs2 rw,nosuid,nodev 0 0
/dev/block//vold/179:0 /sdcard vfat rw,fmask=0000,dmask=0000,allow_utime=0022,co
depage=cp437,iocharset=iso8859-1 0 0

근데 이렇게 할 경우 emulator를 실행할 때 마다 이와 같은 작업을 해야하므로 여간 귀찮은 일이 아닐 수 없다. 그럴 경우 아래와 같이 core의 makefile을 수정하는 방법을 이용한다.

$ANDROID_ROOT/build/core/main.mk : 214 line
# Install an apns-conf.xml file if one's not already being installed.
ifeq (,$(filter %:system/etc/apns-conf.xml, $(PRODUCT_COPY_FILES)))
  PRODUCT_COPY_FILES += \
        development/data/etc/apns-conf_sdk.xml:system/etc/apns-conf.xml
  ifeq ($(filter eng tests,$(TARGET_BUILD_VARIANT)),)
    $(warning implicitly installing apns-conf_sdk.xml)
  endif
endif

이 코드 다음에 아래와 같이 vold.conf에 대한 정보를 추가한다.

ifeq (,$(filter %:system/etc/vold.conf:, $(PRODUCT_COPY_FILES)))
  PRODUCT_COPY_FILES += \
        development/data/etc/vold.conf:system/etc/vold.conf
  ifeq ($(filter eng tests,$(TARGET_BUILD_VARIANT)),)
    $(warning implicitly installing vold.conf)
  endif
endif

생성된 system.img를 직접 수정하여 vold.conf를 넣을 수도 있을 수도 있겠지만 system.img 파일은 yaffs2라는 format으로 되어 있다. yaffs2 는 android에서만 이용하는 것이므로 NAND Boot용으로 만들어진 Format이라고 한다. 따라서, 직접 수정은 어렵고 위와 같이 makefile을 수정하는 편이 더 편하다.
Trackback 1 Comment 1
2009.06.12 17:01

[android] Android Virutal Device 생성하기

Android SDK가 version 1.5 로 업데이트 되면서 AVD (Android Virtual Device)를 생성한 글을 포스팅 (Android SDK 1.5 업데이트 참고) 했었다. 이번에 SDK 1.5 r2로 버젼이 올라가면서 생긴 것인지는 잘 모르겠지만 AVD를 보다 손쉽게 생성하는 방벙이 있어서 몇 자 적어 본다.

Eclipse에 Android Plug-In이 설치되면 Tool bar가 같이 생성된다. 이 Toolbar에 AVD를 관리하는 AVD Manager가 있다.


이를 이용하면 Console에서 Command Line으로 생성하는 것 보다 더 간편하게 AVD를 생성할 수 있다. 물론, Console에서는 여러가지 옵션을 적용 할 수 있지만 일반적 사용자들은 이 방법이 더 효과적이다.



그리고, 현재 생성 할 AVD에 SDCard를 포함하고 싶으면 SDCard 이미지에 대한 전체 경로를 입력하면 된다. (SDCard 이미지 생성은 이전 글 Android 에뮬레이터에서 외장메모리 참조) 이제, Create AVD를 클릭하면 다음과 같이 정상적으로 생성이 되었다고 나타난다.



이제 다음과 같이 두 개의 AVD가 생성되었음을 볼 수 있다.


Trackback 0 Comment 0
2009.06.11 18:08

[android] Wizard에서 Android XML File 생성 시 오류 발생 문제

이번 Android SDK가 v1.5 r2로 업데이트 된 후 이전에 안보이던 문제가 생겼다. 프로젝트에서 Android XML 파일을 생성하기 위해 Wizard를 실행 할 경우 다음과 같은 메시지와 함께 생성이 되지 않는다.

The sleected wizard could not be started. ..
Reason:
Plug-in com.android.ide.eclipse.adt was unable to load class
com.android.ide.eclipse.wizards.NewXmlFileWizard




Eclipse 플러그인과 관련된 버그 같은데 현재 사용하고 있는 Eclipse Europa 버젼이 문제인지는 확인 해 봐야겠다.

급한대로 일반 파일을 만든다음 XML로 확장자를 변경해서 사용 하라는 사람들도 있는데 꽤나 불편하다. 대신 Android ToolBar의 단축 아이콘을 이용하면 오류가 발생하지 않으므로 이를 이용하면 된다.

Java Perspective에 Android Eclipse Plugin을 설치하면 아래와 같이 Android Category 가 설치 된 것을 볼 수 있으며, 이 중 빨간색으로 표시된 아이콘을 선택하면 Android XML File을 바로 생성 할 수 있다.




Trackback 0 Comment 0
2009.06.08 11:20

[android] Application, Activity 그리고 Task

안드로이드 플랫폼에서는 Application 이외에 Activity도 있고 Task 라는 개념도 있다. 이런 개념은 일반적인 OS의 것과 사뭇 달라 약간 혼란스러운 면이 있다. 일단 이런 용어들은 안드로이드에서만 사용하는 새로운 개념으로 생각하고 전반적인 모습을 살펴보도록 하자.


1. Android Applicatin Basic Concept
안드로이드 Application의 기본적인 컨셉은 Application, Activity, Activity Stack 그리고 Task의 4가지이다. 각각의 컨셉은 다음과 같다.


a. Application
Application은 하나 이상의 Activity와 Resource 등이 하나로 묶여 있는 꾸러미 (Bundle)를 말한다. Application은 APK 형식의 파일로 되어 있으며 단말에 복사 설치 할 수 있다.


b. Activity
Activity는 Android Application의 기본 구성 단위로 특정 동작의 수행을 나타내는 객체이다. 하나 이상의 Activity로 구성될 수 있으며 다른 Activity를 호출하거나 다른 Activity에게 노출하여 다양한 조합으로 Application을 구성 할 수 있다.

Activity는 보여주기, 편집하기, 전화걸기, 사진찍기, 검색하기, 데이터 보내기, 음성인식 시작하기 혹은 특정한 타입의 사용자 액션에 대한 동작과 같이 한가지 혹은 그 영역이 잘 정의된 형태의 Visual User Interface로 디자인 되었다.

당연한 이야기지만, 화면에 어떤 것을 표현하는 Application이라면 적어도 display에 대응되는 Activity를 적어도 하나 이상 가지고 있어야 한다.

Android 단말을 이용할 때 사용자들 User Interface를 통해 Activity들을 하나씩 시작하며 이동하게 되고, 내제된 동작에 대해 전혀 생각하지 않게 되므로 이런 경험(User Experience)들은 Activity에서 Activity로 넘어가든 Task에서 Task로 넘어가든 일관된 모습을 가져야 한다.

Activity들은 특정 타입의 Content (데이터)를 처리하며 사용자 행동을 입력 받도록 되어 있다. 일반적으로, 각각의 Activity들은 Life Cycle을 가지게 되는데 이는 다른 같은 Application이나 Task 내에서도 독립적이다. - 각 Activity들은 독립적으로 시작되고, 필요에 따라 사용자 혹은 시스템에 의해 시작, 실행, 중지, 재게, 정지 그리고 재시작 한다. Activity들은 독립적이기 때문에 다양한 방법으로 재사용 될 수도 있고 다른 Activity들로 대치될 수도 있다.

이런 Activity는 Application Component 4가지 (Activity, Services, Broadcase Receiver, Content Provider) 중 가장 중요한 부분이다. Appclication Component 에 대한 자세한 내용은 Application Component을 참고하기 바란다.


c. Activity Stack

사용자가 Activity에서 Activity로 넘어감(Application이 넘어 갈 수도 있음)에 따라 Android 시스템은 사용자가 접했던 Activity들을 순차적으로 기록 유지하고 있게 된다. 이것이 Back Stack으로 알고 있는 Activity Stack이다. 일반적으로 사용자가 새로운 Activity를 생성할 때, Activity Stack에 추가되므로 BACK 키를 누르면 스택에 있는 이전 Activity를 보여준다. 그러나, 사용자가 마지막으로 HOME으로 온 경우는 BACK 키를 눌러도 되돌가 갈 수 없다.

현재 Stack에 Activity를 추가하는 것은 activity가 새로운 task(Home으로 돌아가는 것 없이 task가 시작되었던 것 만큼 오래 걸림)로 시작하는 것과는 상관이 없으므로 뒤로 돌아가는 것은 이전 task에서 있는 activity들로 돌아가는 것을 허락하는 것이다.

사용자는 Application Launcher나 short-cut 아니면 "Recent Task" 스크린에서 Root Activity를 선택함으로써 가장 최근의 Home 보다 더 빨리 task를 가질 수 있다.

Activity만이 Activity Stack에 더해 질 수 있으므로 view, window, menu 그리고 dialog 등은 안된다. 그러므로, 사용자가 스크린 A를 가지고 있고 다음 이어진 순서로 스크린 B로 갔다가 BACK 키를 눌러 스크린 A로 돌아오기를 원한다면, nativigation을 설계 할 때 스크린 A는 Activity로 구현되어야 하는 것이다. 하나의 예외가 있다면 Application이 manage navigation 자체를 관리하는 경우이다.



d. Task

Task는 사용자가 특정 목적을 이루기 위해 따르게 되는 연속된 Activity들로 Activity가 어떤 Application에 속해 있는지는 상관 하지 않는다.

새로운 Task에 대해 명확하게 정해지기 전까지 사용자가 시작하는 모든 Activity들은 현재 Task의 일부로 간주된다. 이런 Activity들은 다른 Application에도 있을 수 있다는 것이 주목할 만한 점이다. Contact에서 시작한 task가 E-mail address를 선택해서 email activity를 유지하고, file을 첨부해서 picture gallery에서 이미지를 선택 할 수 있는 것이다. Contacts, email 그리고 picture gallery는 모두 별도의 application이다.

Task를 시작하는 Activity는 Root Activity에서 호출된다. 이는 반드시 그런 것은 아니지만 Application Launcher, Home Screen의 Shourtcut 아니면 "Recent tasks" (HOME키를 오래 누르고 있으면 나옴)에서 빈번히 호출된다. 사용자들은 task를 처음 시작했을 때외 마찬가지로 root activity에 대한 icon을 선택하므로써 task로 되돌아 갈 수 있다. 한 번 task에 속해지면, BACK 키를 눌렀을 때 task의 이전 activity로 되돌아가게 된다. Activity Stack은 하나 혹은 그 이상의 Task로 만들어져 있다.

Task에 대한 몇 가지 예를 들어 보자:

* 첨부 데이터와 함께 문제 메시지를 보낸다
* 유튜브 비디오를 보고 email로 다른 사람들과 공유한다.


Interruping the Task
task의 매우 중요한 속성은 사용자가 다른 task를 수행하기 위해 현재 실행 중인 task를 interrupt를 할 수 있으며, 떠나 왔던 원래 task를 완료하기 위해 다시 되돌아 갈 수 있다는 것이다. 이것은 사용자들이 여러개의 task를 동시에 실행 할 수 있으며 task 간 전환도 할 수 있게 하는 것이다. 다른 task로 넘어가는 방법이 두 가지가 있는데, 사용자가는 interrupt 전의 위치로 되돌아 올 수 있어야 한다.

* 사용자는 notification에 의해 interrupt 된다 - notification은 나타나면 사용자는 그에 맞는 동작을 하길 원한다
* 사용자가 다른 task를 수행 하길 원한다 - 사용자는 HOME 키를 눌러 Home으로 되돌아가 Applicaiton을 실행한다.


물론 예외적인 규칙이 있다. 위에 언급된 두 가지 방법 이외, Task를 시작하는 제 3의 방법이 있는데, Activity를 시작 할 때 자기 자신을 Task로 시작하게 하는 경우다. Maps와 Browser가  이런 동작을 하는 Application이다.

예를 들어, email에서 address를 선택하는 것은 Maps activity를 새로운 task로 시작하는 것과 같고, email에서 link를 선택하는 것은 Browser Activity를 새로운 task로 시작하는 것과 같다. 이런 상태에 BACK 키를 누른 경우 Home에서 시작한 것이 아니므로 다른 Task(email)에 있는 이전 Activity로 되돌아 가게 된다.




2. Activity & Task

Activity와 Task는 기존의 일반적인 OS의 것과는 꽤 많은 차이가 있어 위의 설명으로는 이해가 어려울 수 있다. 다음의 예를 들어 Activity와 Task의 관계에 대해 명확히 알아보자

a. Home Key와 Back의 차이

Application을 실행하면 해당 Application의 Root Activity가 먼저 실행 된다. 그 상태에서 BACK 키나 HOME 와 같은 Activity 전환에 대한 키를 누를 수가 있다. Android 에서는 이런 동작에 따라 Activity와 Task에 대한 동작이 달라진다.

1) Home Activity에서 Application을 실행

Home에서 Application을 실행 할 경우 Application의 Root Activity는 다음과 같은 상태가 된다.

Home Activity : Foreground → Background
App Activity : <Create> → Foreground




2-1) BACK 키를 눌러 Home으로 이동하는 경우

만약 BACK 키를 누를 경우 Back Activity는 Home Activity이므로 현재 Activity를 제거하고 Home으로 되돌아간다. Back 키를 누르더라도 Activity가 Destory 되지 않는 예외 경우도 있는데 Audio Player와 처럼 Background 실행이 필요한 경우Service 형태로 처리한 경우이다.

Home Activity : Background → Foreground
App Activity : Foreground → <Destory>

그림으로 나타내 보면 다음과 같다.



이 상태에서 Application을 실행하면 처음 Application을 실행 할 때와 동일한 동작을 수행한다.




2-2) HOME 키를 눌러 Home으로 이동하는 경우

Activity를 실행 중 HOME 키를 누르면 무조건 Home Activity로 되돌아간다. 이럴 경우 실행 중이던 Activity는 잠시 Background 상태가 되지만 제거 되지는 않는다.

Home Activity : Background → Foreground
App Activity : Foreground → <Stop>  → Background




만약 이 상태에서 Stop된 Application과 동일한 Application을 실행 하는 경우 이미 실행 중이며 Background 상태였던 Activity가 다시 활성화 된다.

Home Activity : Foreground → Background
App Activity : Background → <Running>  → Foreground


만약, 새로운 Application을 실행할 경우 새로운 Task 가 활성화 되는 것으로 기존 Application과 동시에 실행되는 모습이 된다.

Home Activity : Foreground → Background
App Activity : Background in Task #1
New Acitiivy : <Create> → Foreground in Task #2




b. Activity 재사용하기

Activity A가 다른 application에 있는 Activity B를 시작할 때, activity B는 재사용 되었다(re-used)라고 한다. 이런 경우는 보통 Activity A는 여건이 없고 Activity B에는 있을 때 발생한다.


1) Contacts에서 Gallery를 재사용하여 사진얻기

Contacts Activity는 주소록의 사진 항목을 가지고 있지만, 사진이 보관되어 지는 곳은 보통 Gallery이다. 그렇기에 Contacts에서 사진을 가져오기 위해 Gallery activity를 재사용 할 수 있다. 이것은 Gallery activity의 재사용에 대한 좋은 예일 것이다. 다음 그림은 이미지 영역 지정(Crop)까지의 일련의 Activity 들을 나타내고 있다.



사용자가 Contacts를 선택하고, viewing을 위한 주소를 선택하고, MENU > Edit를 선택하고, Gallery activity를 실행 해 줄 사진 필드를 선택한다. 사용자는 원하는 사진을 선택하고, 영역을 지정(Crop) 한 후 저장한다. 이 이미지는 주소록의 사진 필드로 넣어져야 하기 때문에 저장 된다.

Gallery에서 Contact application로 사진을 준다는 것에 주목한다. 다음 예제는 result를 가져오지 않는 activity의 재사용에 대한 것이다. 이 또한 activity나 activity stack을 통핸 navigation history를 묘사하고 있음에 주목해야 한다. - 사용자는 모든 activity의 back 동작을 통해야만 Home으로 되돌아 갈 수 있다.

application을 디자인할 때 다른 application에 있는 activiity를 어떻게 재사용할지 생각하는 것과 자신이 만든 activity를 다른 applicatin에게 어떻게 재사용하도록 할지를 염두해 두는 것은 은 매우 바람직한 것이다. 만약 activity를 추가 할 때 기존에 있던 Activity와 동일한 intent filter를 적용한다면, 시스템은 사용자에게 이 activity들 중 어떤 것을 선택 할 것인지 알려준다.


2) Gallery에서 Messaging 재사용하여 사진 공유하기

공유라는 것은 한 application이 다른 application으로 부터 온 activity를 재사용하는 또 다른 좋은 예제이다.
아래 그림에서와 같이, 사용자는 Gallery를 시작하고, 사진을 선택하고, MENU > Share를 선택한 후 Messaging을 집는다.
이것은 Messaging Activity를 시작하게 하며, 새로운 Message를 만들고 원본 이미지를 첨부한다. 사용자는 "받는 이" 필드를 채우고, 짧은 문장을 작성 후 보내게 된다. 현재 사용자는 Messaing 프로그램에 있게 된다. 만약 사용자가 Gallery로 되돌아가려 하면, 반드시 BACK 키를 눌러야 한다. (사용자는 HOME으로 가기 위해 모든 Activity에 대해 Back 동작을 수행 할 수 있다)


이전 Contacts 예제와 달리, Message activity의 재사용에 대한 예제는 Gallery activity가 시작될 때 아무것도 가져가지 않는다.


c. Activity 대체

윗 글에서 Actiivity의 intent filter를 기존 activity와 동일하게 설정 할 경우 사용자가 어떤 Activity를 이용할지 선택할 수 있다고 언급 했었다. 이를 Activity 대체라 부른다.

이것은 Activity A가 다른 application에 있는 Activity B를 대체하는 경이다. 이런 상황은 보통 activity A가 activity B의 기능보다 더 나은 기능을 제공 하기 때문에 발생한다. 다시 말해서, A와 B는 동등하거나 A가 B를 대체할만큼 A와 B가 동등하다는 것이다. 이 경우 A와 B가 꽤 많이 다른 Activity들이며 서로가 다른 것들을 가지고 있을 때 Activity의 재사용과 두드러지게 대비된다.

이 예제에서는, 사용자는 Phone Ringtone Activity에 대한 대체로 Rings Extended라는 것을 다운로드 했다. 이제 Settings, Sound & Display, Phone Ringtone을 선택할 때, 시스템은 Android System의 ringtone activity와 새로운 것 사이에서 고를 수 있도록 해 준다. 이 다이얼로그 박스는 "Use by default for this action"이라는 항목을 기억할 수 있다. 만약 "Rings Extended"를 선택하면 Activity는 실행이됙 기존 Android ringtone activity는 대체된다.



c. Multi Tasking

Activity가 실행 중 HOME 키를 누르면 새로운 Task로 인식되며 Multi Tasking이 시작된다. 다음은 Maps에 대한 예로 설명한다.

1단계 - 사용자는 View Map Activity를 실행하고 지도 위치를 검색한다. 네트워크가 느리다고 한다면, maps는 지도를 그리는데 비정상적으로 오래 걸린다.

2단계 - 사용자는 이렇게 기다리는 동안에 뭔가를 하고 싶어하므로 HOME 키를 눌러 maps의 네트워킹 접속을 방해하지 않고 background에서 loading이 계속되도록 한다.

Activity가 Backgournd로 옮겨지면 Activity Lifecycle에 따라 onStop() 메소드가 호출이 되므로 Activity를 작성 할 때 계속 할 것인지 아니면 잠시 멈출 것인지 결정 할 수 있다. 네트워크로 부터 데이터를 다운로드하는 Activity들에 있어서 downloading을 계속 하도록 두는 것은 추천 할 만한 것으로 사용자의 multi-task를 가능하게 한다.

3단계 - map activity는 이제 Backround에서 실행되고 있고, Home은 Foreground로 실행되고 있다. 사용자가 Calendar Activity를 실행하면 foreground가 되고, 사용자 focus를 가지며, 오늘 날짜의 달력이 보여진다.



4단계 - 사용자가 HOME을 누르러 Maps를 다시 실행하면 지도 데이터가 완전하게 load 되어진 모습이 보여진다.



Home에 있는 applicaion laucher는 "View Map"과 "Day View" Activity를 별도의 task로 실행했으므로 시스템은 multitasking이다.


d. 두 개의 시작점으로 실행하기

모든 application은 적어도 하나의 이상의 시작점 (entry point)를 가져야 한다 - 시작점는 사용자 혹은 시스템이 application 내부에 있는 activity에 접근하기 위한 방법이다. Home에 있는 applicatin laucher에 있는 각각의 icon이 application의 시작점을 나타내고 있는 것이다. Application은 다른 application에서 실행 될 수도 있다. 또한 각각의 activity는 application에 잠재되어 있는 시작점이다.


Phone Application은 Contacts와 Dialer 두 개의 시작점을 가지고 있다.ㅏ용자는 Contacts에서 phone number를 선택하여 Dialer를 실행 할 수 있다. 아래 그림에서와 같이, 사용자는 Contacts Icon을 선택하여 Activity를 실행 시킬 수 있으며, Phone Number를 선택하여 Dialer Activity를 호출, 전화를 걸 수 있다.

사용자 한번이라도 application 실행 중에 있다면, Tab과 메뉴 아이템, 리스트 아이템, 스크린에 있는 버튼 혹은 다른 interface control을 이용하여 새로운 주소록을 만들거나 편집과 같은 다른 Activity에 접근할 수 있다.


e. Task 전환

이 시나리오는 사용자가 두 개의 task를 어떻게 전환하는지 보여준다. 이 예제에서, 사용자는 문자 메시지를 작성하고 이미지를 첨부하지만 끝내기 전에 잠깐 달력을 본다. 그리고 첨부된 사진이나 문자 메시지를 남겼던 곳으로 되돌아 온다.

1) Task 시작하기
문자 메시지와 사진을 첨부하려 한다면 다음과 같이 선택해야 한다:

Home > Messaing > New Message > MENU > Attach > Pictures. 이 마지막 단계는 사진을 선택하기 위해 Picture Gallery가 실행된다. Picture Gallery는 별도의 application임을 알아둔다.



사진을 선택하기 전쯤에서 잠깐 멈춰서 별도의 task에서 Calendar를 보려 한다. 현재 activity가 Calendar로 바로 가는 버튼이 없으므로 Home에서 시작해야 한다.

2) 두 번째 Task 시작하기

Home > Caledar를 선택하여 Calendar 이벤트를 본다. Application Laucher는 각각의 application이 실행 될 때 마다 새로운 task로 실행을 하기 때문에 Calendar는 Home에서 새로운 task로 실행이 된다.


3) 첫 번째 Task로 전환하여 마무리 하기

Calendar를 다 보고 난 후 root activity를 다시 시작하여 사진을 첨부하는 곳으로 되돌아 갈 수 있다:
Home > Messaging 선택, 이것은 Messaing으로 가는 것이 아니라 떠나기전 있던 곳인 Picture Gallery로 바로 진입한다. 이제 메시지에 첨부할 사진을 선택하고, 메시지를 보내면 처음 시작했던 task를 마치게 된다.






.




참고 : http://developer.android.com/guide/practices/ui_guidelines/activity_task_design.html

**
Trackback 0 Comment 2
2009.06.03 23:30

[android] SDK v1.5 r2 릴리즈

Android SDK v1.5 r2 가 릴리즈 되었다.

http://developer.android.com/sdk/1.5_r2/index.html

기존 SDK와 마친가지로 해당 Platform 별로 파일을 받아 적당한 디렉토리에 압축을 해제한다.

SDK와 함께 Eclipse Plugin도 업데이트 되었으므로 Help 메뉴의 Software Update로 해당 Android DDMS 와 Development Tool 등을 업데이트 해 준다.

그런데 다음과 같이 Plug-In 업데이트 도중 의존성 검사에서 fail이 발생하여 Plug-In이 설치되지 않는 경우가 있다.

Unsatisfied dependency ...
requiredCapability: org.eclipse.equinox.p2.iu ...

이는 Eclipse Ganimede 의 경우 종종 발생했던 문제라고 하는데 이런 문제가 발생한다면 Android Plug-In 에 앞서 Eclipse SDK를 먼저 업데이트를 진행하면 위의 문제는 해결된다.

Android Plug-In을 업데이트 했다면 Eclipse Preference 메뉴의 Anroid 탭에서 SDK location으로 처음 SDK v1.5 r2의 압축을 풀었던 폴더로 지정하여 SDK에 대한 설정을 완료한다.
Trackback 0 Comment 0
2009.05.28 16:30

[android] Android Dev Phone Firmware 복구 하기


전에 업급했듯 Android 단말은 개발용 단말인 Dev Phone 1과 상용 단말인 G1 단말이 있다. Dev1과 G1의 가장 큰 차이는 바로 adb service의 제공 여부다. adb service는 SDK와 단말 사이에 대한 Protocol을 지원하는 것인데 G1은 상용 단말이므로 기본 동작은 disable 되어 출시된다.

Dev Phone은 G1과 달리 이통사와 상관 없이 출시되고 또한 기업의 개발자들이 구매를 하므로 G1 보다 구매 가격이 높다. 따라서, G1을 이미 구매한 사람들이나 일반적인(?) Android 프로그래머는 단말에서 테스트 하기 어렵다.

그런데, Dev1이 아닌 G1 단말에서도 adb를 가능하게 해 주는 방법이 공개되었다. 초기 Android Version의 Back door를 이용하여 adb service를 활성화 하는 것인데 이를 이용하면 G1 단말에서 개발이 가능하게 된다 (이전 글 Android Dev Phone & G1 Phone Unlock 참조). 그 대신, adb는 root 권한을 가질 수 없으며, G1 단말 제조사인 HTC의 공식 update 도 사용 할 수 없어 일부 S/W 개발자가 배포한 Customized Firmware를 이용하거나, Customized Firmware를 직접 만들어 넣는 수 밖에 없다.

Dev Phone의 경우 adb root service는 기본으로 제공한다. 그러나, 최초 부팅 시 Google 계정 등록 화면으로 진행하도록 되어 있어 마치 Lock이 걸린 것 처럼 보일 수 있다. 그런데 만약 이를 해결 하기 위해 G1의 활성화 방법, 즉, Firmware를 업데이트 하는 방법으로 해결 할 경우 껍데기는 Dev1이지만 내부 version은 G1이므로 위에서 언급한 G1에 대한 문제점이 그대로 발생하게 된다.

그렇다고 원래대로 되돌리기도 그리 쉽지는 않다. 이렇게 Dev Phone이 G1으로 변경된 상태에서 Dev Phone Update를 진행하면 비록, Hardware는 Dev1이라 할지라도 Software가 G1이므로 정상적인 업데이트가 진행되지 않는다.

만약 일반적인 Dev Phone의 업데이트 과정을 진행한다면 다음과 같은 메시지를 보게 된다.

Android System recovery utility
E:Can;t open /cache/recovery/command

Home_Back - reboot system now
Alt+L - toggle log text display
Alt+S - appliy sdcard:update.zip
Alt+W - wipe data/factory reset

Installing from sdcard...
Finding update package...
Opening update package...
Verfying udpate package...
E:No signature (5 files)
E:Verification failed
Installation aborted.

Press Home+Back to reboot


결국 S/W가 G1으로 변경되면서 Bootloader Binary도 같이 변경되었기 때문에 해당 업데이트가 진행되지 않는 것이다.

Bootloader Version은 다음과 같이 세 가지 SPL이 있다.

HBOOT-0.95.3000 : Engineering SPL (Dev1)
HBOOT-0.95.0000 : Original SPL (G1)
HSPL10.95.3000 : Hard SPL ( Customized)

다음과 같은 방법으로 현재 Bootloader Binary 정보를 확인 해 볼 수 있는데 G1일 경우 HBOOT-0.95.0000 임을 확인 해 볼 수 있다.

1. 단말 종료
2. CAMERA 버튼 + POWER 로 부팅


따라서, G1용 Bootloader 를 Dev1이나 Customized Version으로 변경을 해 주어야 하며 이는 다음과 같은 방법으로 진행한다.

먼저 adb root service가 가능한지 확인 해 본다.adb root를 입력하여 root 계정을 활성화 여부를 확인 한다.
※ adb service는 활성화 한 상태이어야 한다.

$ adb root
error: closed


만약 root 계정이 활성화 되지 않는다면 위와 같이 에러 메시지가 출력되며 그렇지 않는 경우 adb shell로 접속 시 root 권한으로 실행 할 수 있다. (※ G1인 경우 adb를 이용한 root 계정은 거의 얻을 수 없다고 본다)

root 권한을 얻었다면 이제 이미지 복구를 위해 다음과 같은 과정을 거쳐 이미지를 복구한다.

- Android Market이나 별도의 파일로 제공되는 Telnet Application을 설치한다.
- 복구에 필요한 recovery.img 파일과 Hard SPL 혹은 Engineering SPL을 SDCard에 update.zip으로 복사한다.
- 재부팅 후 Home Screen 화면에서 Keypad를 연다.
- ↙↙telnetd↙ 를 입력한다. (※ 이 때 telnetd라고 출력되는 것은 정상)
- Telnet Application을 실행하면 root 권한을 가진 shell 로 접속이 되는 것을 확인 해 볼 수 있다.
- 이제 Telnet App에서 다음과 같이 입력한다.
# mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system
# cd /sdcard
# flash_image recovery recovery.img
# cat recovery.img > /system/recovery.img
- 단말 종료 후 HOME + POWER 버튼을 눌러 Firmware Update 모드로 진입한다.
- ALT + L을 누르면 Update 메시지가 출력되며, ALT + S를 눌러 SPL Verify를 진행한다.
- 업데이트가 완료되면 HOME + BACK을 누르면 Writing이 진행되고 자동으로 재부팅 된다.
- 재부팅 시 Flash ROM Writing이 진행되는 것을 볼 수 있다.
- 두 번 정도의 재부팅이 진행되면 ANDROID LOGO가 약간 달라진 것을 볼 수 있다.

이제 Dev Phone Update v1.5 Binary를 설치 해 볼 수 있으며 이와 관련된 부분은 이전 글 Android Dev Phone Firmware Update 하기 를 참고 하기 바란다.

참고 링크

* http://forum.xda-developers.com/showthread.php?t=442480
* http://www.androidandme.com/2009/05/guides/beginners-guide-for-rooting-your-android-g1-to-install-cupcake/
* http://androidcommunity.com/forums/f54/haykuro-adp1-5hr3-adp1-5hr3-a2sd-1-5-cupcake-16001/index515.html
Trackback 0 Comment 2
2009.05.07 13:27

[android] Linux에서 Android 단말 USB 인식하기

Fedora Linux의 경우 기본적으로 Android 단말<HTC G1, Android Dev1>을 연결했을 때 USB 장치로 자동으로 인식된다.
그러나 ADB를 이용하기 위해선 USB Device에 대한 몇 가지 설정이 필요하다.

1. USB Device 정보 추가
$ vi /etc/udev/rules.d/99-android.rules

2. 다음과 같이 내용 편집
SUBSYSTEM=="usb",SYSFS{idVendor}=="0bb4",SYMLINK+="android_adb",MODE="0666"

3. 다음 명령으로 usb 장치 재인식
$ udevcontrol reload_rules

이제 단말을 연결하고 다음과 같이 Device정보를 확인한다.

$ $ANDROID_SDK/tools/adb devices
* daemon not running. starting it now *
* daemon started successfully *
List of devices attached

단말이 인식되면 adb에서 정상으로 인식한 것이다.

Ubuntu나 Kubuntu에서 인식이 안될 경우 다음과 같이 작성한다.

1. USB Device 정보 추가
$ vi /etc/udev/rules.d/51-android.rules

2. 다음과 같이 내용 편집
# For Gusty/Hardy, edit the file to read:
SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"

# For Dapper, edit the file to read:
SUBSYSTEM=="usb_device", SYSFS{idVendor}=="0bb4", MODE="0666"

이제 단말을 연결하고 device 연결 정보를 확인한다.
Trackback 0 Comment 0
2009.05.07 01:14

[android] Android Dev Phone Firmware Upgrade 하기

Android는 지속적으로 update 되고 있으며 최근 SDK와 release된 cupcake version 은 v1.5 이다.

HTC의 경우 Dev1에 대한 Fireware를 제공하고 있으며 다음 문서에서 update binary 및 방법을 알 수 있다.

* HTC Android Dev Phone Update ( http://www.htc.com/www/support/android/adp.html )

다음은 위의 내용 중 v1.5 에 대한 내용을 간략히 설명한 것이다.

1. 업데이트 할 파일 준비

Update 방법으로 Recovery Mode와 Fastboot Mode 두 가지가 있으며 이에 따라 필요한 바이너리는 다음과 같다.

* Recovery Mode
a. Radio Image
b. Recovery Image

* Fastboot Mode
a. Radio Image
b. System Image

여기서는 전통적인 Recovery Mode를 기준으로 진행하기로 한다.

2. Radio Image 업데이트

Radio Image를 받은 후 SDCard에 update.zip이란 이름으로 복사한다.
만약 SDK tool인 adb를 이용하면 다음과 같이 입력한다.

$ cd $ANDROID_SDK
$ cd tools
$ adb push <radio-image-package>.zip /sdcard/update.zip
$ adb sync


POWER 버튼을 5초 이상 눌러 단말을 종료 후, HOME + POWER 버튼을 눌러 Recovery Mode로 진입한다.
진입에 성공하면 다음과 같은 이미지를 볼 수 있다.


키패드를 열어 ALT + L을 눌러 Recovery Mode로 정상 진입 했음을 확인한다.
ALT + S를 눌러 SDCard에 있는 이미지 파일로 update를 진행 한다.

진행 중 Verify, Update가 완료되면 BACK + HOME 버튼을 눌러 Writing 후 재부팅 하도록 해야 한다.
만약 정상적인 방법으로 재부팅이 된다면 Update는 진행되지 않는다.

재부팅 후 다음과 같은 업데이트 화면이 나타나면 완료시 자동으로 재부팅 한다. (version에 따라 이미지는 달라질 수 있다)



3. Recovery Image 업데이트
Radio Image와 마찬가지로 Image 파일을 update.zip이란 이름으로 SDCard에 저장 후 위의 update 과정을 실행한다.

모든 업데이트 과정이 끝나면 다음과 같은 메뉴에서 version 이 update 된 것을 볼 수 있다.

App Menu - Settings - About phone


Trackback 0 Comment 2
2009.04.30 13:28

[android] 에뮬레이터에서 외장 메모리 사용하기

일반적인 단말에서 외장 메모리 카드를 지원하듯이 android 에서도 SDCard 라는 형태로 외장 메모리를 지원한다.
이는 emulator에서도 확인 해 볼 수 있는데 다음과 같이 두 가지 방법으로 제공하고 있다.

1. AVD 생성 시 SDCard 생성.
Emulator의 사용을 위해 AVD (Android Virtual Device)를 생성할 때 SDCard를 같이 생성하는 방법이다.

$ cd $SDK1.5_HOME/tools/
$ ./android create avd -n mydroid_1.5_sd32 -t 2 -c 32M

이와 같이 생성 시 해당 AVD를 이용하는 Emulator는 모두 SDCard를 자동으로 인식하도록 되어 있다.
만약 기본으로 AVD 생성했다면 SDCard를 제거했다는 메시지를 볼 수 있다.






2. SDCard 이미지 생성 후 추가

다른 또하나의 방법은 Disk 이미지를 생성하여 이를 mount 하는 방법이다.

이는 Command line으로만 관리가 되므로 Console에서 다음과 같이 입력한다.

$ cd $SDK1.5_HOME/tools/
$ ./mksdcard 32M extdisk32.iso

extdisk32.iso는 32 MB 크기의 파일로 생성 됨을 볼 수 있다.

이제 이 이미지를 Emulator에 반영해야 하는데 Android Emulator는 실행 중 SDCard의 탈부착에 대한 처리를 하지 않고 있다. 따라서, Emulator 실행 시 -sdcard 옵션을 추가해서 실행 해 주어야 한다.

Command line으로 실행 할 경우는 다음과 같다.

$ ./android -sdcard extdisk32.iso

Eclipse에서 실행하는 경우 기존 실행되던 emulator를 종료 후 해당 프로젝트의 실행 (Run) 구성을 변경해야 한다.

1. 메뉴 - Run 항목 - Open Run Dialog 선택
2. Android Application 항목의 해당 Application Package 선택
3. Target 탭에 `Additional Emulator Command Line Options'항목 선택
-sdcard <파일 경로>extdisk32.iso

<파일 경로>는 extdisk32.iso 가 저정된 위치를 입력해야 한다.



이 상태로 실행하면 SDCard를 제거했다는 메시지는 보이지 않는다.



이제 SDCard에 데이터를 넣어 보자.

Emulator가 실행 중에는 Console에서 adb를 이용하여 다음과 같이 파일을 저장 할 수 있다.

$ cd $SDK1.5_HOME/tools/
$ ./adb push testfile.txt /sdcard/testfile.txt

Eclipse를 이용하는 경우 DDMS에서 File Explore 탭을 이용하면 보다 쉽게 접근 할 수 있다.



만약 Emulator가 실행되고 있지 않은 상태에서는 ISO 파일로 생성한 경우만 수정 가능하며, Ultra ISO와 같은 일반적인 ISO 편집 프로그램을 이용하면 된다.

그리고 또 하나, MS Windows가 아닌 환경 (Linux 등)에서 ISO 파일을 사용할 때 다음과 같은 메시지와 함께 외장 메모리가 인식되지 않는 경우가 있다.

ignoring locked SD Card image ...

이런 경우는 다른 Emulator에서 해당 ISO 파일을 사용하고 있거나 아니면 File Access Permission이 없거나 ISO 파일이 있는 파티션이 FAT32와 같이 vfat일 경우에 발생한다. 이런 경우 다음과 같이 처리하면 된다.

Permission이 없는 경우는 다음과 같이 full permission을 주고 확인 해 보면 된다.

$ chmod 777 extdisk32.iso
$ ls -l extdisk32.iso
-rwxr-xr-x 1 mc500 mc500 33554432 2009-06-04 18:44 extdisk32.iso

만약 vfat을 사용하는 경우 ISO파일을 리눅스 파티션으로 옮겨 놓거나 다음과 같이 symbolic link를 이용해서 링크를 걸면 된다.

$ ln -s $VFAT_DISK/extdisk32.iso $LINUX_DISK/extdisk32.iso


Android Emulator에 대한 자세한 설명은 다음 문서 (http://developer.android.com/guide/developing/tools/emulator.html) 를 참고하기 바란다.
Trackback 0 Comment 0