[안드로이드] Emulator: ERROR: bad config: virtual device directory lacks config.ini - 안드로이드 가상머신관련 오류 해결

by Blogger 하얀쿠아
2011. 1. 29. 20:21 소프트웨어 Note/Android

안드로이드 Emulator: ERROR: bad config: virtual device directory lacks config.ini - 안드로이드 가상머신관련 오류 해결

emulator: ERROR: bad config: virtual device directory lacks config.ini
emulator: could not find virtual device named 'test'

위와 같은 오류가 발생하는 이유는, 컴퓨터의 사용자 이름이 한글인 경우, 경로 인식을 제대로 하지 못해서 오류가 생긴다고 한다.
아래의 사진을 보면 커맨드라인의 폴더경로중 사용자이름 부분이 한글인 것을 확인할 수 있다.
바로 이러한 경우가 문제가 된다.


이런 문제가 생긴다고 가상머신을 사용하지 못한다면 더 이상 안드로이드 프로그래밍을 진행할 수 없을 것이다.

해결방법은 아래와 같다.

 

먼저 준비과정으로 환경변수를 설정하도록 한다.

아래의 사진처럼 환경변수를 설정할 수 있는 창을 띄운다.


'내컴퓨터' 우클릭 -> '속성' 을 클릭


이러면 창이 하나 나오는데, 거기서 환경변수라 적힌 버튼을 클릭하면 된다.

path라는 값을 찾아서 더블클릭 후, 빨간네모박스처럼 입력한다.

만약 path가 없으면 새로 만들면 되니까 걱정할 필요는 없다.

 

 

환경변수 설정을 완료했으면 다시 커맨드 창으로 이동하여

'android list avd'라고 입력해본다. 

혹시라도 이미 커맨드창이 실행되어 있던 중이라면 종료후 새로 시작하자. (바뀐 환경변수 내용은 이미 실행되어 있던 커맨드창까진 적용되지 않는다.)


아래 화면처럼 현재 PC에 설치된 가상머신의 종류들이 주르륵 나타나게 될것이다.

이걸 가지고 설치된 가상머신들을 파악할 수 있는 것이다.

 

사진을 보면 avd의 Path에 한글이 포함되어 있는 것을 알 수 있다.
한글이 없는 경로로  avd파일을 옮기는 것으로 문제를 해결할 수 있다.
C 드라이브에 아래와 같이 avd파일을 관리할 폴더를 생성하자. (폴더이름은 자유)

예제에서는 C:\android\avd\myavd21이라는 폴더를 만들고 그쪽으로 파일을 옴기는 작업을 수행했다.
2.1버전의 가상머신만 사용할 계획이어서 하나만 옮겼지만,
다른 가상머신도 사용할 의향이 있는 개발자라면 동일한 방법으로 옮기면 된다.

아래 사진과 같이 입력하면 생성한 폴더로 가상머신 파일을 이동시키게 된다.

 

 

본격적으로 프로그래밍을 시작하기도 전에 이것저것 걸리적 거리는게 많지만, 이외에도 많은 문제들이 있을 수 있다.

좌절하지 말자.

 

 

내용은 여기까지입니다.

'emulator: ERROR: bad config: virtual device directory lacks config.ini - 안드로이드 가상머신관련 오류 해결'에 관련된 내용 입니다.

이 댓글을 비밀 댓글로

나는 어떤 프로그래머가 되고자 하는가?

by Blogger 하얀쿠아
2011. 1. 19. 10:05 NULL ptr/일기장

나는 어떤 프로그래머가 되고자 하는가?

 


'프로그래머란 자신이 작성한 코드를 통해서 의사소통을 한다'

 

일단 소프트웨어를 개발하는 일이 시작되면 오직 프로그래밍 실력만이 말을 한다.

다른사람들 틈에 섞여서 일을 열심히 하는 '시늉'만 잘해도 버틸 수 있는 직종이 있다.

하지만 프로그래밍이라는 직업에는 그런 측면이 전혀 없다.

 

달리지 못하는 사람이 축구선수를 할 수 없고, 아름다운 소리를 만들어 내지 못하는 사람이 첼로 연주자가 될 수 없는 것처럼, 품질이 뛰어난 코드를 생산할 수 없는 사람은 프로그래머라는 직업을 유지할 수 없다.


프로그래밍은 소설이나 논문처럼 온 힘을 다해서 만들어낸 지적 활동의 결과물을 다른 사람들에게 보여주는 일이다. 

그렇기 때문에 진정한 실력이 없이 흉내만 내는 사람은 숨을 곳이 없다.


이력서 상의 직장 경력이 아무리 풍부한들, 나이가 많은들, 일류 대학을 나왔다고 한들, 튼튼한 연줄을 붙잡고 있다고 한들, 서류상의 화려함은 그가 작성한 코드의 구조와 성능 앞에서 거짓을 말할 수 없다.

프로그래밍에서는 무엇보다도 옆에서 함께 일하는 동료들의 눈을 속일 도리가 없다.

 

그래서 프로그래머들은 자신의 정신적 리더를

오직 실력만으로 결정한다.


옛날로 돌아간다면, 꿈을 좀 바꿔서... 공부 열심히 해서 치과의사나 성형외과 의사가 차라리... 낫지 싶다.

아니면 사법고시 일찌감치 준비해서 판사나 검사도 좋고..



이 댓글을 비밀 댓글로

[안드로이드] ADT 8.0.0으로 업데이트 후의 draw9patch 에러

by Blogger 하얀쿠아
2011. 1. 17. 13:24 소프트웨어 Note/Android

ADT 8.0.0으로 업데이트 후의 draw9patch 에러


Android SDK, draw9patch Tool


Android SDK에는 draw9patch 라는 툴이 내장되어있다.

이 툴은 auto resizing이 필요한 (버튼과같은) 이미지가 있을 때, 어느 영역을 resizing 할것인지를 지정하는 툴이라고 생각하면 이해가 쉽다.

그런데 Android SDK버전을 진저브레드로 업데이트 이후, draw9patch 실행시 아래와같은 예외메세지를 뿌리며 프로그램이 죽는 증상이 발생할 수 있다. (스트레스!)

원인은 swing-worker.jar 파일이 ANDROID_SDK설치폴더/tools/lib 에 없기때문에 발생한다.

해결책은 해당파일을 해당위치에 넣어주면 된다.
swing-worker.jar 파일은 아래에 링크해두었다.


swing-worker.jar


Marius Mathiesen라는 한 개발자가 문제점과 해결책을 찾았고, Google 안드로이드 코드 페이지에는 이미 보고됐다고 한다.

Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/jdesktop/swingworker/SwingWorker

at com.android.draw9patch.Application$1.run(Application.java:48)

at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)

at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)

at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)

at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)

at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Caused by: java.lang.ClassNotFoundException: org.jdesktop.swingworker.SwingWorker

at java.net.URLClassLoader$1.run(URLClassLoader.java:202)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:190)

at sun.misc.Launcher$ExtClassLoader.findClass(Launcher.java:229)

at java.lang.ClassLoader.loadClass(ClassLoader.java:307)

at java.lang.ClassLoader.loadClass(ClassLoader.java:248)

... 9 more




이 댓글을 비밀 댓글로

[책] 내 여자친구의 귀여운 연애

by Blogger 하얀쿠아
2011. 1. 13. 11:02 NULL ptr/ NULL ptr

내 여자친구의 귀여운 연애


내여자친구의귀여운연애
카테고리소설
지은이윤영수 (민음사펴냄, 2007년)
상세보기


'돈이 최고인 세상에서

돈벌이를 제대로 하는 것만큼

훌륭한 미덕은 없는것이다'

 

각자 다르게 살고있는 인간들의 이야기 5편을 담고있는

윤영수씨의 소설

 

사랑, 감정, 입양, 뻔뻔함, 현실과 연극, 치매, 살인기도, 자살,

돈, 황금만능주의, 패륜, 섹스와 문란함, 허세, 싸구려 주둥이 등.. 인간세상의 흥미로운 가십거리를 버무려내어

5개의 이야기로 풀어내는 소설이다

 

나 역시 언젠가는 이런 인간세상 안으로

좋던싫던 기어들어가야 하는 때가 오겠지?

이 댓글을 비밀 댓글로

[안드로이드] Preferences 다루기 - 앱의 환경설정을 위한 Class

by Blogger 하얀쿠아
2011. 1. 9. 09:28 소프트웨어 Note/Android

안드로이드 Preferences 다루기


앱을 개발하다보면 각각의 사용자별로 선호하는 값들을 저장하는 화면을 제공해야 할 때가 있다.

게시물을 보여주는 앱을 예를들어 보자. 한화면에 보여지는 글의 목록을 어떤 사용자는 10개를 선호하는 반면, 어떤 사용자는 5개를 좋아한다면 앱개발자가 글 목록의 개수를 강제로 고정시킬 것이 아니라,  사용자 별로 설정을 할 수 있게 허용하는 것이다. 이것을 '환경설정' 혹은 'Preferences' 라고 하며, 안드로이드 플랫폼은 이런 것을 구현하기 편리하도록 기능을 제공한다.

안드로이드 플랫폼은 Data를 저장하는 방법으로 환경설정(이하 Preferences), 파일, Local DB, 네트워크를 제공한다.


그 중 Preferences는 가장 간단하게 정보를 저장하는 방법(mechanism)을 제공하며, App이나 그 컴포넌트 (Activity, Service 등)의 환경 설정 정보를 저장/복원하는 용도로 사용된다.


Preferences의 형태

안드로이드에서 Preferences는 ListView의 형태로 표현되며 쉬운 Preferences의 구현을 위해 PreferenceActivity 클래스를 제공한다. PreferenceActivity 클래스는 XML 기반의 Preference 정의 문서를 통해 App 파일 저장소에 Preferences 파일을 생성하고 사용하는 방식으로 작동한다. (참고: 일반 Activity를 사용해 ListView형태의 Preference Activity가 아닌 커스텀 Preference Activity를 구현 할 수도 있지만 (Container + 각종 UI 위젯 사용) 이 글에서는 그 방법에 대해 다루지 않으려고 합니다)



 

 

▌Preferences 데이터 저장▐

Preferences를 위한 데이터 저장 시 사용되는 자료구조는 Map 방식이다. 즉 키(key)-값(value) 한 쌍으로 이루어진 1~n개의 항목으로 구성된다. 키(key) 는 String 타입으로, 말 그대로 각 데이터에 접근할 수 있게 하는 유일한 구분자며, 값(Value)은 기본 자료형 (int, boolean, string 등) 기반의 데이터로 구성된다. 다음은 Map 데이터 구조의 한가지 예이다.

 키(Key) - String 형
 값(Value) - 기본자료형
 Font
 "Noraml"
 FontSize  20
 FontColor  FFFFFFFF
 ... ...
 ... ...

 

위와 같은 Preferences데이터는 안드로이드 디바이스의

data/data/App 패키지 이름/shared_prefs/

경로에 XML형태의 파일로 생성된다. xml 파일 이름은, 파일 생성/접근을 위해 어떤 메서드를 사용하느냐에 따라 시스템이 지정 할 수도 있고, 개발자가 임의의 파일 이름을 지정할 수도 있다.

 

 

참고로, 안드로이드에서 Preferences 데이터 파일을 다수의 App간에 공유하는 것은 기본적으로 불가능 하게 디자인 되어 있다. (참고: 여기서 불가능하다는 뜻은 Preferences Framework에서는 타 App의 환경 설정 파일에 접근할 수 있는 메서드를 제공하지 않는다는 뜻이다. 그럴 필요가 있을지 모르겠지만, 굳이 접근해야 한다면 Preferences 파일 생성 모드를 MODE_WORLD_READABLE로 설정해 guest가 파일을 쓰고 읽을 수 있도록 하고(위에서 MyCustomePref.xml 처럼) Preferences 데이터 파일을 파일 스트림을 통해 읽어와 직접 파싱하고 사용할 수 있는 편법이 있긴 하다)

 

XML파일을 디바이스로부터 추출해 열어보면 Preference 데이터가 다음과 같은 형식으로 저장되어 있음을 볼 수 있다.

view source
print?
1 <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
2 <map>
3     <boolean name="GreetingMsg" value="true" />
4     <boolean name="sub_checkbox" value="true" />
5     <string name="AdditionalMsg">tigerwoods.tistory.com</string>
6     <string name="TextColor">FF00FF00</string>
7     <string name="Ringtone">content://settings/system/ringtone</string>
8 </map>

 

 

Preferences 구현 시 위와 같은 XML 기반 Preferences 데이터 파일을 File I/O API를 사용해 직접 생성/사용 하는 것은 아니다. 안드로이드는 Preferences구현/운용을 위해 android.preference 패키지 및 몇 가지 유용한 클래스/인터페이스(PreferenceActivity, SharedPreferences 등)를 제공하는데, 그것들의 도움을 받으면 손쉽게 Preferences를 구현/운용 할 수 있다.

 

 

▌Preferences 구현▐

안드로이드에서는 Preference 구현을 위해 많은 관련 클래스를 제공하기 때문에 그 클래스들을 적절히 이용하여 다음과 같이 몇 가지 단계만 추가하기만 하면 쉽게 프로젝트에 Preferences 기능을 추가 할 수 있다.

  • 프로젝트 내 어떤 환경정보를 Preferences로 관리 할지 설계
  • 위 설계에 따라 Preferences XML 문서를 작성하고 프로젝트 리소스로 공급 (\res\xml\ 밑)
  • 작성된 Preferences XML문서를 사용하는 PreferenceActivity 구현
  • Preferences가 필요한 Activity로부터 PreferenceActivity를 호출 (Intent 이용)
  • App이 다시 실행될 때 이미 저장된 Preference데이터 파일이 있다면 onResume()과 같은 callback내부에서 환경 설정 값 설정을 불러와 사용

 

위에 나열된 사항 이외에 Preference 데이터 파일의 생성, 데이터 변경 이벤트 listener, 데이터의 저장과 같은 부분은 PreferenceActivity 클래스가 자동으로 관리해 줌으로 개발자는 별로 신경 쓸 필요가 없다. (참고: PreferenceActivity를 사용하지 않고 일반 Activity로 구현한다면 안드로이드가 제공하는 여러 Preferences 관련 클래스 등을 이용해 파일 생성, 이벤트 listener, 저장 등을 직접 구현 해야 한다.)

 

그럼 위 Preference 구현 5단계 중 두 번째인 Preference XML 문서 작성부터 한 번 살펴보자.

 

 

 

 

2. Preference XML 문서 작성하기

 

Preference XML 문서를 작성하기 전에 문서를 구성할 Preferences 관련 클래스들에 관해 약간의 지식이 필요함. 이 글 끝 부분에 "참고. Preference XML 문서 작성시 사용되는 클래스" 단락에 간단한 클래스 설명과 중요 XML 속성, 메서드 등이 설명 되어 있음으로 참고.

 

Preferences XML 문서는 프로젝트 폴더\res\xml\파일이름.xml의 위치에 생성 한다. xml 파일의 이름은 개발자 임의로 지정할 수 있으며 추 후 code 상에서 R.xml.파일이름으로 접근 할 수 있다.

 

이렇게 생성된 XML 문서 내부를 여러 Preference 관련 클래스를 사용해 정의 해야 하는데, 이 글에 포함된 예제 프로젝트에서 사용된 Preference XML 문서를 살펴보면 다음과 같다.

소스 펼치기

 

 

그럼 settings.xml에서 사용된 요소들을 하나씩 분석해 보자

 

 

<PreferenceScreen>

Preferences XML 문서의 root 요소는 항상 <PreferenceScreen>이며 root 요소 내부에는 반드시 xmlns 속성 (xmlns:android=http://......)을 정의해 주어야 한다.

 

root로 사용된 <PreferenceScreen>는 child를 포함하는 container 역할을 하며, PreferenceActivity에게 Preferences 계층 구조를 전달하는 역할을 한다. root로 사용된 <PreferenceScreen>은 container역할 만 하고 자기 자신은 화면에 직접 표현이 안됨으로 title, summary 속성을 지정할 필요가 없다.

 

key 속성에 지정된 문자열은 추 후 code에서 이 preference 계층 구조 내부의 특정 요소를 찾을 수 있는 키 값이 된다.


Preferencescreen root = (PreferenceScreen)getPreference("preference_root");

CheckBoxPreference cb = (CheckBoxPreference)getPreference("checkbox");

 

 

<CheckBoxPreference> & <EditTextPreference>

Root <PreferenceScreen> 밑에 처음 나오는 두 개의 child이며, XML에 추가된 순서대로 Preference view에 표시된다.

각 아이템은 key, title, summary 속성이 지정되어 있으며, checkbox의 경우 초기 설정이 check 상태로 지정되어 있다.

<EditTextPreference> 같은 경우 DialogPreference로부터 상속하며, 클릭 시 별도의 다이얼로그 창을 popup 한다.

 

 

<PreferenceCategory>

예제는 총 2개의 <PreferenceCategory>가 있으며 첫 번째는 <ListPreference>와 <RingtonePreference>를 하나의 Category로 묶는다. 예제 XML의 34번째 라인에 보면 두 번째 Category도 지정되어 있으며 <PreferenceScreen>을 Catefory 멤버로 가지고 있다.

 

<PreferenceCategory>에서 title속성은 다른 Preference 객체와 같이 제목을 표시하지만, summary는 지정되어도 화면에 표시 되지 않는다.

 

또, 첫 번째 category의 속성 중 android:enabled 속성이 false로 지정되어 있음으로 Preference초기 실행 시 child인 <ListPreference>와 <RingtonePreference>는 비활성화 상태로 표현된다. 이와 같이 여러 Preference 아이템을 하나의 category로 묶으면 그룹 속성을 지정하는 것이 가능하다. (Preference의 마지막 항목, checkbox를 check하면 첫 번째 category를 활성화 함)

 

 

<ListPreference>

다른 항목들과 마찬가지로 key, title, summary가 설정되어 있으며, entries 속성에는 사용자에게 보일 ListView 아이템을 지정하며, entryValues속성에는 컴퓨터가 처리할 처리 할 정보를 제공한다. 예를 들면 entries – "Red", "Green", "Blue" 등 사람이 읽을 수 있는 값을 제공하고, entryValues에는 "FFFF0000", "FF00FF00", "FF0000FF" 등 컴퓨터가 사용할 정보를 제공한다.

 

또, android:defaultValue 속성이 "FFFFFFFF"으로 지정되어 있어 사용자가 설정 값을 바꾸기 전까지는 "FFFFFFFF" (흰색)이 기본 값으로 사용된다.

 

 

<RingtonePreference>

key, title, summary가 지정되어 있으며, showDefault와 showSilent가 true로 설정되어 Default 항목과 Slient 항목이 리스트에 표시된다. (<RingtonePreference>는 사용자가 지정한 정보를 바탕으로 Ringtone 설정 기능을 제공하는 Activity들을 찾는 Intent를 발생 시킨다. 디바이스에 여러 종류의 ringtone과 ringtone 관련 activity를 제공하는 app이 설치되어 있다면 더 많은 ringtone 옵션이 화면에 표시 될 수도 있다)

 

 

<PreferenceCategory>

두 번째 그룹으로 CheckBox를 별도의 화면에 표현하는 <PreferenceScreen> child를 포함.

 

 

<PreferenceScreen>

<PreferenceScreen>가 child 요소로 사용된 경우. Preferences에서 하나의 아이템으로 표현되기 때문에 title, summary가 지정되어 있다. 이 아이템을 선택하면 별도의 Preference 창 (dialog 기반)이 Popup한다.

 

 

<CheckBoxPreference>

key, title이 지정되어 있으며, summayOn과 summaryOff에는 각각 check상태의 도움말과 uncheck상태의 도움말이 설정 되어 있다.

 

 

 

 

3. XML + PreferenceActivity이용해 Preference 구현하기

 

작성된 Preference XML 파일을 화면에 표현 가능한 Preference로 만드는데 핵심적인 역할을 하는 것이 바로 PreferenceActivity이다. 전에 살펴본 적이 있는 ListActivity, TabActivity와 마찬가지로 Activity로 상속하며, Preference를 화면에 표현하고 운영하는데 특화된 클래스이다.

 

PreferenceActivity는 Preference 생성/운영에 도움이 되는 다음과 같은 편리한 기능이 구현되어 있다.

  • XML부터 Preference 계층 구조를 전달 받는 메서드 제공
  • 타 Activity의 Preference 계층 구조를 받아오는 메서드 제공
  • 제공된 Preference 계층 구조를 ListView 형태로 자동 구성/표현
  • 제공된 Preference 계층 구조에 따라 디바이스에 Preference 데이터 파일 자동 생성
  • 사용자가 변경한 사항들을 Preference 데이터 파일에 자동 저장

 

 

PreferenceActivity를 이용해 Preference를 구현하려면 크게 두 가지 단계만 거치면 되는데 다음과 같다. (물론 PreferenceActivity도 Activity 생명 주기를 따르기 때문에 onPause(), onResume() 메서드 같은 생명 주기 관련 callback의 구현도 신경 써야 하지만 여기서는 Preference를 구현하는 최소한의 기능만 설명한다)

  • PreferenceActivity를 상속하는 커스텀 클래스 정의.
  • onCreate()에 내부에서 Preference 계층 구조를 가져오는 메서드 호출.

 

위에서 두 번째 구현 순서로 설명된 Preference 계층 구조를 가져오는 메서드는 2개가 제공된다.

우선, \res\xml 밑의 Preference XML로부터 Preference 계층 구조를 얻어올 수 있는 메서드는 다음과 같다.

void addPreferencesFromResource(int)

Parameter:

  • int: Preference XML Resource. (예. R.xml.preferences)

 

두 번째로 타 Activity가 사용하는 Preference 계층 구조를 가져와 적용 시킬 수도 있는데, 이 때 사용되는 메서드는 다음과 같다.

(이 부분은 해결이 안 되는 중요한 버그가 있습니다. main preference까지는 잘 가져와 지는데 별도의 dialog를 띄우는 Preference 아이템을 클릭하면 WindowsManager가 BadTokenException을 발생합니다. 자세한 증상은 첨부된 예제 프로젝트에서 확인하시고, 혹시 해결 방법을 아시는 분은 꼭 댓글 부탁 드립니다)

void addPreferencesFromIntent(Intent)

Parameter:

  • Intent: Preference 계층 구조를 제공할 Activity를 지정하는 Intent

 

구현이 완료된 PreferenceActivity는 타 Activity로 부터 호출 되면 ListView 형태의 Preference 화면을 사용자에게 제공하고, 사용자가 정보를 수정하면 자동으로 Preference 데이터에 저장 하게 된다.

 

PreferenceActivity가 많은 편의 기능을 제공하지만 저장된 설정 복원은 개발자의 몫이다. 즉, 포함된 App이 다시 실행될 때, 기존에 저장된 Preferences설정 값을 Preference 데이터 파일로부터 읽어와 App에 적용 시키는 작업 (ex. App시작 시 Preference 파일에 저장된 폰트 색깔 등을 로드 해 App에 적용시키는)은 개발자가 직접 구현해 주어야 한다. 이를 위해 다음 단락에는 저장된 Preference 데이터 파일에 접근하여 저장된 정보를 가져오는 방법에 대해 알아본다.

 

 

 

 

4. Preference 데이터 파일로부터 환경 복원하기

 

안드로이드에서는 SharedPreferences 인터페이스를 이용해 저장된 Preferences 데이터 파일에 접근한다.

 

 

▌SharedPreferences 인터페이스 얻기▐

 

안드로이드 코드 내에서 SharedPreferences 인터페이스를 얻는 방법은 다음 나열된 세 개의 메서드를 통해서 가능하다. 



SharedPreferences Activity.getPreferences(int)

Parameter:

  • int: Preference 데이터 파일의 생성 시 접근 권한을 설정. Context클래스에 상수로 선언된 MODE_PRIVATE, MODE_WORLD_READABLE, MODE_WORLD_WRITABLE을 설정 가능. MODE_PRIVATE는 지금 App 만 접근 가능하도록 파일을 생성하며 (_rw_rw____), MODE_WORLD_READABLE/WRITABLE은 타 App에서도 파일을 읽고/쓸 수 있도록 생성한다 (_rw_rw_r__ 또는 _rw_rw__w_ 또는 |를 이용해 두 속성을 모두 지정하면 _rw_rw_rw_)

Return:

  • SharedPreferences: 메서드가 호출되는 Activity 클래스의 이름으로 저장된 Preference 데이터 파일의 SharedPreferences 인터페이스를 리턴. 같은 이름의 Preference 데이터 파일이 없을 경우 새로 생성

 

예를 들면 Activity를 상속하는 A, B라는 클래스 이름의 커스텀 Activity가 정의 되어 있다. A 내부에서 getPreference를 호출할 경우 디바이스의 Preference 저장 위치(data/data/패키지이름/shared_prefs/)에 A.xml 이라는 Preference 데이터 파일을 검색하고 파일이 존재 한다면 해당 파일에 대한 SharedPreferences 인터페이스를 리턴 하며, 파일이 존재하지 않을 경우에는 A.xml 파일을 생성한 후 생성한 파일에 대한 SharedPreferences 인터페이스를 리턴한다. 마찬가지로, B 내부에서 getPreference를 호출할 경우 디바이스에서 B.xml 파일을 검색 후 해당 파일에 대한 SharedPreferences 인터페이스를 리턴 한다 (없으면 파일 생성 후 인터페이스 리턴).


 

SharedPreferences Context.getSharedPreferences(String, int)

Parameter:

  • String: 사용(생성)할 Preference 데이터 파일의 이름을 지정
  • int: 생성될 Preference 데이터 파일의 생성 시 접근 권한을 설정

Return:

  • SharedPreferences: 첫 번째 인자로 전달되는 문자열과 일치하는 이름의 Preference 데이터 파일의 SharedPreferences 인터페이스를 리턴. 만약 같은 이름의 파일이 없다면 파일을 새로 생성하고 생성된 파일에 대한 SharedPreferences 인터페이스를 리턴

 

한가지 참고할 사항은 이 메서드를 통해 개발자가 생성/사용될 Preference 데이터 파일의 이름을 임의로 설정할 수 있다는 것인데, 예를 들어, A라는 Activity에서 getSharedPreferences("initial_setting", MODE_PRIVATE)라는 메서드를 실행한다면, preference framework는 /data/data/패키지/shared_pref/ 밑에서 initial_setting.xml이라는 파일을 검색하고 없다면 이를 새로 생성 후 initial_setting.xml에 대한 SharedPreferences 인스턴스를 리턴 하게 된다..

 

제일 처음에 설명한 Activity.getPreferences(int)도 실제로는 자기자신을 호출한 Activity(또는 컴포넌트)의 이름과 입력된 int 형 인자를 가지고 본 메서드를 호출하는 형태로 구현되어 있다.




Static SharedPreferences PreferenceManager.getDefaultSharedPreferences(Context)

Parameter:

  • Context: 사용하기 원하는 SharedPreferences 인터페이스를 포함하는 Context 지정

Return:

  • SharedPreferences: 인자로 지정된 Context (app 구동 환경)가 기본으로 생성하는 Preference 데이터 파일에 대한 SharedPreferences를 리턴

 

이 메서드는 App level의 기본 Preference 데이터 파일을 생성/사용하는데 사용된다. 예를 들어 com.holim.test.aaa 라는 패키지에 포함되는 A Activity에서 본 메소드를 호출 하면 Preference 프레임웍은 /data/data/패키지이름/shared_pref/com.holim.test.aaa_preferences.xml 이라는 Preference 데이터 파일을 생성한다. 전달된 Context 인자에 따라 패키지이름_preferences.xml 형태로 생성/사용할 Preference 데이터 파일의 이름이 시스템에 의해 자동으로 지정되게 되기 때문에, 호출되는 위치가 어디이든 같은 Context를 인자로 전달해 호출한 getDefaultSharedPreferences(…)메서드는 항상 같은 SharedPreferences 인스턴스를 리턴한다.

 

한가지 참고할 사항은 본 메서드는 static 메서드이기 때문에 메서드를 제공하는 PreferenceManager 클래스를 따로 생성할 필요 없이 다음과 같이 사용하면 된다.

SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);

 

 

이와 같이 여러 메서드를 사용해 얻어온 SharedPreferences 인터페이스로 무엇을 할 수 있는 지 알아 보자. 다음은 SharedPreferences 인터페이스가 제공하는 중요 메서드들이다.

 

 

▌SharedPreferences 인터페이스▐

 

SharedPreferences 인터페이스가 제공하는 기능은 다음과 같다.

  • 디바이스에 저장되어 있는 Preference 데이터 파일로부터 데이터를 추출하는 여러 메서드
  • Preference 데이터를 수정하는 방법을 제공하는 Editor 내부 인터페이스
  • Preference 데이터가 변경되었을 때 호출되는 callback 인터페이스

 

중요 메서드

SharedPreferences.Editor edit() – SharedPreferences가 연결된 Preference 데이터 파일을 수정 할 수 있게 여러 메서드를 제공하는 Editor 인터페이스 리턴. Editor 인터페이스는 자료 수정을 완료 한 후 Editor.commit() 메소드를 사용해야 파일에 변경내용이 저장됨.

void registerOnSharedpreferenceChangeListener(…) – Preference 변경 이벤트 Listener 등록

void unregisterOnSharedPreferenceChangeListener(…) – 위에 등록한 이벤트 Listener 등록 해지

Map <String, ?> getAll() – 모든 Preferences 값을 Map 자료형으로 리턴

boolean contains(String) – 인자로 제공되는 문자열과 같은 key의 Preference 항목이 있으면 true 리턴

타입 get타입(String, 타입) – Boolean, Float, Int, Long, String 형 메서드가 있으며 첫 인자는 데이터를 가져올 Key 값이며, 두 번째 인자는 찾는 preference 데이터가 존재하지 않을 때 리턴 할 값이다.

Boolean isMarried = sharedPref.getBoolean("결혼여부", false);

int fontSize = sharedPref.getInt("폰트사이즈", 20);

 

중요 인터페이스

  • SharedPreferences.Editor – Preference 파일에 저장된 항목을 수정/제거 할 수 있는 여러 메서드를 제공하는 인터페이스
  • SharedPreferences.OnSharedPreferenceChangeListener – Preference 데이터가 변경되었을 때 호출되는 callback 인터페이스

 

 

예제 프로젝트 중 MainActivity.java의 onCreate(…)와 onPause(…)메서드에서 보면 지금까지 설명한 SharedPreferences 인터페이스 얻기와 인터페이스가 제공하는 여러 메서드를 사용해 Preference 데이터 파일로부터 저장된 정보를 가져와 사용하는 것을 볼 수 있다.


MainActivity.onCreate()

소스 펼치기

 

MainActivity.onResume()

소스 펼치기

 

 

 

 

참고. Preference XML 문서 작성시 사용되는 클래스

 

전 글들에서 다루었던 XML을 이용한 UI메뉴 구성에서도 봤듯이

XML을 이용하면 디자인과 Logic을 분리 시킬 수 있어 간결한 코드의 구성이 가능할 뿐 아니라 현지화/유지보수 등 작업을 하는데 훨씬 편리 할 수 있음으로 권장되는 구현 방식 이라고 설명 한 적이 있다.

 

Preference에서도 마찬가지로 XML을 이용해 Preferences 구조를 쉽게 정의할 수 있다.

 

Preference XML 문서 작성시 android.preference 패키지 밑의 여러 클래스가 사용되는데 패키지 내부의 중요한 클래스의 상속 구조는 다음과 같다.

 

 

붉은 색 사각형 내부의 클래스가 Preferences 과 직접적으로 연관이 있는 클래스이며, 그 중 Preference 클래스를 비롯한 하위 클래스들이 XML Preference 문서 작성에 사용된다.

 

그럼 Preference 클래스부터 한번 살펴보자

 


 

▌Preference 클래스▐

여러 Preference 관련 클래스의 최상위 부모 클래스 이므로, 제공하는 XML 속성, 메서드는 자식 Preferences 관련 클래스에서도 모두 사용할 수 있다. XML 내부에서 직접적으로 사용되지는 않는다.

 

중요 XML 속성

  • android:key – Preferences 데이터 저장/불러올 때 사용되는 키(key) 지정
  • android:title – Preference 항목의 제목을 지정
  • android:summary – Preference 항목을 자세히 설명하는 문자열 지정
  • android:enabled – Preference 항목의 활성화 비활성화 여부 지정 (true/false)
  • android:selectable – Preference 항목의 선택 가능 여부 결정 (true/false)
  • android:order – Preference 항목이 표시되는 순서를 결정 (0-based 정수 사용: 낮은 값 먼저 보임). 순서가 명시적으로 지정되지 않는다면 XML에 정의된 순서대로 표시됨

 

중요 메서드

  • void setKey/Title/Summary(…) – Preference 항목의 키/제목/설명을 지정
  • void setEnabled(boolean) - Preference항목의 활성화/비활성화 여부 지정
  • void setSelectable(boolean) – Preference 항목의 선택 가능 여부 결정
  • void setLayoutResource(int) – Preference 항목에 표시할 View를 R 클래스로부터 지정
  • void setOnPreferenceChangedListener(…) – Preference 항목에 변화가 있으면 호출될 callback을 지정
  • void setOnPreferenceClickListener(…) – Preference 항목에 click 이벤트가 발생하면 호출될 callback을 지정

 

중요 인터페이스

  • Preference.OnPreferenceChangeListener - 사용자가 Preference를 변경하였을 때 호출되는 callback에 대한 인트페이스
  • Preference.OnPreferenceClickListener - 사용자가 Preference를 클릭하였을 때 호출되는 callback에 대한 인터페이스

 

 


▌PreferenceGroup 클래스▐

 

Preferences를 구성하는 객체들을 담을 수 있는 Container 클래스. PreferenceCategory와 PreferenceScreeen을 파생. XML 내부에서 직접적으로 사용되지는 않음.

 

중요 메서드

  • boolean addPreference(Preference) – 새로운 Preference 항목을 그룹에 추가. 추가 성공/실패 리턴.
  • Preference findPreference(String) – 인자로 전달되는 문자열과 같은 key값을 갖는 group 내 (자기자신포함) Preference 항목 리턴
  • Preference findPreference(int) – 인자(0-based정수)에 명시된 위치의 Preference 항목 리턴. 기본적으로 가장 처음 추가된 항목이 index 0
  • void removeAll() – 이 그룹 내 모든 Preference 항목을 삭제함
  • void removePreference(Preference) - 인자로 전달된Preference 항목을 삭제함
  • void setEnabled(boolean) – 그룹 전체의 활성화/비활성화 여부 지정
  • void setOrderingAsAdded(boolean) – true일 경우 그룹에 추가된 순서로 표현. false일 경우 Preference아이템 내 순서 정보가 있으면 그걸 따르고 순서 정보가 없으면 Preference 아이템의 title을 이용해 알파벳순 정렬.

 


 

▌PreferenceScreen 클래스▐

 

PreferenceGroup에서 파생하며, 실제로 Preference XML 문서 내부에 사용 되는 클래스이다. 여러 Preference 구성 요소를 담을 수 있는 root container역할을 하며 Activity에 표현될 Preference의 계층구조를 나타내는 클래스이다. PreferenceActivity에 전달되어 이 클래스의 인스턴스가 포함하는 것들을 화면에 표현한다.

 

이 클래스가 Preference XML 문서에서 사용될 때는 다음과 같이 두 가지 용도로 사용된다.

  • Preference XML 문서의 root 요소 사용 시 - 경우에는 PreferenceActivity에 전달되어 preference의 전체 구조를 전달하는 용도로 사용. 이 경우 자기 자신은 화면에 표현 안되고 child 요소를 포함하는 Container의 용도로 사용됨 (XML UI에서 Containter는 화면에 표현 안되고 것과 같은 의미)
  • Preference XML 문서에서root가 아닌 child 요소로 사용 시 - Preference 아이템 중 하나로 취급. Preference 아이템 중 하나로 화면에 표시되며, 클릭 시 별도의 preference 화면으로 이동

 

!!! 그림 (main pref. -> sub pref)

 


 

▌PreferenceCategory 클래스▐

 

Preferences를 구성하는 객체들을 특정 category별로 분류 할 수 있게 하는 클래스. 중요한 XML 속성이나 메서드 없음

!!! 그림 (category 분류)

 

 


▌DialogPreference 클래스▐

 

모든 dialog 기반 Preference 객체의 부모 클래스. Preference 화면에는 링크만 표시되고, 링크를 클릭했을 때 실제 Preference를 컨트롤 할 수 있는 Dialog가 popup한다.

!!! 다이얼로그 그림

 

중요 XML 속성

  • android:dialogIcon – Dialog의 Icon 지정
  • android:dialogTitle – Dialog의 제목 지정
  • android:dialogMessage – Dialog 내에 표시될 문자열 내용 지정
  • android:negativeButton – 부정 버튼에 표시될 Text설정 (취소, cancel 등)
  • android:positiveButton – 긍정 버튼에 표시될 Text 설정 (적용, OK 등)

 

중요 메서드

  • void setDialogIcon(Drawable) – Dialog의 Icon 지정
  • void setDialogTitle(…) – Dialog의 제목 지정. 문자열 직접 지정 또는 문자열 리소스 사용
  • void setDialogMessage(…) – Dialog 내에 표시될 문자열 내용 지정
  • void setPositiveButtonText(…) – 부정 버튼에 표시될 Text설정 (취소, cancel 등)
  • void setNegativeButtonText(…) – 긍정 버튼에 표시될 Text 설정 (적용, OK 등)

 


 

▌EditeTextPreference 클래스▐

 

DialogPreference로부터 상속하며, 사용자로부터 문자열을 입력 받아 저장 하기 위한 Preference 아이템을 구현한 클래스.

 

중요 메서드

  • EditText getEditText() – Dialog가 포함하는 EditBox인스턴스를 리턴
  • String getText() – SharedPreferences 객체로부터 저장된 문자열 리턴
  • void setText() – SharedPreferences에 문자열 저장

 


 

▌ListPreference 클래스▐

 

DialogPreference로부터 상속하며, Dialog기반의 ListView 위젯에 미리 제공되는 문자열들을 표현하고 사용자가 그 문자열 중 하나를 선택하여 설정 값을 지정할 수 있도록 구현한 클래스.

 

중요 XML 속성

  • android:entries – ListView의 각 raw에 표현될 문자열을 array 리소스를 통해 공급. 사용자(human)를 위한 정보.
  • android:entryValues – ListView의 특정 raw가 사용자에 의해 선택되었을 때 프로그램 내부적으로 처리 할 문자열 data를 array 리소스 형식으로 제공. 컴퓨터가 처리 하기 위한 정보. (ex. 남/여: 사람을 위한 정보 -> 0/1: 컴퓨터를 위한 정보)
  • android:defaultValue – 초기 선택 항목 지정. (0-based 정수)

 

중요 메서드

  • CharSequence[] getEntries() – ListView의 각 row에 표현될 문자열들을 리턴 (사용자 위한 정보)
  • CharSequence[] getEntryValues() – Entry(사람을 위한 정보)와 연계된 컴퓨터가 처리할 문자열들을 리턴
  • void setEntries(…) – ListView의 각 row에 표현할 문자열 지정. Array리소스 또는 CharSequence[] 전달
  • void setEntryValues(…) – 컴퓨터가 처리할 문자열 지정. Array또는 CharSequence[] 전달

 


 

▌CheckBoxPreference 클래스▐

 

CheckBox 기능의 Preference 아이템을 구현한 클래스. SharedPreferences에 boolean 값으로 정보 저장

 

중요 XML 속성

  • android:summayOn – CheckBox가 check상태일 때 사용자에게 보일 안내문
  • android:summaryOff – CheckBox가 uncheck 상태일 때 사용자에게 보일 안내문

 

중요 메서드

  • boolean isChecked() – 현재 check/uncheck 상태 리턴
  • void setChecked(boolean) – CheckBox를 program 상에서 check/uncheck 함
  • void setSummaryOn(…) – CheckBox가 check상태일 때 사용자에게 보일 안내문 설정. String 리소스나 CharSequence 인스턴스 전달
  • void setSummaryOff(…) – CheckBox가 uncheck상태일 때 사용자에게 보일 안내문 설정

 


 

▌RingtonPreference▐

 

사용자가 디바이스에서 제공하는 전화 벨 소리를 지정할 수 있게 구현된 클래스. Intent를 이용해 어떤 벨 소리 Picker를 화면에 표시할 지 결정함.

 

중요 XML 속성

  • android:ringtoneType – 어떤 종류의 벨 소리 종류를 선택 가능하게 할지 지정. ringtone, notification, alarm, all 중에 하나 또는 복수(| 사용)개 지정 가능
  • android:showDefault – Default 벨소리 항목 표시 여부 결정 (true/false)
  • android:showSilent – 무음(Silent) 항목 표시 여부 결정 (true/false)

 

중요 메서드

  • setRingtoneType(int type) – XML 속성 중 ringtoneType에 대응. RingtoneManager 클래스에 선언되어 있는 상수 TYPE_RINGTONE, TYPE_NOTIFICATION, TYPE_ALARM, TYPE_ALL 중 하나 또는 복수(|사용) 전달
  • setShowDefault(boolean) – XML showDefault 속성에 대응
  • setShowSlient(boolean) – XML showSilent 속성에 대응

 


 

PreferenceManager 클래스

 

Activity나 XML로부터 Preferences 계층구조의 생성을 돕는 helper 클래스이지만 이 클래스를 이용하여 직접 Preferences를 구성하기보다는 PreferenceActivity.addPreferenceFromResource(int) 또는 PreferenceActivity.addPreferenceFromIntent(Intent)를 사용하는 것이 일반적이다.

 

혹시, PreferenceActivity를 사용하지 않고 Activity를 이용해 직접 Preferences 화면을 구성해야 한다면 필요한 클래스이다.

 

중요 메서드

  • Preference findPreference(CharSequence) – 인자로 전달되는 Key값을 가지는 Preference 항목의 인스턴스를 가져옴
  • SharedPreferences getDefaultSharedPreferences(Context) – 제공되는 context가 기본으로 사용하는 Preference파일로부터 SharedPreferences인스턴스 생성해 리턴
  • SharedPreferences getSharedPreferences() – this객체가 사용하는 context와 연결될 Preference파일로부터 SharedPreferences 인스턴스 생성해 리턴
  • void setDefaultValues(Context, int resId, boolean) – 제공되는 context가 사용하는 SharedPreferences를 두 번째 인자로 제공되는 XML 리소스에 정의된 기본 속성값들로 설정 함. 세 번째 인자가 false 일 경우엔 이 메서드가 전에 실행된 적이 있다면 무시하고, true일 경우 전에 실행 여부화 상관없이 재 실행된다. 참고: 마지막 인자를 true로 지정 했다고 해서 이 메서드를 이용해 Preferences를 바로 초기화 할 수 있는 것은 아니고, SharedPrefernces.clear() 메서드를 사용해 Preferences 항목을 모두 삭제 후 이 메서드를 사용해 XML에 지정된 본래의 값으로 Preferences를 초기화 할 수 잇다.






이 댓글을 비밀 댓글로

[안드로이드] 서로다른 Activity 사이에 Parcelable사용하여 데이터/객체 전달 및 받는 방법

by Blogger 하얀쿠아
2010. 12. 30. 13:49 소프트웨어 Note/Android

서로다른 액티비티(Activity) 사이에 Parcelable사용하여 데이터/객체 전달 및 받는 방법


Parcelable의 정석적인 사용방법은 아니지만, 객체의 포인터를 액티비티간 주고 받는 방식으로 보면 될 것 같다.

물론 자바는 포인터가 없지만 여기서 사용한 방법은 개념상 포인터를 넘기는것과 같다고 봐도 무방할것 같다.


이미 잘 알려진것과 같이, 안드로이드에서는 서로다른 엑티비티 사이에서 객체를 주고 받기 위해서는 Intent를 이용한다.

그런데 기본 데이터 형인 int, String, short, float... 등이 아니라 사용자 정의 Class의 instance를 넘겨야 하는 상황이라고 생각해보자.

어떻게 해야할까?

이때 사용되는 interface가 Parcelable 이다.

기본 자료형 int, boolean, long, String 등등 이 아닌 일반 Class의 instance를 엑티비티간에 주고 받기 위해서는, Parcelable을 이용해서 포장한 후에 넘겨주어야 한다.


보내는 엑티비티를 A라고 하고, 받는 엑티비티를 B라 가정해보자.

A에서는 Intent에 putExtra( ) 메서드로 객체를 넣고, B에서는 getParcelable( ) 메서드로 객체를 받는다.

이때 사용할 putExtra( )는 아래의 API이다.


Intent putExtra (String name, Parcelable[] value)

Add extended data to the intent. The name must include a package prefix, for example the app com.android.contacts would use names like "com.android.contacts.ShowAll".


name : String, 패키지 접두어를 가진 추가 데이터의 이름.

value : Parcelable, Parcelable[ ] 배열 데이터 값


Cursor의 instance를 넘기는 예제를 보자.

우선 아래와 같이 'Parcelable' interface를 구현하는 'ParcelableCursor' 라는 이름의 Class를 하나 정의한다.

public class ParcelableCursor implements Parcelable {
	static private Cursor mCursor = null;
	static ParcelableCursor obj = null;

	ParcelableCursor(Cursor cursor) {
		mCursor = cursor;
		obj = this;
	}

	public Cursor getCurosr() {
		return mCursor;
	}

	public int describeContents() {
		return 0;
	}
	public void writeToParcel(Parcel out, int flags) {
		;
	}
	public static final Parcelable.Creator CREATOR
	= new Parcelable.Creator() {
		public ParcelableCursor createFromParcel(Parcel in) {
			return obj;
		}
		public ParcelableCursor[] newArray(int size) {
			return new ParcelableCursor[size];
		}
	};     
}


Parcelable interface는 public abstract 메서드가 2개다.

  • abstract int describeContent( )
  • abstract void writeToParcel(Parcel dest, int flags)

그렇지만, 예제코드에서 이 둘은 하는 일이 없다.

받는 엑티비티(B) 쪽에서  Parcelable객체를 전달받고, 해당 객체로부터 Cursor객체를 받기 위해 getCurosr( ) 라는 메서드를 만들어 주었다.


CREATOR 에서만 obj 를 리턴 하는데, 이는 최초 객체가 생성될때 생성자에서 자기 자신을 담고 있는다.

A에서 Cursor객체를 생성해서 putExtra 로 전달하면, B에서는 getParcelable 를 호출할 것이고, 이때  CREATOR가 호출되면서 이는 곧 다른 엑티비티에서 보내온 객체를 할당 받게 된다.


A(보내는 엑티비티) 

ParcelableCursor pc = new ParcelableCursor(cursor);
         intent.putExtra("cursor_instacne", pc);
         startActivity(intent);



B(받는 액티비티)

ParcelableCursor parcelcursor = bundle.getParcelable("cursor_instance");
         Cursor cursor = parcelcursor.getCurosr();


엑티비티 사이 에서 객체를 주고 받는 것은 interface를 맞춰주고 Parcelable객체도 만들어 주어야 하는 약간 손이 가는 작업이다. 객체의 전달은 서로 다른 프로세스 사이에서도 발생할 수 있기 때문에, 속도저하 문제 등에도 어느정도 영향을 줄 수 있다.

때때로, 이렇게 Parcelable을 전달하는게 유용할 경우도 있는데, 예를 들면, 주변 bluetooth device 스캐닝 후의 결과 목록을 위와 같이 Parcelable interface를 통해 UI화면으로 전달하는 것 등이다.

가능하다면 구현 전 설계 단계에서 이런 불필요하고 복잡한 일은 회피 할수 있도록 하는게 바람직 할 것 같다. 또한, 불가피 하게 적용해야 하는 상황이라면, 이 방법을 한번 검토 해보길 바란다.



이 댓글을 비밀 댓글로

[안드로이드] 이미지와 텍스트가 같이 들어간 버튼 만들기

by Blogger 하얀쿠아
2010. 12. 30. 13:47 소프트웨어 Note/Android

이미지와 텍스트가 같이 들어간 버튼 만들기

안드로이드 SDK(1.5기중)에는 버튼을 처리하는 클래스가 Button과 ImageButton 크게 두가지 있다. 


ImageButton이 내부에 이미지를 가지고 있는 버튼이고,  Button은 TextView를 상속하고 있기에 텍스트 버튼이라고 생각하기 쉬운데, 사실 그렇지 않다.

일반적으로 버튼을 표시할때 간단하게 해당 버튼의 기능을 시각화 하여 나타내는 간단한 Icon을 함께 넣어주는 경우가 많을텐데, 그런 경우 ImageButton대신 Button을 활용해서 처리할 수 있다.


이미지의 위치는 텍스트의 상, 하, 좌, 우에 위치시킬 수 있으며, Xml에서는 각각 android:drawableTop, android:drawableBottom, android:drawableLeft, android:drawableRight에 drawable값을 넣어줌으로써 처리 가능하다.

그리고 텍스트와 이미지 사이의 간격은 android:drawablePadding 값으로 설정할수 있다.


<Button
	android:layout_width="fill_parent"
	android:layout_width="wrap_content"
	android:drawableLeft="@drawable/ic_settings"
	android:drawablePadding="4dp"
	android:text="Settings"
/>



drawableLeft를 넣어서 만든 버튼의 모습이다.

혹시나 어렵게 직접 Layout을 써서 버튼을 구성하시고 계시는 분들이 있을까 하여 팁을 작성하였다. 


아이콘이 들어간 Android Button

안드로이드 어플을 작성한지 1년 반이 되가는데 가끔 새로나온 SDK의 기능을 못보고 옛날 스타일로 작성하는 경우도 종종 있고, 웹의 소스들도 오래된 것들이 많아서 새로 SDK나올때마다 중요한 부분들은 정리를 해서 체크해봐야하는데, 사실 쉬운일은 아니다. 사실 옛날 옛적에는 그림 들어간 버튼을 직접 작성해서 써야 했었다고 한다.


이 댓글을 비밀 댓글로

[안드로이드] Bitmap 과 ByteArray 상호변환

by Blogger 하얀쿠아
2010. 12. 27. 11:00 소프트웨어 Note/Android

Bitmap 과 ByteArray 상호변환


이 포스팅은 Bitmap 데이터 형을 ByteArray로 변환하거나, 혹은 그 역, ByteArray -> Bitmap으로 변환하는 방법을 예제코드와 함께 다룬다.


안드로이드 카메라와 이미지를 다루다보면, 종종 데이터 형(type)이 달라서 형변환을 해야 하는 상황이 발생한다. 

그때 필요한 내용이다.


방법을 간단히 요약하자면 아래 두줄만 보면 된다.

Bitmap -> ByteArray : ByteArrayOutputStream 인스턴스를 생성한 후, Bitmap의 compress 메서드를 통해 비트맵을 압축하여 stream에 담는다.

ByteArray -> Bitmap : BitmapFactory의 decodeByteArray 메서드를 통해 byte Array를 Bitmap으로 변환한다.


Bitmap -> ByteArray 예제코드

안드로이드의 Bitmap은 비트맵 데이터를 stream에 넣어주는 compress 메서드를 제공하고 있다.

public byte[] bitmapToByteArray( Bitmap $bitmap ) {   
     ByteArrayOutputStream stream = new ByteArrayOutputStream() ;   
     $bitmap.compress( CompressFormat.JPEG, 100, stream) ;   
     byte[] byteArray = stream.toByteArray() ;   
     return byteArray ;   
}  

compress 인자는 3개의 값을 받는다.

  1. 압축 옵션( JPEG, PNG ) 
  2. 품질 설정 ( 0 - 100까지의 int형 )
  3. 압축된 바이트배열을 담을 stream

그리고, byteArray는 세번째 인자인 stream의 toByteArray( ) 메서드를 통해 반환받을 수 있다.


ByteArray -> Bitmap 예제코드

다음은 역으로, 바이트 배열로부터 비트맵을 생성하는 예제코드이다.

public Bitmap byteArrayToBitmap( byte[] $byteArray ) {   
    Bitmap bitmap = BitmapFactory.decodeByteArray( $byteArray, 0, $byteArray.length ) ;   
    return bitmap;   
}  

바이트 배열로부터 비트맵 생성은 BitmapFactory의 decodeByteArray( ) 메서드를 통해 간단히 생성할 수 있다.

decodeByteArray( ) 메서드 인자값도 3개이다.

  1. byteArray(바이트 배열)
  2. offset(배열의 시작점)
  3. length(decode할 바이트 배열의 길이)


이 댓글을 비밀 댓글로

[안드로이드] 인터넷에서 이미지 비동기 다운로드

by Blogger 하얀쿠아
2010. 12. 25. 18:27 소프트웨어 Note/Android

안드로이드 인터넷 이미지 비동기 다운로드

보통, 인터넷에서 이미지를 다운로드 하는 코드를 아래와 같이 사용하는 경우가 종종 있었다.
그러나 잘못된 사용방법이라고 한다.


잘못된 사용 예
URL url = new URL(imageUrl);

bitmap = BitmapFactory.decodeStream(url.openStream());


이미지 주소로 URL 객체를 만든 후, BitmapFactory의 decodeStream( )의 인자로써 생성한 URL객체의 openStream( ) 메서드를 호출하고 있다.

그러나, 아래와 같은 방법으로 사용하는 것이 올바른 사용 방법이라고 한다.


올바른 사용 예

HttpGet httpRequest = new HttpGet(URI.create(imageUrl) );
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
InputStream instream = bufHttpEntity.getContent();

bitmap = BitmapFactory.decodeStream(instream);


마지막의 BitmapFactory.decodeStream( ) 메서드 사용은 동일하다.

그러나, 입력하는 parameter가 다름에 주목하자.

이 댓글을 비밀 댓글로

[안드로이드] 증강현실 구현을 위한 기초 개념, 벡터(Vector)와 노름(Norm)

by Blogger 하얀쿠아
2010. 12. 25. 14:34 소프트웨어 Note/Android

증강현실 구현을 위한 기초 개념, 벡터(Vector)와 노름(Norm)




노름(Norm)은 일종의 '벡터의 크기'를 일반화시킨 것이라고 생각하면 쉽다.

선형대수학 및 함수해석학 등의 분야에서 쓰인다. 

선형대수학 및 함수해석학에서는, 노름(영어: norm 놈[*])은 벡터 공간의 원소들에 대하여 일종의 ‘길이’ 또는 ‘크기’를 부여하는 함수 라고 정의한다.

0 벡터의 노름은 0 이며, 그 외의 모든 벡터는 양의 실수 노름을 갖는다.

한편, 반노름(半norm, 영어: seminorm 세미놈[*])이라 하는 개념이 있는데, 이는 영 벡터 이외의 벡터도 노름이 0 이 될 수 있도록 조건을 약화한 것이다. 


노름(Norm)은 다음 조건을 만족시켜야 한다.

 

Lp노름은 다음과 같이 정의된다.

한마디로 말하면, 각 성분들의 절대값의 p제곱들의 합의 p제곱근이다. (당연히 양수임)

 

Max Norm은 로 표기하며, 다음과 같이 정의된다.

즉, 각 성분 중 제일 큰 놈을 잡아온단 뜻이다.

 

Matrix Norm은 다음을 만족시키면 된다.(이때 Matrix Norm은 벡터공간 에서 정의된다. 그리고 A는 에 속한다.)

 


이 댓글을 비밀 댓글로