국내에서는 이클립스를 주로 사용하지만 구글이 Android Studio 기반에 Gradle 사용을 통한 플러그인 관리 등을 권장하고 있다.


지난 달에 아마존에서 구입한 파이어폰을 이클립스에 물려보니 DDMS에서는 폰 자체는 인식하는데, 빌드할 때 폰이 보이지 않아서 좀 찾아보니 얘네도 이클립스보다는 이런 환경을 설정해서 사용하길 권한다. 


https://developer.amazon.com/public/resources/development-tools/ide-tools/tech-docs/01-setting-up-your-development-environment#Using%20the%20Eclipse%20IDE


아마존 XML 리소스를 읽지 못하는 거라고 하는데, 일단 가이드에 따라서 ADB를 실행 후에 User Define Site에 해당 주소를 추가하여 파이어폰 SDK와 EXTRA에서 필요한 파일들을 모두 설치했다.


https://developer.amazon.com/public/solutions/devices/fire-phone/docs/connecting-your-device


흠...아무튼...

아침에 일어나면서 시작되는 하루의 일과는 언제나 바쁘다.


살아온 시간은 적다면 적고, 움직였던 영역도 제한적이지만 

그간의 경험은 '실제로 바쁜 일은 그다지 없어' 라고 말한다.


바쁜 일도 없고, 느릿느릿하기만 한 하루의 연속.


하지만 시간은 잘 흐른다.


그저 잘 흐른다.


순간은 너무 길지만 과거를 돌아보면 너무 빠르게 잘 흐른다.


하루 이틀, 일 년 이 년, 십 년 이십 년이 지나면서

지금을 인지하는 것이 얼마나 힘든 일인지 알게 되었다.


지금 해야 할 일과 하지 말아야 할 일들이 있다는 것도 알게 되었다.


상상과 공상 만큼 지금의 나를 망각하게 하는 것도 없다는 것을 알게 되었다.


적절한 공상은 일상의 지겨움과 공포를 털어내주곤 한다.


아무 것도 하지 않아도 

가만히 있어도 지금의 나는 꽤나 바쁘다.


오늘의 일상이 어제와 다르지 않은데

자꾸만 나는 바빠진다.



일상의 반복이 지겨워져 이리저리 도망칠 구멍을 찾고

멈춰있는 듯한 이 기다란 순간에도

나는 무척 바쁘다.


아침에 분명 느릿하게 일어났는데

아무런 일도 없이 종일 내내 바빴고

이내 잠자리에 들어야한다는 사실이 

때로는 분하기도 하다.


왜 오늘은 이렇게 바빴던 것일까?

잠들기 전에 궁금함이 생겨 속다짐을 해본다.


내일은 바쁘지 않겠다!


제이슨킷을 포함해서 Xcode 4.4 이상에서 컴파일하면 다음과 같은 경고들이 뜬다.


1. Format specified type 'unsigned long' but the argument has type 'NSUInteger' (aka 'unsigned int')


http://stackoverflow.com/questions/4998722/why-does-only-nslog-warn-me-about-using-the-lu-string-format-specifier-for-nsui



2. Direct access to objective-c's isa is deprecated in favor of object_setClass() and object_getClass()


http://stackoverflow.com/questions/11735460/multiple-format-string-issue-warnings-in-jsonkit-m-after-upgrading-to-phonegap



대충 읽어보니...현재 버전에서 문제는 없지만 노란 경고가 줄줄이 뜨니 기분이 영 마뜩찮다.


추가한 광고 패키지에 들어있는 제이슨킷 메서드 관련된 부분인데, 직접 수정해도 되지만 요거 수정해달라고 해야 할 듯...


아무튼 해결책은 다음과 같다.


https://issues.apache.org/jira/browse/CB-1164



[GADBannerView private]: unrecognized selector sent to instance 0x9159e50 2012-08-20 


애드몹 새로운 SDK 연결했더니 이런 에러 뜨면서 앱이 죽는다...메모리 참조 문제로...


검색해보니...다음과 같은 해답이 있다. 으...음...


https://developers.google.com/mobile-ads-sdk/docs/#incorporating


ㅋㅋㅋ...SDK 다운로드 페이지 옆에 안내문 써있네...문서에도 적혀있고.

하아~ 안드로이드는 적응이 잘 안된다.

안되는 것 없이 다 되기는 하는데...이러나 저러나 적응이 안돼. -_-;;


아이폰에서는 뭐...탭 메뉴나 테이블 등과 같이 데이터를 순차적으로 나열하여 보여주고 네비게이션하기 쉽게 되어 있는데...안드로이드를 처음 접하는 입장에서 이것 참 쉽지 않다.


데모 형태의 앱을 만들면서 첫 목표는 DB(SQlite)의 활용, 탭 메뉴 생성, 메뉴 내에서의 네비게이션 등을 익히는 일이다. 


아무튼, 탭 메뉴를 만드는 방법은 몇 가지가 있다.



1. TabActivity를 사용하는 방법

deprecated 됐다고 한다. 하지만 아직 사용은 가능하다. 또 하지만 대부분의 사람들이 이걸 사용하는 것보다 다른 것을 권장한다. 그 이유는 꽤나 많다.


예제 - http://www.androidhive.info/2011/08/android-tab-layout-tutorial/


하나의 탭 내에서 액티비티간 이동(세부 내용 보기 등)을 위해서는 ActivityGroup을 이용한다.

하지만 이것도 deprecated 되어 있는 상태. ㅋㅋㅋ


예제 - http://richipal.com/post/2624844577


요거는 한 번 해봤는데...이전 액티비티로 안돌아오고 그냥 종료되네...ㅋㅋㅋ 뭔가 실수한 듯.

다시 한 번 확인해봐야할 지...FragmentActivity를 사용할 지...더 나은 무료 공개 소스를 이용할 지 생각 좀 해봐야 할 듯.


2. FragmentActivity 사용하는 방법

3.0 이후로 TabActivity 사용이 deprecated 되어 있어서 권장하는 방식이다.

코드가 좀 늘어 났다.


예제 - http://android.codeandmagic.org/2011/07/android-tabs-with-fragments/



3. Custom Tab Menu 만들기

실무 작업자들이 권하는 방식은 이미지뷰나 버튼을 활용해서 커스텀 탭 메뉴를 만드는 방식이다.

이미지는 나인 패치를 이용해서 만들면 괜찮을 것 같다.


http://www.androidside.com/bbs/board.php?bo_table=B49&wr_id=81870

http://darphin.tistory.com/22


이미지 리소스를 조금이라도 줄여볼까 하는 생각으로 배경 이미지를 패턴으로 깔아주는 것에 대해서 좀 알아 보았다.


아이폰에서는 쉽게 아래와 같이 하면 패턴이 적용된다.


1:    [self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg_pattern.png"]]];  


안드로이드에서는 어떻게 하는 지 좀 알아봤다.


1. xml을 이용한 배경 이미지 패턴 설정

xml을 이용하는 방법은 일반 레이아웃 사용할 때 활용하면 될 듯하다.

적용한는 방법은 간단하다.


1) Drawable 폴더에 비트맵 xml  파일을 만든다. (background_pattern.xml로 만든다)

타일 이미지 리소스를 지정하고 tileMode를 "repeat"로 하면 된다. (titleMode에는 clamp, micro, repeat 가 있다)

1:  <?xml version="1.0" encoding="utf-8"?>  
2:  <bitmap xmlns:android="http://schemas.android.com/apk/res/android"  
3:    android:src="@drawable/bg_pattern"   
4:    android:tileMode="repeat" />  


2) 해당 xml을 패턴을 설정할 레이아웃의 background로 지정하면 된다.

1:  <?xml version="1.0" encoding="utf-8"?>  
2:  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
3:    android:id="@+id/MainLayout"  
4:    android:layout_width="fill_parent"  
5:    android:layout_height="fill_parent"  
6:    android:orientation="vertical"  
7:    android:background="@drawable/background_pattern">  
8:  </LinearLayout>  




2. 코드로 배경 이미지 패턴 설정

1:  BitmapDrawable bg;  
2:  bg = new BitmapDrawable(BitmapFactory.decodeResource(getResources(),R.drawable.bg_pattern));  
3:  bg.setBounds(0, 0, getWidth(), getHeight());  
4:  bg.setTileModeX(Shader.TileMode.REPEAT);  
5:  bg.draw(canvas);  

코드로도 간단하게 배경을 채울 수 있다.

드로우하는 코드 안에서 BitmapDrawable을 하나 생성해서 리소스를 읽고, 해당 리소스를 전체 화면의 영역을 얻어와서 해당 영역에 타일 반복으로 캔버스에 그려주면 된다.


안드로이드나 자바나 거의 하나도 모르는 상태에서 하나 하나 찾아보고 있다.


SQLite  파일을 미리 생성해서 앱 패키지에 추가하고 싶은데, 책을 찾아보니 그런 내용들은 나와 있는 것이 별로 없다. 대부분 앱 실행 시 생성하고 추가, 검색, 삭제 등에 대한 부분을 다루고 있다.


그래서 일반적인 sqlite 사용법을 다룬 글들을 모두 제외하고, 

검색을 통해서 관련된 괜찮은 글들을 몇 개 추려 봤다.



1. apk에 sqlite 파일을 넣어서 사용하기

http://stackoverflow.com/questions/513084/how-to-ship-an-android-application-with-a-database

http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/



2. 대용량 sqlite 파일을 잘라서 사용하기

http://www.chriskopec.com/blog/2010/mar/13/deploying-android-apps-with-large-databases/


작성자 글을 보면 1메가 이상의 raw 파일의 경우 안드로이드에서 제한을 걸고 있는 것 같다. 그래서 1메가 이상의 파일은 잘라서 사용해보니 잘 되더라라는 글이다.


2012.08.13 추가

좀 더 검색을 해보니...asset 폴더에 확장자를 일반 리소스처럼해서 집어 넣고, 데이터베이스를 읽어서 data/data 폴더에 저장할 때 .sqlite 확장자를 붙이면 된다고 한다.


http://dhna.tistory.com/185


자세한 것은 위의 블로그로...


일단 데이터베이스를 담고 서비스를 하는 것과 사용자가 데이터베이스를 생성해서 사용하게 하는 것 가운데 후자가 바람직하고 그 권한이 사용자에게 있으므로 좋을 것 같기는 하지만, 그렇지 않은 서비스도 있으니 이것이 문제.


아무튼, 그러하다...이제 테스트해봐야겠당.


웹에서 데이터베이스를 다운로드 받아서 SD카드에 저장하게 할 수도 있을 것 같지만 일단은 별도의 네트워크 연결 없이도 사용할 수 있도록 하려면 위의 방법을 사용해야 할 듯.



구글 메일을 사용하면서 오탈자 수정해주는 기능이 있어서 영문 메일 쓸 때 유용하게 써먹고 있다.


대충 메일을 써도 단어를 수정해주니 정확한 철자를 몰라도 된다.

(자주 사용하지 않는 단어도 사전을 검색할 필요가 거의 없다)


오늘은 또 놀란게...메일 작성 시 작성한 글의 문맥을 읽는다는 점이다.


예를 들면, '첨부된 파일도 잘 보았습니다.' 라고 문장을 쓰고 보내기를 클릭하니...


팝업이 뜨면서 '첨부된 파일이라고 작성하셨으나 본 메일에 첨부된 파일이 없습니다. 이대로 보내시겠습니까?'라고 물어보는 것이 아닌가?


물론 스크립트로 처리하겠지만 이런 세심함까지 있다니...놀라울 따름.



갑자기 메일 이야기하니까 생각나는데...

한 오륙년 전에 네이버 메일을 사용하다가 불편해서 운영자에게 메일을 보낸 적이 있다.


당시에 네이버 메일의 폴더 관리가 10개 제한이 있었던 것 같은데...받은 메일을 개별 폴더로 분류하여 자동으로 수령하게 하는 데 불편했다.


다음이나 구글 등은 그런 제약이 없었는데...폴더 생성이 10개까지로 제한이 되어 있어서 조금 불편했던 것 같다.


메일을 보내고 회신도 받고 한 뒤 한 일이년 후에 폴더 생성 제한 갯수가 변경된 것 같다.



아무튼, 사용자 입장에서 작은 부분이 큰 차이로 느껴지고 꽤나 놀라운 기능처럼 느껴지기도 한다.


UX/UI 라는 것도 어쩌면 이런 측면에서의 접근이 아닐까 생각된다.


https://developer.apple.com/icloud/documentation/data-storage/


오늘 리젝을 하나 당했는데...사유가 '사용자가 생성한 데이터가 아닌 파일은 도큐멘트 디렉토리에 저장하면 안되용~' 이네.


당신이 사용자의 Document Directory에 2메가 이상의 파일들을 저장하고 있으니 위의 가이드를 잘 살펴보라고 한다.


iCloud가 나오면서 체크해야 할 부분이 몇 가지가 있는데, 데이터 저장과 관련한 몇 가지 부분을 수정해주어야 한다.

예전의 클라우드 서비스가 없을 시절에는 그다지 체크하지 않던 부분이었지만 글을 읽어보니 그 말도 맞다.


아무튼 수정해서 다시 올리면서 관련 사항을 한 번 정리해본다.


아이폰 개별 앱의 샌드박스 내에는 일반적으로 저장 공간이 세 부분으로 나뉘어진다.



1. 아이폰의 세 가지 저장 공간


1) Documents Directory:  <Application_Home>/Documents

이 디렉토리는 마치 영구 저장소같이 사용할 수 있고, 아이클라우드 백업 시 자동으로 백업이 함께 된다.

보통은 사용자가 앱을 사용하면서 필요한 내용을 저장하거나 사용자가 생성한 데이터를 저장하게 된다.


2) Library내의 Caches Directory: <Application_Home>/Library/Caches

이 디렉토리는 사용자가 선별(아이템 구매 또는 잡지 구매 같이)적으로 저장할 수 있고, 클라우드 백업 역시 선별적으로 가능하다.

보통은 추가 구매 콘텐츠나 웹 등에서 임시적으로 이미지, 동영상, pdf 등의 파일을 저장하기도 하고 기간을 두고 해제하기도 한다.


3) tmp Directory: <Application_Home>/tmp

이 디렉토리는 일시적으로 사용하게 되는 곳으로,  클라우드 백업과는 무관한 폴더다.

잠시 보여주기 위해서 저장한 파일이나 일회성으로 소비되는 리소스를 제공한다.



그냥 끝내면 재미없으니까...유익하지도 않고, 사용법을 간략하게 적어본다.

아래의 예제는 화면 스샷을 만들어서 해당 스크린샷을 각각의 폴더에 저장해본 예제임. (파일 저장 및 읽기 부분만)



2. 활용하기


1) Documents Directory:  

도큐멘트디렉토리를 지정하여 저장하려는 파일명을 패스에 추가한 뒤에 데이터를 그 지정한 패스로 저장하면 된다.


1) 쓰기

    NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString * documentsDirectory = [paths objectAtIndex:0];
    NSString * filePath = [documentsDirectory stringByAppendingPathComponent:@"screenshot.png"];
    UIImage * image = [self screenshot];
    NSData * imageData = UIImagePNGRepresentation(image);
    [imageData writeToFile:filePath atomically:NO];


2) 읽기

     NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString * documentsDirectory = [paths objectAtIndex:0]; NSString * path = [documentsDirectory stringByAppendingPathComponent:@"screenshot.png"]; NSData * imageData = [NSData dataWithContentsOfFile:path];



2) Library내의 Caches Directory: 

캐쉬디렉토리를 지정하면된다. 사용법은 동일하니 참고.


1) 쓰기

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString * cachesDirectory = [paths objectAtIndex:0];
    NSString * filePath = [cachesDirectory stringByAppendingPathComponent:@"screenshot.png"];
    UIImage * image = [self screenshot];
    NSData * imageData = UIImagePNGRepresentation(image);
    [imageData writeToFile:filePath atomically:NO];


2) 읽기 

   NSArray * paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
   NSString * documentsDirectory = [paths objectAtIndex:0];
   NSString * path = [documentsDirectory stringByAppendingPathComponent:@"screenshot.png"];
   NSData * imageData = [NSData dataWithContentsOfFile:path];



3) tmp Directory: <Application_Home>/tmp

템프 디렉토리에 사용하는 법은 조금 다르지만 아주 간단하다.


1) 쓰기

    NSString * tempFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"screenshot.png"];
    UIImage * image = [self screenshot];
    NSData * imageData = UIImagePNGRepresentation(image);
    [imageData writeToFile:tempFilePath atomically:NO];


2) 읽기

NSString * tempFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"screenshot.png"];
        NSData * imageData = [NSData dataWithContentsOfFile:tempFilePath];


아무튼 해당 내용을 잘 파악해서 목적에 맞게 저장하고 읽어야지...리젝을 안 당함...-_-;;


아참...파일이 잘 저장되었나 확인하는 방법은 시뮬레이터의 앱 안의 각각의 폴더를 확인하면 된다. 단지 템프 폴더의 경우에는 시뮬레이터 작동 시에는 해당 폴더에 저장이 안된다. 단말로 체크.



오늘 카메라킷이 사무실로 배송와서 korg 미디키보드를 아이패드2에 연결해봄...

연결해서 잠시 가지고 놀다보니...일렉 기타 사고 싶어짐...-_-;;

음...

 

재미있었다...-_-; 

+ Recent posts