MJAndroid, [INSTALL_FAILED_MISSING_SHARED_LIBRARY] By Vins

오렐리 책을 실습하다가 보면서 MJAndroid의 설치에서
[INSTALL_FAILED_MISSING_SHARED_LIBRARY] 가 발생했다

이전 HelloAndroid와 무엇이 다른지 생각해 보다가 구글맵을 사용하는 것이
문제라는 것을 발견했다

우선 MJAndroid를 패키지 익스플로러를 살펴보면 MapKey를 넣는 곳이 있는데

먼저 android용 api key를 받아야 한다 아래주소로 이동하면

Sign Up for the Android Maps Key Api 라며 박스안에 녹색 글자들이 나오는데

$ keytool -list -keystore ~/.android/debug.keystore
...
Certificate fingerprint (MD5): 94:1E:43:49:87:73:BB:E6:A6:88:D7:20:F1:8E:B5:98



<-- 인증키 발급하는 부분은 내용상 따로 준비하였습니다.
아직 인증키 발급안 하신분은 이쪽으로 새탭으로 바로 아래 링크 부터 
하여 MD5키를 생성하시고 다음으로 이동하시기 바랍니다.
http://mcpicdtl.blogspot.com/2010/01/api-key.html 


------------ API Key URL ----------------
http://code.google.com/intl/kr/android/maps-api-signup.html


다시 본론으로 돌아가서
이클립스를 사용하여 AVD를 생성하였다면
MJAndroid 경우는 구글 맵을 사용하는 App이기 때문에 Android+google map을 선택해야 한다
이클립스에서는 아마 Google APIs 각 버젼으로 나올것이다
그래서 /android-sdk-window/tools 폴더에 있는 android.bat 를 사용해서 가상머신을 돌리기로 했다

근데 자기 PC에 설치된 것들이 뭐뭐가 있는지 잘 모를수 있으니 먼저
어떤 것들이 있는지 보자

cmd 창을 하나 열어 아래와 같이 tools 폴더로 이동한 후 실행 시켜보자

C:\vinsPrivate\Android\android-sdk-windows\tools> android list targets

그러고 나면 아래 안드로이드 종류가 10~20가지 정도 나올것이다

---------------------- 출력 결과 -----------------------------------------------------
Available Android targets:
id: 1 or "android-2"
Name: Android 1.1
Type: Platform
API level: 2
Revision: 1
Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
id: 2 or "android-3"
Name: Android 1.5
Type: Platform
API level: 3
Revision: 1
Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
id: 3 or "android-4"
Name: Android 1.6
Type: Platform
API level: 4
Revision: 1
Skins: HVGA (default), QVGA, WVGA800, WVGA854
id: 4 or "android-5"
Name: Android 2.0
Type: Platform
API level: 5
Revision: 1
Skins: HVGA (default), QVGA, WQVGA400, WQVGA432, WVGA800, WVGA854
id: 5 or "android-6"
Name: Android 2.0.1
Type: Platform
API level: 6
Revision: 1
Skins: HVGA (default), QVGA, WQVGA400, WQVGA432, WVGA800, WVGA854
id: 6 or "android-7"
Name: Android 2.1
Type: Platform
API level: 7
Revision: 1
Skins: HVGA (default), QVGA, WQVGA400, WQVGA432, WVGA800, WVGA854
id: 7 or "Google Inc.:Google APIs:3"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 3
Description: Android + Google APIs
Based on Android 1.5 (API level 3)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: QVGA-P, HVGA-L, HVGA (default), QVGA-L, HVGA-P
id: 8 or "Google Inc.:Google APIs:3"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 3
Description: Android + Google APIs
Based on Android 1.5 (API level 3)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: QVGA-P, HVGA-L, HVGA (default), QVGA-L, HVGA-P
id: 9 or "Google Inc.:Google APIs:3"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 3
Description: Android + Google APIs
Based on Android 1.5 (API level 3)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: QVGA-P, HVGA-L, HVGA (default), QVGA-L, HVGA-P
id: 10 or "Google Inc.:Google APIs:4"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 2
Description: Android + Google APIs
Based on Android 1.6 (API level 4)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: WVGA854, HVGA (default), WVGA800, QVGA
id: 11 or "Google Inc.:Google APIs:4"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 2
Description: Android + Google APIs
Based on Android 1.6 (API level 4)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: WVGA854, HVGA (default), WVGA800, QVGA
id: 12 or "Google Inc.:Google APIs:4"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 2
Description: Android + Google APIs
Based on Android 1.6 (API level 4)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: WVGA854, HVGA (default), WVGA800, QVGA
id: 13 or "Google Inc.:Google APIs:5"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 1
Description: Android + Google APIs
Based on Android 2.0 (API level 5)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: WVGA854, WQVGA400, HVGA (default), WQVGA432, WVGA800, QVGA
id: 14 or "Google Inc.:Google APIs:5"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 1
Description: Android + Google APIs
Based on Android 2.0 (API level 5)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: WVGA854, WQVGA400, HVGA (default), WQVGA432, WVGA800, QVGA
id: 15 or "Google Inc.:Google APIs:5"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 1
Description: Android + Google APIs
Based on Android 2.0 (API level 5)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: WVGA854, WQVGA400, HVGA (default), WQVGA432, WVGA800, QVGA
id: 16 or "Google Inc.:Google APIs:6"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 1
Description: Android + Google APIs
Based on Android 2.0.1 (API level 6)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: WVGA854, WQVGA400, HVGA (default), WQVGA432, WVGA800, QVGA
id: 17 or "Google Inc.:Google APIs:6"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 1
Description: Android + Google APIs
Based on Android 2.0.1 (API level 6)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: WVGA854, WQVGA400, HVGA (default), WQVGA432, WVGA800, QVGA
id: 18 or "Google Inc.:Google APIs:6"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 1
Description: Android + Google APIs
Based on Android 2.0.1 (API level 6)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: WVGA854, WQVGA400, HVGA (default), WQVGA432, WVGA800, QVGA
id: 19 or "Google Inc.:Google APIs:7"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 1
Description: Android + Google APIs
Based on Android 2.1 (API level 7)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: WVGA854, WQVGA400, HVGA (default), WQVGA432, WVGA800, QVGA
id: 20 or "Google Inc.:Google APIs:7"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 1
Description: Android + Google APIs
Based on Android 2.1 (API level 7)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: WVGA854, WQVGA400, HVGA (default), WQVGA432, WVGA800, QVGA
id: 21 or "Google Inc.:Google APIs:7"
Name: Google APIs
Type: Add-On
Vendor: Google Inc.
Revision: 1
Description: Android + Google APIs
Based on Android 2.1 (API level 7)
Libraries:
* com.google.android.maps (maps.jar)
API for Google Maps
Skins: WVGA854, WQVGA400, HVGA (default), WQVGA432, WVGA800, QVGA

C:\vinsPrivate\Android\UTIL\android-sdk\tools>
-------------------- 출력 결과 끝 -------------------------------

내 경우엔 위 출력 결과에서 파란색 처리 된 부분..
즉 android 2.1(현재최신버젼) + google Apis 를 사용할 것이었기 때문에
ID : 21 인 AVD를 사용할 것이다
(사용자 PC마다 원하는 번호가 다를수 있기 때문에 확인하고 타켓 번호를 사용하자)

자 그럼 AVD를 실행시켜 보자

cmd.exe 창으로 돌아가서
C:\vinsPrivate\Android\UTIL\android-sdk\tools> android create avd -n vinsAndroid-2.1 -t 21 -c 1000M

위에 보면 -n 과 -t 가 있는데 이의 상세한 설명은
http://developer.android.com/guide/developing/tools/avd.html

공식 웹 사이트를 참조하면 된다
뭐 지금은 -n (avd 이름 : 맘대로 정하면 됨)과 -t (타켓번호) 만 알아도 된다
내 경우엔 AVD이름을 vinsAndroid-.2.1 로 하였지만 이건 자기가 원하는 이름으로 하면 된다

단 MJAndroid와 같이 데이터를 저장하고 또 불러와야 하는 경우는
sdcard를 인식시켜 줘야 함으로 이미지가 없다면 -c 옵션으로 sdcard이미지를 생성하든지
이미 sdcard 이미지를 만들었거나 만들어진 파일이 있다면 이를 인식시켜 주도록 한다
위에선 새로 만들는 방법을 사용하였는데 어떤 차이가 있는지 설명하면 다음과 같다

android create avd -n vinsAndroid-2.1 -t 21 -c 1000M (1기가 sdcard를 자동으로 생성하였을 경우)

간단하게 정의 내리자면 AVD가 SDcard를 포함한 채로 실행되는 경우를 말한다
예를 들어
android create avd -n vinsAndroid-2.1 -t 21 -c 1000M
위 구문을 실행시켜 AVD를 생성하였다면

C:\Documents and Settings\vins\.android\avd\vinsAndroidinSDcard-2.1.avd 폴더 내부는 아래와 같다
2010/01/28 16:07 <DIR> .
2010/01/28 16:07 <DIR> ..
2010/01/28 15:51 16,860 cache.img
2010/01/28 14:54 189 config.ini
2010/01/28 16:07 54 emulator-user.ini
2010/01/28 16:07 1000,485,760 sdcard.img
2010/01/28 16:07 44,996,124 userdata-qemu.img
2010/01/28 14:54 2,401,344 userdata.img

즉 1기가짜리 sdcard.img 이라는 것이 여기에 생성되고 AVD에 의해서 관리가 된다
즉 한가지 유의 해야 할 점은 외부 sdcard이기 때문 쓰기, 읽기 등의 권한을 가지고 있어야 한다
AndroidManifest.xml 의 Permission tab을 클릭하고 추가적으로 권한을 주도록 해야 한다
추가해야 할 권한은 "android.permission.WRITE_EXTERNAL_STORAGE" 을 줘야 한다
해석하면 외부 저장장치에 쓰기 권한을 달라는 말이 된다

user-permission 이 한줄 더 추가 되게 된다
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
---------------------------------------------------------------------------------------------------------
android create avd -n vinsAndroid-2.1 -t 21 -c c:\vinsPrivate\android\workspace\MJAndroid\sdcard (이미 만들어진 sdcard 이미지를 이용할 경우)

내부 sdcard 이미지의 경우는 프로젝트에 종속되어져서 AVD에서 실행시
해당 경로를 참조하게 된다
MJAndroid의 경우엔
C:\vinsPrivate\Android\workspace\MJAndroid\sdcard 가 될 것이다
AVD에서 MJAndroid를 실행시켜보고 해당 MJAndroid 폴더 이름을 바꾸려고 하면
사용중인 리소스가 있어서 디렉토리 명을 변경 할 수 없다고 나온다

---------------------------------------------------------------------------------------------------------





즉 프로젝트를 실행하는데 sdcard 이미지가 프로젝트 폴더 내부에 있는 것은 그리 권장할 만하지 못한것 같다
배포파일의 크기만 커질뿐이며 유지관리에는 자동으로 AVD가 생성하도록 하는 것이
좋을 것 같다

자 실행후 몇줄 더 읽는 동안 AVD가 회면에 떠 있을 것이다
이클립스에서 그냥 안드로이드만 실행했을때와 달라진 점은 메인 화면에 구글맵 아이콘이
하나 더 생겼다는 점이다

그리고 Menu위에 어플리케이션 리스트를 출력 버튼을 클릭해 보면
"MicroJobs"라는 어플리케이션이 설치되어 있을 것이다

이번에 안드로이드를 새로이 입문하면서 느낀것이지만
자바, 리눅스, Struts 등 오픈진형의 소스는 환경 설정 및 Docs를 철저히 파악하지 못하면
삽질에 시간을 많이 보낼수 있다는 점이다

최근 OpenPNE라는 일본 오픈SNS로 프로젝트를 하고 있는데
이 역시도 설정을 맞추는데 3일이나 잡아 먹었다 (나중에 그 버젼이 beta라는 것을 알게 되었지만 ㅜ.ㅜ)

by Vins

ps. 아 오렐리 책에서 보면 $ adb install mjandroid-1.0.0.apk 부분은 신경 쓸 필요 없다
전부 빌드 하고 나면 /bin 폴더안에 MJAndroid.apk 가 생기는데 버전관리의 중요성을
언급하기 위한 변형일 뿐이다.
버젼관리는 AndroidManifest.xml 파일에 서 Manifest탭을 클릭하면
android:version을 설정할 수 있고 version code는 1, version name 1.0 이 된다
사용사가 보게되는 version 숫자는 version name이 되겠다

혹시 설치까지는 성공하였으나 실행시
에라가 뜨는 분들은 Google Maps 부분에서 실수를 하였을 가능성이 높다
만일 MJAndroid가 아니더라도 구글맵에서 계속해서 에러가 발생한다면
다음 링크를 꼭 클릭해서 내용을 살펴보도록 하자

아마도 컴파일을 버젼을 Android 1.x or 2.x 등 단순 안드로이드를 사용했을 가능성이 높고
http://mcpicdtl.blogspot.com/2010/01/mjandroid.html  <-- 여기에서 모든것을 해결 할 수 있을 것이다