Skip to main content

6 posts tagged with "android"

View All Tags

· 4 min read

아래와 같은 단순한 구조를 가진 service에서 android app (Phonegap)이 AJAX로 API server와 SSL 통신을 하고 있다. SSL 설정은 reverse proxy 역할을 하는 NginX에 되어 있는 상태였는데 개발단계에서는 나타나지 않았던 문제가 app publish 이후에 발생해서 현상과 해결책을 정리해본다.

android_ssl

 

1. 현상

App에서 API call을 했는데도 오류나 정상 응답이 떨어지지 않는다. API server 쪽에서 로그를 확인해보니 호출된 기록이 없다. 전혀 호출되지 않는다고 판단할 수 있었다. 혹시나 싶어서 NginX의 로그도 확인해봤는데 access 자체를 하지 않는 것으로 보였다. (호출 후 access log, error log 모두 기록되는게 없음)

두번째 이상한 현상은 android app의 manifest에서 debuggable 설정에 따라 API 호출이 되거나 되지 않는다는 사실이었다. debuggable이 true (debug mode)인 경우에는 API 호출에 문제가 없었는데 publish를 위해 packaging 하려고 debuggable을 false로 바꾸면 호출이 불가능했다.

 

2. 조사

Stackoverflow에서 힌트를 찾았는데 자문자답한 사용자의 얘기로는 android app의 debug mode에서는 인증서 확인을 하지 않는데 그렇지 않은 경우 SSL 인증서를 엄격하게 검사한다고 한다. (http://stackoverflow.com/questions/14363994/android-debuggable-false-causing-jquery-ajax-post-to-fail-in-cordova-phonegap-ec) 그래서 링크된 ssl checker로 API service되는 url (NginX가 처음 받는 url)을 검사해봤더니 다른건 문제가 없었는데 인증서 체인이 제대로 되어있지 않았다. Root CA 인증서가 없다는 내용의 메세지와 함께.

 

3. 해결

Startssl에서 인증서를 발급받아 사용하고 있었는데 생각해보니 도메인에 대한 인증서와 그에 맞는 private key는 발급받았는데 startssl(CA)에 대한 인증서는 없었다. Startssl에서 안내하는대로 ca.pem, sub.class1.server.ca.pem을 추가로(내가 사용하는게 startssl의 class1 certificate) 받아서 기존의 인증서를 합쳐 인증서 체인을 만들고 NginX에 설정했다. (https://www.startssl.com/?app=42)

설정 이후에 다시 SSL 검사를 해보니 아래처럼 문제있던 부분이 정상. Android app도 수정없이 제대로 호출되는 걸 확인했다.

ssl_check

 

 

4. 결론

나의 경우엔 CA의 인증서 하나를 누락한 경우지만 개발할 때 self sign된 인증서를 사용하는 경우도 있는데 이 경우에도 publish 할 때에는 반드시 교체해야 한다. 이 부분은 사실 개발할 때 문제가 없었기 때문에 간과하고 넘어가기 쉬운 부분인데 publish 이전에 packaging 해서 한 번 확인은 해봐야 할 것 같다. 아니면 Android developer site에서 발견한 StrictMode class를 이용하는 것도 방법이 될 수 있을 것 같다. (http://developer.android.com/reference/android/os/StrictMode.html)

· 6 min read

개인적인 사정으로 맥북에서 Android full source를 다운받아서 빌드할 일이 생겼다. Google에서 Mac OS X의 경우에 어떻게 다운로드해서 빌드해야 하는지 설명하고 있지만 그대로 진행했을 경우에 문제점들이 몇가지 있어서 그 부분에 대해 정리해볼까 한다.

 

우선 문제점들이 발생하는 이유는 시간이 흘러서 변경사항이 생겼거나 개인의 환경설정 차이에서 기인하는 것으로 보이는데 일단 내 기준으로 환경을 요약하면 아래와 같다.

OS X 10.6.6, JDK 6 (OS에 기본적으로 탑재된 상태), Macports 설치됨.

Download 참조 페이지 : http://source.android.com/source/download.html

 

#1. 첫번째 문제

위의 페이지대로 진행하다보면 terminal에서 아래와 같은 command를 입력해야 하는 부분이 있다.

$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git-core gnupg

 

설치된 macports로 gmake, libsdl, git-core, gnupg를 내려받아 설치하는 command인데 나의 경우엔 libsdl 설치 도중 오류와 함께 중단되는 경우가 발생했다. Command 포함 오류 메세지는 아래와 같음.

 

$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git-core gnupg
--->  Computing dependencies for gmake
--->  Cleaning gmake
--->  Computing dependencies for libsdl
--->  Dependencies to be installed: xorg-libXext xorg-libX11 xorg-libxcb python27 db46 gdbm openssl zlib readline sqlite3 xorg-libpthread-stubs xorg-xcb-proto libxml2 xorg-util-macros xorg-xcmiscproto xorg-xextproto xorg-xf86bigfontproto xorg-xtrans xorg-libXrandr xorg-randrproto xrender xorg-renderproto
--->  Configuring db46
Error: db46 requires the Java for Mac OS X development headers.
Error: Download the Java Developer Package from: <https://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?bundleID=20719>;
Error: Target org.macports.configure returned: missing Java headers
Error: Failed to install db46
Log for db46 is at: /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_ports_databases_db46/main.log
Error: The following dependencies were not installed: xorg-libXext xorg-libX11 xorg-libxcb python27 db46 gdbm openssl zlib readline sqlite3 xorg-libpthread-stubs xorg-xcb-proto libxml2 xorg-util-macros xorg-xcmiscproto xorg-xextproto xorg-xf86bigfontproto xorg-xtrans xorg-libXrandr xorg-randrproto xrender xorg-renderproto
Error: Status 1 encountered during processing.
To report a bug, see <http://guide.macports.org\/#project.tickets>;

 

문제가 되는건 libsdl 설치할 때 dependency를 가진 다른 모듈들을 설치하는데 db46 이란 녀석이 말썽인거다. 왜 이런 일이 생기는 걸까? 위의 오류 메세지 중에 보면 Download the Java Developer Package from: 어쩌구 하는 부분(빨간색)이 있는데 위의 url로 다운받을 때 문제가 생기는 것으로 보인다. 여기저기 찾아보니 아마 apple 내부에서 어떠한 이유로 url을 변경한 것으로 생각되는데 실제로 위의 url을 입력해보면 redirect 되어 다른 페이지로 이동되는걸 확인할 수 있다. macports는 그 작업을 해주지 않는 것으로 생각되기 때문에 당연히 실패로 끝나는거고.

 

해결책은 무척 간단하다. 위의 문제가 되는 url을 직접 입력해 redirect 되는 페이지에 접근해보면 download 할 수 있게 되어있으니 직접 download 하고 설치하면 끝. 그리고 다시 위의 command를 입력해 진행하면 문제없이 모든게 설치된다.

 

#2. 두번째 문제

또 하나 알게된 사실은 Google에서 제공하는 git repository에서 source를 다운받는데 특정 branch가 사라졌다는 거. Source 다운로드를 위한 모든 잡다구레한게 제대로 설치된 상태에서 repo를 만들기 위해 아래와 같은 command를 입력하라고 google에서 친절하게 알려주고 있다.

$ repo init -u git://android.git.kernel.org/platform/manifest.git -b cupcake

 

위의 command는 cupcake branch만 다운로드 하기 위해서 repo를 만드는건데, google의 설명을 보면 mainbranch를 원하면 -b 옵션없이 입력하라고 되어있다. 난 gingerbread 까지는 필요없었고 froyo가 적당하다고 판단했기 때문에 -b froyo라고 입력했는데 이런. 오류가 막 생긴다. 역시 찾아보니 froyo라는 branch를 없앤걸로 보이는데 대신 froyo-plus-aosp 라는 이름의 branch 사용은 가능하다. 역시 -b froyo-plus-aosp 로 입력하면 정상적으로 다운로드 가능. 근데 왜 froyo branch를 없앤걸까??

 

 

참조

1. Failed to install db46 (for git-core) : http://comments.gmane.org/gmane.os.apple.macports.user/22266

2. Failed to get froyo : http://groups.google.com/group/android-porting/browse_thread/thread/1dc55cf079291abc/ab1a9ee55681f95f?show_docid=ab1a9ee55681f95f#

· 6 min read

Android 연구회 과제로 notepad에 몇 가지 기능 추가하기로 했었는데, 내가 맡은 부분은 완료했다. 입력된 메모를 email로 전송하는 간단한 기능인데 책도 보고 여기저기 뒤지면서 android 에서 제공하는 기본적이고 중요한 내용은 어느 정도 익힐 수 있었다. 사실 제공되는 notepad sample 자체가 가지는 몇가지 문제점 때문에 그것부터 개선한 후에 가려고 했으나(예전에 포스팅 했던), 내 능력의 미숙함과 더불어 게으름 때문에 신규 기능만 추가하는 선에서 마무리 하기로 했다.

1. User account

내가 참조했던 어떤 블로그에서 android 가 아직 자체적으로 email 관련 라이브러리를 제공하지 않는다고 봤는데, 예전 버전에서 안되었던건지 그래서 현재는 제공되는 것인지는 확인을 해봐야 하지만 일단 해당 라이브러리를 import 해서 사용했고 덕분에 Gmail 계정 사용자만 이용 가능한 상태. 어쨌든 공부의 목적으로 시작한거니 문제없는 기능구현이 우선이었다. User account 를 입력할 수 있는 activity 를 별도로 구현했으며 sample 의 NoteList activity 에서 intent로 넘겨받은 계정 정보를 처리. SharedPreferences 로 한 번 입력한 내용은 activity 나 application 이 종료되더라도 계정정보를 다시 입력하는 일이 없도록 작성했다.

2. Recipients

User account 정보를 입력한 이후에는 수신인 email 주소를 입력하는 activity를 실행하게 되는데, 필수 항목이므로 한글자도 입력하지 않으면 OK 버튼을 비활성화 상태로 두어 진행 불가능하게 구현했다. (User account 도 마찬가지) 여기까지 필요한 정보를 입력하고 OK 버튼을 누르면 이메일이 전송된다.

3. 결론

Notepad sample의 소스를 들여다보면 application 작성에 필요한 거의 대부분의 내용을 담고 있다는 걸 알 수 있다. Activity 간 data를 주고받는 Intent 의 사용은 물론이고, database, ContentProvider 를 모두 사용해서 구현되어 있기 때문에 이런 필수적인 API 들의 사용방법을 익히기에 딱 적당한 내용인 듯 하다. 추가로 배운 내용들은 아래에 간단히 요약.

Popup dialog

popup 형태의 activity 를 만들기 위한 방법은 여러가지가 있을 수 있는데 가장 간단한 방법은 일단 popup 형태로 만들고자 하는 activity 를 일반적인 activity 처럼 구현한 이후에 AndroidManifest.xml 파일의 해당 activity의 속성에 아래의 항목을 추가하면 끝.

android:theme="@android:style/Theme.Dialog"

Activity 는 호출순서의 가장 마지막에서 시작할 수 있도록 작성할 것.

sample 이 제공하는 것 이외에 별도로 작성한 activity 가 두 개인데 (User account와 recipient 정보 입력하는), 시나리오상 두 개가 연속으로 불려야 할 때도 있고, 따로 불려야 하는 경우도 있다. 두 개의 activity가 연속으로 시작해야 하는 경우 (User account 입력 후 바로 수신인 메일 주소를 입력하는 시나리오)를 위해 처음엔 startActivityForResult 를 연속으로 호출하게 작성했었다. 내 생각엔 하나의 activity 가 활성화되면 입력이 끝나야 main activity 로 넘어가서 다시 두 번째 activity 가 시작될거라고 생각했기 때문이었는데, 실제로 구현해보니 main activity는 두 개의 activity 를 모두 호출하고 그 아래에 있던 디버깅용 구문들까지 모두 순서대로 호출해버리는 사태가 발생했다. 이리저리 머리를 굴려서 적당히 분리해 문제가 없도록 개선은 했는데, 이런 경험하면서 가능한 startActivity나 startActivityForResult 호출한 이후엔 다른 메소드가 호출되는 일이 없도록 작성하는게 좋겠다는 생각을 하게 되었음.

Hint / Toast

EditText 에 data 를 입력하지 않은 상태에서 예시를 보여주는 hint 의 사용법과 Activity 에 짧은 메세지를 보여주기에 적당한 Toast 의 존재를 알았다. 그 중 Toast 는 간단히 구현결과 확인하는데도 아주 좋음.

· 4 min read

내가 가진 책이 너무나 좋은 관계로 책 전반을 구글 혹은 출판사에서 제공하는 샘플을 사용해 설명하고 있지만 해당 샘플을 어떻게 import 하는지에 대한 설명이 없다. IDE를 이클립스로 사용하고 있기 떄문에 제공되는 샘플에 프로젝트 파일만 들어있다면 클릭 몇 번으로 import는 마칠 수 있지만 유감스럽게도 구글에서 제공하는 샘플에는 프로젝트 파일이 들어있지 않다. .classpath도 물론 없다. 프로젝트 생성에 관련된 파일들만 제외하고 샘플 자체에 대한 파일들만 들어있는 셈이다. 처음엔 프로젝트를 새로 만들면서 manifest 파일이나 각종 소스파일과 리소스들을 그냥 복사, 붙여넣기 등을 통해서 해결하려고 해봤는데 그나마 건드려야 하는게 너무 많아서 짜증을 내고 있던 찰나에 이런 생각에 이르게 되었다. '구글에서 과연 이렇게 하라고 해둔걸까?' 역시 그렇지 않다. 제대로 꼼꼼하게 살펴보지 않아서 삽질만 한 셈. 구글에서 제공하는 샘플들을 사용하는 방법은 아래와 같다.

1. 프로젝트 생성

기본적으로 프로젝트 생성을 해보면 위와 같은 pop-up 을 만날 수 있다. 여기서 default로 설정된 항목들을 그대로 두고 필수항목인 프로젝트 이름이나 activity name 등을 채운 후에 Next를 해버리면, 나와 같은 삽질을 해야만 한다. 그래서 천천히 살펴보면 이런 걸 볼 수 있다. Create project from existing sample.

2. Sample 추가

Create project from existing sample 을 선택하면, 바로 위에 선택되어 있던 라디오버튼 항목들은 비활성화가 되고, Build Target 까지 적당히 원하는걸로 선택해주면 해당 platform 아래에 있는 sample 들을 선택할 수 있게 되어있다. (실제로 platform 별로 sample 디렉토리가 별도로 존재한다.) 그래서 맘에 드는 sample 을 골라주기만 하면 끝. 물론 프로젝트 이름 등의 필수항목들은 본인이 직접 채워줘야...

· 4 min read

회사 업무 이외에 연구회 활동을 하고 있다. 다뤄본 사람이 조금 있어서 진입장벽이 나름 낮았던 WM은 이후 프로젝트에 별로 유용하지 않을 듯 하여 안드로이드로 옮겨타게 되어서 짬짬이 준비하고 있다. 덕분에 iphone 에 대한 공부는 좀 더 미뤄질 예정. 시간관계상 갑작스럽게 새로운 무언가를 만들기는 힘들듯 해서 제공되는 sample 중 하나인 notepad 를 응용하기로 했는데, 이리저리 돌려보니 notepad sample 자체의 기능이 조금 부족한 감이 없지 않아 개선작업부터 먼저 할 생각을 하게 되었다. 간단히 메뉴나 작은 기능만 추가하면서 익힐 예정. 아래는 기본 기능에서 개선이 필요한 부분들.

1. 메모 저장 기능

notepad 실행 후 menu 버튼을 눌러 새 메모를 추가하게 되면 간단히 글 입력이 가능하지만, 별도의 저장버튼이 존재하지 않는다. 단지 글 입력 후 되돌아가기 버튼을 누르면 저장이 되는 형태. 별도의 저장 기능이 있는 것 보다 편할 수도 있지만 사람 헷갈린다. 그러므로 저장 메뉴가 필요함. (Delete는 있는데 왜 Save는 없는걸까?)

2. Title과 본문 분리

저장 아닌 저장을 마치고 note list로 빠져나가서 확인해보면 처음에 입력했던 모든 내용이 title로 등록되어 있다. 물론 별도로 title을 수정하면 title만 변경되고 실제 내용엔 변화가 없다. 이걸 보면 입력한 내용과 동일한 data를 title에도 복사하고 저장은 별도로 하고 있음을 유추해 볼 수 있다. 개선이 필요하다. 새 메모 입력시 Title과 본문을 분리해 두어야 하고, 본문 입력시 제한적인 화면크기를 생각해서 title은 숨겨야 한다. 물론 저장시 숨겨두었던 title은 다시 꺼내서 보여주어야 함.

3. Menu list에서의 Delete 기능

Note list에서 메모 하나를 선택 후 메뉴 버튼을 눌러보면 Add Note, Edit Note, Edit Title 세 가지의 메뉴만 나타난다. 물론 메모를 선택해 롱키를 누르면 context menu에 Delete가 보이지만 별도의 메뉴로 존재해야 한다. Edit이 있는데 Delete가 없다는건 말이 안되니까.