'강좌'에 해당되는 글 3건

  1. 2010.09.03 [강좌A13] 안드로이드 실전 개발 - Hangul2English 최종소스 공개 (한글 자모 분리, Manifest) (6)
  2. 2010.08.20 [강좌A07] 안드로이드 실전 개발 - 리소스 해킹 (10)
  3. 2010.08.04 [강좌A03] Android 실전 개발 - 아이디어 / 기획 / Wireframe (6)
2010.09.03 15:02

[강좌A13] 안드로이드 실전 개발 - Hangul2English 최종소스 공개 (한글 자모 분리, Manifest)




차주쯤 강좌를 쓸려고 했는데, 오늘 일이 한가한 바람에 시간이 남아서 마지막 소스 부분을 마무리 할까 합니다.
오늘의 강좌는 소스코드의 마지막 부분인 한타 -> 영타 변환 소스 부분과 메니페스트 부분에 대해서 설명하겠습니다. 오늘 강좌가 끝나면 전체 소스코드가 다 오픈되는 군요.

전체 강좌 목차

[강좌A01] Moteodev Studio를 이용한 안드로이드 개발 환경 구축 가이드
[강좌A02] 안드로이드 개발 참고 서적 소개
[강좌A03] Android 실전 개발 - 아이디어 / 기획 / Wireframe
[강좌A04] 안드로이드 실전 개발 - 아이콘 제작
[강좌A05] 안드로이드 실전 개발 - 레이아웃 및 리소스 : Part1
[강좌A06] 안드로이드 실전 개발 - 레이아웃 및 리소스 : Part2
[강좌A07] 안드로이드 실전 개발 - 리소스 해킹
[강좌A08] 안드로이드 실전 개발 - SQLite

[강좌A09] 안드로이드  실전 개발 - 데이터베이스 : Part1
[강좌A10] 안드로이드  실전 개발 - 데이터베이스 : Part2
[강좌A11] 안드로이드  실전 개발 - 데이터베이서 : Part3 (Motodev database)
[강좌A12] 안드로이드  실전 개발 - Main UI 소스, ListAdapter
[강좌A13] 안드로이드  실전 개발 - Hangul2English 최종 소스 공개 (한글 자모 분리, Manifest)


먼저, 한타를 영타로 변환하는 부분입니다.
저는 앞선 강좌에서 onTextChanged 이벤트를 잡아서 한글을 영문으로 변환 하도록 구성했습니다. 한글을 영문으로 변환하기 위해서는 여러 방법이 있겠지만, 저는 한글을 자소(초성/중성/종성) 분리하여 각 글자에 해당되는 영문을 찾아서 변환해 주는 방식을 사용했습니다.

먼저, 한글 자소 분리에 대한 기본 이론을 살펴보도록 하겠습니다. 이 이론을 잘 이해하시면 초성검색 구현도 별 어려움 없이 처리할 수 있습니다. 자소 분리나 초성검색은 이미 많으신 분들이 웹사이트에 구현코드를 많이 올려 놓으셨기 때문에 별도로 언급하지 않을까 하다가, 정리하는 차원에서 함께 설명합니다.

한글 유니코드 자소(초성,중성,종성) 분리 원리.

www.unicode.org/charts 에 들어가시면 East Asian Scripts 하위의 Hangul syllables 를 클릭하시면 한글 완성형 유니코드가 나옵니다. 첫번째 “가”는 유니코드가 0xAC00 이군요. 한글 완성형 코드는 0xAC00 ~ 0xD7A3까지의 코드 범위에 존재합니다.

유니코드에서 한글은 초성 19개, 중성 21개, 종성 28개의 모든 경우의 수에 따라 조합순으로 코드가 배열되어 있습니다.

초성  "ㄱ", "ㄲ", "ㄴ", "ㄷ", "ㄸ", "ㄹ", "ㅁ", "ㅂ", "ㅃ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅉ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ"

중성  "ㅏ", "ㅐ", "ㅑ", "ㅒ", "ㅓ", "ㅔ", "ㅕ", "ㅖ", "ㅗ", "ㅘ", "ㅙ", "ㅚ", "ㅛ", "ㅜ", "ㅝ", "ㅞ", "ㅟ", "ㅠ", "ㅡ", "ㅢ", "ㅣ"

종성  "", "ㄱ", "ㄲ", "ㄳ", "ㄴ", "ㄵ", "ㄶ", "ㄷ", "ㄹ", "ㄺ", "ㄻ", "ㄼ", "ㄽ", "ㄾ", "ㄿ", "ㅀ", "ㅁ", "ㅂ", "ㅄ", "ㅅ", "ㅆ", "ㅇ", "ㅈ", "ㅊ", "ㅋ", "ㅌ", "ㅍ", "ㅎ"

한글 유니코드를 초성,중성,종성으로 분리해 보면 다음과 같은 산식이 나옵니다.

0xAC00 + ( 초성순서 * 21 * 28 ) + ( 중성순서 * 28 ) + 종성순서 = 한글유니코드값.

다르게 표현하면

0xAC00 + ( ( 초성순서 * 21) + 중성순서 ) * 28 + 종성순서 = 한글유니코드값.

유니코드 표를 보시면 한글 “가”는 0xAC00 입니다. 즉, (초성 0번째 + 중성 0번째 + 종성 0번째) 로 구성되어 있습니다. 각 순서는 0번 인덱스부터 시작합니다.

“난” 이란 글자를 한번 분해해 보도록 하겠습니다.
한글 “난”은 초성 두번째(2) + 중성 0번째 + 종성 4번째로 구성되어 다음과 같은 산식이 성립됩니다.

“난” = ( 2[초성순서] * 21 * 28 ) + ( 0[중성순서] * 28 ) + ( 4[종성순서] ) + 0xAC00
    = 1180(십진수) + 0xAC00
    = 0x049C  + AC00
    = 0xB09C

즉 “난”이란 글자의 유니코드는 0xAC00 부터 1180번째 글자라 볼 수 있습니다.

이 수식을 기본으로 한글 유니코드를 초성/중성/종성으로 분리하도록 하겠습니다.

종성
종성은 한글유니코드값에서 0xAC00을 뺀 값에서 28로 나눈 나머지 값이 종성 순서 값이 됩니다.

종성 = (한글유니코드 – 0xAC00 ) % 28

“난”의 종성 “ㄴ”은 0xB09C – 0xAC00 = 1180(십진수) % 28 = 4
중성 배열 중 4번째 값인 “ㄴ”을 잦을수 있습니다.

중성

중성은 한글유니코드값에서 0xAC00을 빼고 거기서 다시 종성값을 뺀 후 28로 나눈 몫을 21로 나눈 나머지가 중성이 됩니다. 말로 하니 복잡하군요.

중성 = ( ( 한글유니코드 – 0xAC00 – 종성 ) / 28 ) % 21

“난” 의 중성 “ㅏ”는
“ㅏ” = ( ( 0xB09C – 0xAC00 – 4 ) / 28 ) % 21
    = ( 1176(십진수) / 28 ) % 21
    = 42 % 21 = 0
즉 중성 0번째 글자인 “ㅏ”로 분해됩니다.

초성

초성도 마찬가지로 산식을 이용하여 구할 수 있습니다.
초성 = ( ( ( 한글유니코드 – 0xAC00 – 종성 ) / 28 ) – 중성 ) ) / 21

“ㄴ”  = ( ( (0xB09C – 0xAC00 – 4 ) / 28 ) – 0 ) ) / 21
     = ( 1176(십진수) / 28 ) / 21
     = 42 / 21
     = 2
즉 초성 2번째 글자인 “ㄴ” 값을 구할 수 있습니다.

각 한글 자모 각각의 유니코드 값은 www.unicode.org/charts 에서 Hangul Compatibility Jamo 부분을 클릭하시면 pdf로 나오는데, 0x3131 ~ 0x318E 값의 범위를 가지고 있습니다.



이제 소스코드를 보겠습니다.
기본 자모 분석에 관한 소스는 웹에서 구한 소스입니다. 초성검색 때문에 많은 곳에 소스가 퍼져있고, 원 저작자 출처가 불분명해서 누가 최초로 만든 것이지 알 수는 없었습니다. 또한, 저도 소스를 사용한지 오래 되어 어느곳에서 가져다 왔는지 조차 기억이 안나는 군요. 가져온 소스에다가 제가 필요한 부분이 더 추가된 소스입니다.

//Hangul.java

package com.overoid.hangul2english.util;

 

public class Hangul {

   

                                //                                   

                                //                                   

                                //                                
                                //

final static char[] ChoSung   = { 0x3131, 0x3132, 0x3134, 0x3137, 0x3138, 0x3139,

                                  0x3141, 0x3142, 0x3143, 0x3145, 0x3146, 0x3147,

                                  0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d,
                                  0x314e };

   

    final static String[] ChoSungEng = {"r", "R", "s", "e", "E", "f",

                                        "a", "q", "Q", "t", "T", "d",

                                        "w", "W", "c", "z", "x", "v", "g"};

 

                                   //                                   

                                   //                                 

                                   //                              

                                   //           

   final static char[] JwungSung = { 0x314f, 0x3150, 0x3151, 0x3152, 0x3153, 0x3154,

                                     0x3155, 0x3156, 0x3157, 0x3158, 0x3159, 0x315a,

                                     0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160,

                                     0x3161, 0x3162, 0x3163 };

   

    final static String[] JwungSungEng = {"k", "o", "i", "O", "j", "p",

                                          "u", "P", "h", "hk", "ho", "hl",

                                          "y", "n", "nj", "np", "nl", "b",

                                          "m", "ml", "l"};

 

                                   //                                     

                                   //                             

                                   //                             

                                   //                                 

                                   //                   

   final static char[] JongSung  = { 0,      0x3131, 0x3132, 0x3133, 0x3134, 0x3135,

                                     0x3136, 0x3137, 0x3139, 0x313a, 0x313b, 0x313c,

                                     0x313d, 0x313e, 0x313f, 0x3140, 0x3141, 0x3142,

                                     0x3144, 0x3145, 0x3146, 0x3147, 0x3148, 0x314a,

                                     0x314b, 0x314c, 0x314d, 0x314e };

   

    final static String[] JongSungEng = {"", "r", "R", "rt", "s", "sw",

                                          "sg", "e", "f", "fr", "fa", "fq",

                                          "ft", "fx", "fv", "fg", "a", "q",

                                          "qt", "t", "T", "d", "w", "c",

                                          "z", "x", "v", "g"};

   

   

    public static String hangulToJaso(String s) {

       

        int a, b, c; // 자소 버퍼: 초성/중성/종성

        String result = "";

 

        for (int i = 0; i < s.length(); i++) {

            char ch = s.charAt(i);

 

            if (ch >= 0xAC00 && ch <= 0xD7A3) { // "AC00:" ~ "D7A3:" 속한 글자면 분해

                c = ch - 0xAC00;

                a = c / (21 * 28);

                c = c % (21 * 28);

                b = c / 28;

                c = c % 28;

 

                result = result + ChoSung[a] + JwungSung[b];

                if (c != 0) result = result + JongSung[c] ; // c 0 아니면, 받침이 있으면

            } else {

                result = result + ch;

            }

        }

        return result;

    }

   

    /**

     * 한글기준의 문자열을 입력받아서 한글의 경우에는 영타기준으로 변경한다.

     * @param s 한글/영문/특수문자가 합쳐진 문자열

     * @return 영타기준으로 변경된 문자열값

     */

    public static String convertToEnglish(String s) {

        // *****************************************

        // 0xAC00 + ( (초성순서 * 21) + 중성순서 ) * 28 + 종성순서 = 한글유니코드값

        // ( (초성순서 * 21) + 중성순서 ) * 28 + 종성순서 = 순수한글코드

        // 순수한글코드 % 28 = 종성

        // ( (순수한글코드 - 종성) / 28 ) % 21 = 중성

        // ( ( ( 순수한글코드 - 종성) / 28) - 중성) ) / 21 = 초성

        // *******************************************

       

        int a, b, c; // 자소 버퍼: 초성/중성/종성

        String result = "";

 

        for (int i = 0; i < s.length(); i++) {

            char ch = s.charAt(i);

 

            if (ch >= 0xAC00 && ch <= 0xD7A3) { // "AC00:" ~ "D7A3:" 속한 글자면 분해

                c = ch - 0xAC00;

                a = c / (21 * 28);

                c = c % (21 * 28);

                b = c / 28;

                c = c % 28;

 

                result = result + ChoSungEng[a] + JwungSungEng[b];

                if (c != 0) result = result + JongSungEng[c] ; // c 0 아니면, 받침이 있으면

            } else {

                result = result + ch;

            }

        }

       

        return result;

    }

   

    /*

     * 완성되지 않은 한글의 경우 영문 변환이 제대로 되지 않는다.

     * 잘못된 글자인 경우에도 영문으로 변환이 가능하도록 추가적으로 처리하는 함수

     * 글자가 초성, 중성, 종성을 구성하는 글자 배열을 루프돌면서 같은글자가 있는지

     * 확인한 해당 영문으로 변환함.

     */

    public static String convertToEnglishforSingleChar(String s) {

        String result = "";

        String temp = null;

       

        for (int i = 0; i < s.length(); i++) {

            char ch = s.charAt(i);

           

            if(ch >= 0x3131 && ch <= 0x3163) {

                temp = findChoSung(ch);

                if(temp != null) {

                    result = result + temp;

                } else {

                    temp = findJwungSung(ch);

                    if(temp != null) {

                        result = result + temp;

                    } else {

                        temp = findJongSung(ch);

                        if(temp != null) {

                            result = result + temp;

                        } else {

                            result = result + ch;

                        }

                    }

                }

            } else {

                result = result + ch;

            }

           

        }

       

        return result;

    }

   

    private static String findChoSung(char c) {

        String result = null;

        for(int i=0; i < ChoSung.length; i++) {

            if(ChoSung[i] == c) {

                result = ChoSungEng[i];

                break;

            }

        }

        return result;

    }

   

    private static String findJwungSung(char c) {

        String result = null;

        for(int i=0; i < JwungSung.length; i++) {

            if(JwungSung[i] == c) {

                result = JwungSungEng[i];

                break;

            }

        }

        return result;

    }

   

    private static String findJongSung(char c) {

        String result = null;

        for(int i=0; i < JongSung.length; i++) {

            if(JongSung[i] == c) {

                result = JongSungEng[i];

                break;

            }

        }

        return result;

    }

}



위 한글 자모 분석 로직을 이해하셨으면 소스는 이해가 쉽게 되실겁니다.

 

hangulToJaso 메소드는 카피한 소스에 있던 메소드인데, 한글 자모를 분리해서 string으로 리턴해주는 메소드입니다. 저희 소스에는 불필요한 부분이지만 나중에 쓸일이 있을지도 몰라서 그냥 그대로 두었습니다.

 

convertToEnglish 메소드가 저희 앱에서 사용하는 메소입니다. 한글을 초성/중성/종성으로 분리하여 순서값에 해당되는 영문자 배열을 리턴하면 간단히 변환이 끝났니다. 하지만, 사용자가 패스워드용 한글을 정상적인 완성형 한글만 사용하는 아니라 하ㄱㅏㅏ라고 자모만을 이용해서 만들 수도 있으므로 convertToEnglish 메소드는 이런 자모만으로 구성된 비정상적인 글자를 영문으로 변환할 수가 없어서 부분은 처리를 위한 convertToEnglishforSingleChar() 메소드를 추가로 두었습니다. 한글 자모 배열을 뒤져서 매칭되는 자모를 찾고, 동일한 배열값의 영문자를 리턴하는 메소드입니다.

 

Hangul Class 유틸성이라서 인스턴스 없이 메소드 호출을 하기 위해 모두 static으로 구현했습니다.

 

이로써 저희 Hangul2English 소스가 완성되었습니다.

 

끝으로 메니페스트 파일을 보도록 하겠습니다.


//AndroidManifest.xml

<?xml version="1.0" encoding="UTF-8"?>

<manifest android:versionCode="1" android:versionName="1.0"

          package="com.overoid.hangul2english" xmlns:android="http://schemas.android.com/apk/res/android">

    <application android:icon="@drawable/icon"

                 android:label="@string/app_name"

                 android:debuggable="false">

        <activity android:label="@string/app_name"

                  android:name=".MainActivity"

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

                  >

            <intent-filter>

                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>

            </intent-filter>

        </activity>

    </application>

    <uses-sdk android:minSdkVersion="5"/>

</manifest>



다른 부분은 별개 없고,
Acticity의 속성으로 android:theme="@android:style/Theme.NoTitleBar" 를 기술하시면 앱 실행시 상단에 나오는 회색 타이틀 바가 없어집니다. 별도로 Custom TitleBar를 만드는 방법도 있긴 하지만, 그냥 디폴트 타이틀 바를 위 처럼 없애고 Layout 작성시 타이틀 처럼 보이는 레이아웃을 추가하면 될 것 같습니다. 저희도 별도로 타이틀 바 비스무리한게 있어서 디폴트 타이틀바는 빼버렸습니다.

Hangul2English를 실행해 보셨는지 모르겠습니다만, Hangul2English는 가로 회전시에도 디자인이 별 문제없이 잘 돌아갑니다. 만일, 개발하시려는 앱이 특정 가로나 세로방향만 지원해야 한다면 메니페스트 파일에 android:screenOrientation="portrait"  로 기술하시면 세로방향만, landscape로 지정하시면 가로방향으로만 앱이 실행됩니다.

그리고 application entity에 설정되어 있는 android:debuggable="false" 속성은 어플리케이션 개발 및 테스트 완료 후에 배포용 패키지를 만드실 때  설정하시면 됩니다. 부가적으로 배포용 패키지 만드실 때는 로그 기능을 빼야 합니다. 런타임시에 불필요한 로그 코드가 나오는 것은 안 좋겠죠.

로그에 대해 간단히 알려드리면 로그는 ERROR, WARN, INFO, DEBUG, VERBOSE 이 다섯개 레벨로 나눌 수 있습니다. Verbose로 설정된 로그(Log.v)는 개발용 컴파일이 아닌 배포용 패키지를 만드실 때 컴파일 단계에서 빠져버립니다. 디버그 레벨 로그는 컴파일은 되지만 런타임시에 빠져서 절대 런타임시에 출력될 일은 없습니다. 나머지 에러나 warning, info 레벨 로그는 개발시나 런타임시나 출력이 됩니다. 아주 중요한 정보만 ERROR, WARN, INFO 레벨 로그로 남기시고, 가능한 개발시에는 Verbose 레벨을 사용하시면 런타임시 부하를 줄일 수 있습니다.

아. 정말 코드가 끝났습니다.
그동안 많은 도움이 되었는지 모르겠습니다.

완성된 소스코드 첨부합니다. 개발하시는데 많은 도움이 되셨으면 좋겠네요^^



앞으로 남은 안드로이드 실전강좌는 다 만든 앱을 시장에 배포하는거에 관련된 강좌가 남은 것 같습니다. 그럼, 즐거운 하루 되시기 바랍니다.

Trackback 1 Comment 6
  1. zzl986 2011.03.24 22:15 신고 address edit & del reply

    강의 해주신내용에. 감동이였구요!
    필요한 내용이든 그렇치않은.내용이든.고생하신. 모습에. 박수드립니다!
    아자..화이팅!

  2. 김영호 2011.04.18 13:43 신고 address edit & del reply

    강의 잘 보았습니다 ^^+

    얕은 지식에 많은 보탬이 되었습니다.

    감사합니다. __+

  3. BlueSkygogo 2011.06.25 17:54 신고 address edit & del reply

    정말 좋은 내용으로 가득하네요...!
    개발하는 데 큰 도움이 될것 같습니다.
    감사드립니다....^^

  4. 민짜 2011.10.06 13:24 신고 address edit & del reply

    폰에서 글자를 입력받아 실시간으로 서버로 전송하는 프로그램을 개발중입니다. 자음/모음 분리하는것때문에 좌절하고 있었는데 올려주신 Hangul소스를 바탕으로 해결했습니다.정말 감사합니다.

  5. 미래소년 2012.04.05 23:39 신고 address edit & del reply

    감사합니다.. 강의 정말 잘 봤습니다.. 무지한 저도 이해할 수 있을만큼 잘 설명해 주셨네요..
    그런데 제가 지금 만들고 싶은 어플은 영타를 한글로 바꿔주는 것입니다..
    이 강좌와 반대로 말이죠.. 의외로 한글을 초성중성종성으로 분해할 필요가 없어 쉬울 것 같은데..
    코드 좀 부탁드려도 될까요.. 머리에서 돌기는 하는데 사실 자신이 없어서요..

  6. 2012.07.05 16:36 address edit & del reply

    비밀댓글입니다

2010.08.20 14:14

[강좌A07] 안드로이드 실전 개발 - 리소스 해킹




안녕들 하십니까?

오늘의 강좌 주제는 안드로이드 App Resource(이미지, XML) Hacking 입니다.

정말 잘 만들어진 App을 보면서 이 App은 어떻게 UI를 구성했을까? 고민해 본적은 없습니까? 하하~ 저는 그런 고민을 많이 했습니다. 단순한 UI야 쉽게 만들 수 있지만, 복잡한 UI를 보면서.. UI를 만들기 위해서 어떤 Layout을 사용했으며, 어떤 View를 사용했을까? 고민하다가 찾아본 프로그램에 대한 소개입니다.


전체 강좌 목차

[강좌A01] Moteodev Studio를 이용한 안드로이드 개발 환경 구축 가이드
[강좌A02] 안드로이드 개발 참고 서적 소개
[강좌A03] Android 실전 개발 - 아이디어 / 기획 / Wireframe
[강좌A04] 안드로이드 실전 개발 - 아이콘 제작
[강좌A05] 안드로이드 실전 개발 - 레이아웃 및 리소스 : Part1
[강좌A06] 안드로이드 실전 개발 - 레이아웃 및 리소스 : Part2
[강좌A07] 안드로이드 실전 개발 - 리소스 해킹

참고로 안드로이드 소스 역컴파일은 현재는 불가능합니다. 어셈블리 레벨로 볼 수는 있지만, 그거 분석하는거 공부할려면 짜증납니다. 언젠가는 자바로 역컴파일 해주는 프로그램이 나오지 않을까? ㅋㅋ 안 나올수도 있습니다.

 

기본적으로 Android App을 빌드하면 .apk 파일이 만들어집니다. 이 파일은 압축파일로 압축을 풀면 이미지는 볼 수 있으나, xml 파일의 경우에는 binary로 저장되기 때문에 editor에서 볼 수가 없습니다. xml을 볼 수 있다면.. resource 설계에 상당한 도움이 될 것입니다

~ 시작하겠습니다.

 

1. 먼저 apk 파일을 구해야 겠지요.

핸드폰으로 앱을 다운/설치 하시면.. 기본적으로 apk 파일은 /data/app 디렉토리에 저장됩니다. 근데, 우리가 구매한 핸드폰은 기본적으로 root 계정이 막혀있으며, /data 디렉토리에 퍼미션이 없어서 접근 자체가 불가능합니다. 루팅을 하지 않는 한 /data 디렉토리의 apk를 볼 수 있는 방법이 없습니다. <개발자 폰이 있으면 가능할텐데…> 하지만, 구글 검색어: “android apk rapidshare” 이정도 치면 누군가 apk를 모아서 rapidshare 사이트에 올려둔 게 많습니다. 특정 App 이름을 검색어에 추가하면 그 앱을 구할 수도 있습니다. 최신 App은 거의 없구요. 일종의 불법 app 사용이겠네요. 것도 원래 무료 App이 많습니다.  폰에 설치해서 사용도 가능합니다. 사용하기 위해서 이짓하기는 좀 귀챦습니다. 무료인 경우에는 개발사 홈페이지에서 바로 다운이 가능한 곳도 많습니다. 향후 Google App 인증이 적용된 App들이 나오면 설치는 불가능하게 되겠죠?

저희는 TStore에서 다운받겠습니다. tstore에서 pc manager로 다운 받으시면 local pc apk 파일이 다운됩니다. (참고로 tstore에서는 개발자에게 ARM 관련 library를 제공하기 때문에 ARM이 걸려있는 apk는 폰에 설치해도 실행이 안됩니다. 어플 실행 부분에 체크하는 로직이 들어있기 때문입니다. 저희는 리소스만 볼 것이므로 상관은 없습니다.)

 


앱에서 아무 프로그램이나 pc Manager로 다운받으신 후 우측마우스 클릭 > 파일이 저장된 폴더 열기를 하시면 apk 파일이 저장된 폴더가 열립니다. 저는 R-2 Player라는 라디오 프로그램을 다운 받았습니다. 제가 강좌하고 있는 Hangul To English 앱을 다운 받으셔서 테스트 하셔도 됩니다.

 

2. 압축을 풀자.

apk
파일은 압축 파일이므로 압축을 풀 수가 있습니다. 다만, 알집으로는 못 풀고 오픈소스 진영에서 만든 압축 프로그램인 7-zip으로 푸셔야 합니다. 7-zip은 홈페이지
(http://www.7-zip.org/) 에서 다운받으시면 됩니다.


위 그림을 보시면 /res/drawable 디렉토리에 이미지들이 보이네요. 보통 개발할 때 drawable 디렉토리에는 xml만 넣고, drawable-hdpi 폴더에 큰이미지, drawable-mdpi에 작은 이미지를 넣는데, 이 앱은 drawable에 이미지랑 xml 모두 다 들어있군요.

3. xml 파일 보기.

압축 푼 파일에서 xml 파일을 열어 보겠습니다.


~ binary 파일로 되어 있어서 xml 파일 자체를 볼 방법이 없군요.

이제 이 xml을 볼 수 있는 프로그램을 다운 받아 봅시다.

오픈소스로 만든 AXMLPrinter2 라는 자바로 개발된 프로그램입니다.


http://code.google.com/p/android4me/downloads/list  

에서 AXMLPrinter2.jar 파일을 다운 받아서 아무 디렉토리에 넣습니다. 저는 d:\test 디렉토리에 apk 압축을푼 파일(apk 디렉토리명도 r2_player로 변경했습니다) AXMLPrinter2.jar 파일을 넣어두겠습니다.

이제 준비가 끝났습니다. 위 압축 푼 파일 중에서 D:\test\r2_player\res\layout-hdpi\player_fwvga.xml 파일을 변환한다고 할 때..

cmd 창에서 다음과 같이 입력하시면 작업이 끝납니다.

java –jar [AXMLPrinter2.jar위치] [binary 포맷 xml 파일 위치] > [변환될 파일 위치]


java –jar D:\test\AXMLPrinter2.jar D:\test\r2_player\res\layout-hdpi\player_fwvga.xml > D:\test\r2_ player\res\layout-hdpi\player_fwvga.xml.txt



변환 작업이 완료되었습니다.

변환된 파일 위치에 가보시면 변환된 파일이 존재합니다. 열어보도록 하겠습니다.



잘 변환이 되었습니다.
그런데 이 작업에는 두가지 문제가 존재합니다.

하나는 변환 해야 될 파일이 많은 경우 엄청난 노가다를 해야 합니다.
두번째는, 현재 변환된 XML을 보시면 android:layout_width=”-2”로 실제 상수값이 들어가 있습니다. -2developer.android.com 에서 찾아보니
WRAP_CONTENT를 말합니다. 이것을 우리가 보기좋게 변환하려면 AXMLPrinter2 프로그램을 소스를 수정하거나 혹은 XML -> XML로 변환하는 XSLT 하나 만들면 될 것 같은데만들까 했는데.. 도저히 시간이 나지 않는군요. 누군가 해 주시면 감사하겠습니다. 아무도 안 해주심..하하 내년쯤에나 만들어 볼까 합니다.

 

첫번째 이슈인 변환해야 될 파일이 많은거..이것은 제가 도저히 참을 수가 없어서 간단히 VB스크립트로 조금 일을 간단하게 처리할 수 있도록 만들었습니다.

 

처음에는 vbsWindow Shell을 이용하여 프로그램을 직접 실행하도록 만들었으나 cmd 창이 개수만큼 떴다 사라지고 해서 오히려 불편해서 그냥 batch 파일을 만들어 주는 스크립트를 만들었습니다.

스크립트
소스입니다.



Const AXMLPRINTER_FILE = "D:\test\AXMLPrinter2.jar"

Const APP_ROOT_DIR = "D:\test\r2_player"

Const SAVE_FILE = "D:\test\print_xml_r2_player.bat"

 

Dim fso, tf

Set fso = CreateObject("Scripting.FileSystemObject")

 

 

If Not fso.FolderExists(APP_ROOT_DIR) Then

             Print("App Root Folder not exist. Check APP_ROOT_DIR Constants")

             WScript.Quit 0

End If

 

If Not fso.FileExists(AXMLPRINTER_FILE) Then

             Print("AXMLPrinter2.jar file not exist. please check AXMLPRINTER_FILE Constants")

             WScript.Quit 0

End If

 

Set tf = fso.CreateTextFile(SAVE_FILE, True)

 

call ShowSubfolders(APP_ROOT_DIR)

 

tf.Close

 

 

Sub ShowSubFolders(Folder)

             Set folder = fso.GetFolder(Folder)

    Set files = folder.Files

 

             For each file In files

                            If InStr(file.Name, ".") <> 0 Then

            fext = Right(file.Name, Len(file.Name) - InStrRev(file.Name, "."))

                  End If

 

                            If UCase(fext) = "XML" Then

                                        runCmd = "java -jar " & AXMLPRINTER_FILE & " " & file.Path & " > " & file.Path & ".txt"

                                        Print(runCmd)

                                        tf.WriteLine(runCmd)

 

                            End If

    Next

 

    For Each Subfolder in Folder.SubFolders

        ShowSubFolders Subfolder

    Next

End Sub

 

Sub Print(x)

   WScript.Echo x

End Sub

 


소스는 간단합니다.
디렉토리를 뒤져서 xml 파일인 경우 우리가 실행할 명령어를 텍스트 파일로 만들어 주는 스크립트입니다. vb 스크립트 아시면 금방 이해가 가실겁니다.

 

위 스크립트를 test 디렉토리에 저장한 후 처음 세줄인 상수값을 자신에게 맞게 수정합니다.

 

Const AXMLPRINTER_FILE = "D:\test\AXMLPrinter2.jar" 'AXMLPrinter2.jar 파일 경로 및 파일명

Const APP_ROOT_DIR = "D:\test\r2_player"                  '압축푼 apk 파일 루트 경로 (이 경로 하위 디렉토리를 뒤집니다.)

Const SAVE_FILE = "D:\test\print_xml_r2_player.bat"   '스크립트가 생성할 파일명

 

자 이제 실행은 cmd 창에서 cscript d:\test\print_xml.vbs 라고 명령 내리시면 apk 루트 하위의 모든 xml를 뒤져서 필요한 배치 스크립트를 만들어 줍니다. wscript d:\test\print_xml.vbs 라고 입력하셔도 되나, 이 경우 스크립트에서 메시지가 출력될 때 팝업창으로 나와서 조금 불편합니다.


위 그림과 같이 입력하면 배치파일이 만들어 집니다.

이제 만들어진 배치 파일을 실행하시면 모든 xml 파일을 텍스트 파일로 변환해 줍니다. 일이 한결 편해졌습니다.

이로써 7번째 안드로이드 실전 강좌를 마치겠습니다.

다음 강좌에서는 DB 부분을 살펴볼 것입니다. DB 관련 툴도 살펴보고 저희 Hangul to English 앱의 DB 부분 소스도 개발하겠습니다. 제 강좌를 구독하시면서 아직 Hangul To English App을 설치해 보지 않으신 분은.. 한번 설치해보시기 바랍니다. 그래도 직접 해보면 개발하는 앱에 대한 이해를 높일 수 있으니 ..

 

끝으로 스크립트 소스 첨부합니다. 필요하신분은 다운받으시기 바랍니다.

 

 

 

Trackback 1 Comment 10
  1. 지니님 2010.08.20 19:33 신고 address edit & del reply

    안녕하세요 강좌 잘 보고 있습니다. 서핑하다 우연히 들어왔는데 이렇게 좋은 강좌가 있었네요. 앞으로도 좋은 강좌 많이 부탁드립니다.^^

  2. onjo 2010.08.21 18:39 신고 address edit & del reply

    좋은 정보 감사합니다.. ^^

  3. 나그네 2010.08.25 11:36 신고 address edit & del reply

    좋은 강좌 감사합니다.

    너무나 많은 도움이 된거 같네요!

    앞으로도 잘 부탁드립니다 (__)

  4. seso 2010.12.19 16:04 신고 address edit & del reply

    좋은 정보 감사드립니다~!!

  5. 지니파파 2010.12.21 17:00 신고 address edit & del reply

    좋은 정보 감사합니다.

  6. tony 2011.05.04 19:28 신고 address edit & del reply

    최고에요0.0

  7. 빛나는 야옹이 2011.06.29 12:10 신고 address edit & del reply

    열심히 따라했는데요... 안되네요... xml파일 내용이 텅~ 비어있어요,,, 왜 그런건가요?

  8. 빛나는 야옹이 2011.06.29 12:12 신고 address edit & del reply

    꼭 해보고 싶은데 ㅠㅠ *

  9. 뽀잉뽀잉 2011.10.26 21:48 신고 address edit & del reply

    와우! 이런정보가 있다니!!
    정말 많은 도움이 되었어요!!

  10. eeaa3 2012.02.27 21:56 신고 address edit & del reply

    소스구하기에 좋습니다. 책에서는 이부분을 왜 그냥지나쳣는지 ㅎㅎ

2010.08.04 21:07

[강좌A03] Android 실전 개발 - 아이디어 / 기획 / Wireframe




전편 강좌에 이어 이제부터 본격적인 실전 개발에 들어가도록 하겠습니다.
개발을 시작하면서 처음으로 할 일은 기획이겠죠. 아이디어 구상 및 대략적인 UI 스케치 정도까지가 될 것 같네요.

전체 강좌 목차
[강좌A01] Moteodev Studio를 이용한 안드로이드 개발 환경 구축 가이드
[강좌A02] 안드로이드 개발 참고 서적 소개
[강좌A03] Android 실전 개발 - 아이디어 / 기획 / Wireframe

1. 아이디어 구상.

모니 모니 해도 앱 개발에 젤 중요한 것은 아이디어 겠죠. 기발한 아이디어로 제품만 만들 수 있다면 큰 돈도 벌 수 있고 성공할 수 있지만..그게 어디 말 처럼 쉽겠습니까?
좋은 아이디어는 많이 보고 많이 사용하다 보면 언젠가는 여러분이나 저나 뛰어난 앱을 만들날이 오지 않을까 싶습니다.

2. Wireframe 제작 (Mockup 혹은 스토리보드라고도 하죠)

아이디어가 정해지면 Wireframe(스토리보드)을 제작합니다.
모, 제작이라해서 거창하게 생각하실 것 없이 종이에 그적 그적 아이디어를 화면으로 구성해도 무방합니다.

다음은 제가 주로 작업하는 방식과 유용한 Wireframe 제작 툴에 대해서 간략 설명하겠습니다.

A. 종이에 스케치.

제가 가장 즐겨 사용하는 방법입니다. 혼자서 개발한다던지 복잡하지 않고 간단한 어플은 이걸로 충분합니다.
하지만 만든 앱을 TStore에 등록하기 위해서는 스토리보드 문서가 필요합니다. 이때는 종이를 제출 할 수 없으니..
완성된 앱의 화면을 캡처해서 별도의 스토리 보드를 만들어서 제출하시면 됩니다.

종이에 그려도 외곽 아웃라인이라도 폰모양과 사이즈로 그려진 종이가 있다면 편리할 겁니다.


위 그림과 같은 형태의 자료를 http://iphone-dev-tips.alterplay.com/2009/11/iphone-app-desgin-templates.html 사이트에서 Download or print these design templates from Google docs. 클릭하시면.. 아이폰 밑그림이긴 하지만, 출력해서 사용할 수 있는 디자인 템플릿 pdf 문서를 다운하실 수 있습니다.
출력해서 연필로 찍~찍~. 최고입니다.

사이트에 보니 포토샵 원본파일도 있군요. 이미지로 떠서 파워포인트에서 배경으로 지정하셔서 사용해도
좋을것 같습니다.

B. Visio Stencil for Android.

여러명이 개발하는 팀 프로젝트라 커뮤니케이션이 필요하거나 고객에게 보여주며 회의를 해야 한다면 좀 그럴싸한 기획안을 만들어야 합니다. Artfulbits라는 회사에서 안드로이드 개발을 하면서 UI Prototyping하기 편리한 MS Visio Stencil을 무료로 제공합니다.


이 화면은 Vision Stencil을 이용해서 스토리 보드 형식으로 배경을 만들어서 샘플로 만든 템플릿입니다. 이 템플릿 파일을 첨부합니다. 필요하신분은 다운해서 사용하시기 바랍니다. 다만, 이 파일은 안드로이드 스텐실이 포함되어 있지 않기 때문에 http://www.artfulbits.com/android/stencil.aspx#Presentation_1 이 사이트에서 Android GUI Prototyping 자료를 다운해서 사용하시면 됩니다.  
그리고 Yahoo에서도 Visio Stencil을 제공합니다. Mobile은 안드로이드 디자인이라기 보다는 iPhone 디자인이지만, 자료 자체는 아주 좋습니다.

http://developer.yahoo.com/ypatterns/about/stencils/ 요기서 다운 가능합니다. Visio Stencil 뿐만 아니라 PNG, SVG 등 다양한 포맷으로 제공하기 때문에 활용성이 매우 좋습니다. UI 템플릿 말고도 Yahoo UI에서는 다양한 자료들이 많으니 개발자라면 한번쯤 가서 살펴 볼만 합니다.

C. DroidDraw


네. 많은 개발자분들이 알고 계시며, 좋다고 칭찬하시는 그 툴입니다.
일종의 UI Editor로 쉽게 Wireframe도 만들고 바로 XML 레이아웃 소스을 개발 할 수 있어서 많은 사람들이 열광하던데.. 솔직히 저는 좀 별로입니다. DroidDraw로 복잡한 UI 그리기도 힘이들고 UI 개발하느니 기냥 이클립스에서 바로 UI 개발하는게 훨씬 편리한 것 같아서.. 하여간 저는 잘 사용하지는 않습니다.
무료니깐... 한번들 써보시고 판단하시기 바랍니다. 다운 및 사용법은 http://www.droiddraw.org/ 사이트를 참고하시기 바랍니다.

D. 웹사이트 개발할 때 사용하는 PowerPoint로 된 스토리 보드

웹 개발에 많이 쓰는 방식이죠. 디자이너 분이 계시면 실제 디자인 해서 멋있는 이미지로 이쁘게 만들기 좋죠.
다들 아실테니... 그만 중략.


툴들도 살펴봤으니..이제 저희가 개발할 내용을 살펴보도록 하겠습니다.

3. App 컨셉 및 아이디어:

제가 스마트폰을 사용하다 보니 웹사이트나 은행 앱등을 사용할려니 아이디/패스워드 입력하는 곳이 많더군요. 저는 주로 한글로 패스워드를 만들어 둔 곳이 많은데.. 도대체 한글에 해당되는 영문 자판을 몰라 필요한 정보를 키보드로 일일히 확인하여 메모장에 기록해 두었다가 웹사이트 로그인을 합니다. 무지 불편합니다. 아..님들도 그러시다구요? 하하..그럼, 이런 불편한 사용성을 개선시킬 앱을 만들면 많은 사람들이 사용하지 않을까?

네. 이 컨셉이 저희가 기획하고 개발할 앱 컨셉입니다.

 4. WireFrame 제작

아이디어가 정해졌으니 이제 대충 UI스케치를  하겠습니다. 위 아이디어의 핵심은 텍스트박스 2개만 있으면 될것 같네요. 한글 그리고 영문. 그리고 터치로 복사하기 귀챦으니 클립보드 복사 버튼 정도 필요하고, 한번만 사용할 게 아니라 필요한 한글/영문쌍을 DB에 저장해 두어 볼 수 있음 좋을것도 같습니다.
UI 화면(Activity) 하나면 될 것 같습니다. 이정도면 연필로 노트에 그리는게 제일 편리하겠죠.

네. UI.스토리 보드가 완성되었습니다.
하하. 이것은 제가 어제 완성한 제품의 이미지를 캡처한 것인지라.. 좀 그럴싸하게 보입니다.

화면 하나로 끝냈습니다.  스토리보드 파일 첨부합니다. 필요하신 분은 사용하십시요. 공짜입니다.


기능 요건은 스토리보드나 위 이미지를 참고하시면 됩니다. 워낙 간단한 기능인지라~ 한 번 보면 아실 겁니다.

이상으로 안드로이드 실전 개발 - 아이디어 / Wireframe 제작에 대해 강좌를 마치며, 다음번 강의해서는 아이콘 디자인에 대해서 툴 리뷰 및 Android 설치 파일(.apk)을 가지고 Resource 훔쳐보기 편을 진행한 다음, 그 이후에 모토데브를 띄우겠습니다.

 

Trackback 1 Comment 6
  1. 남시언 2010.08.04 21:37 신고 address edit & del reply

    우와~~ 대단하시네요 ~ ㅎㄷㄷㄷ
    저는 언제쯤 그정도의 경지에 이를런지 ㅠㅠㅠ
    CP에서만 현재 게속 쩔쩔메는중 ㅋㅋㅋ

    스토리보드는 오피스 버전이 낮아 못보네요 읔....

    잘 보고 갑니다 ^^

  2. killerjoe 2010.08.24 09:21 신고 address edit & del reply

    스토리보드가 편해보입니다. ㅎㅎㅎ 점 사용해볼게요 . ^^ / 잘 보고갑니다.

  3. 지나가는중 2010.09.13 16:24 신고 address edit & del reply

    안드로이드 스텐실을 받으려고 링크된 곳으로 가봤는데...메일 보내도 감감무소식이네요.
    어떻게 다운 받을수 있나요?

    • 보고픈 2010.09.14 11:15 신고 address edit & del

      http://www.artfulbits.com/android/stencil.aspx#Presentation_1 여기서 상단 download 누르시고, 정보 입력하시면 메일로 바로 다운로드 링크가 전송됩니다. 한번 더 해보시고, 그래도 안되시면 비밀댓글로 이메일 남겨주세요.

  4. 리칼 2010.12.10 17:46 신고 address edit & del reply

    와..정말 대단하세요! 존경스럽네요 저도 현업이 안드로이드지만 볼수록 도움이 되는 글입니다.

    좋은 정보 감사합니다.^^

  5. kang 2012.11.19 10:32 신고 address edit & del reply

    좋은 자료 잘 보고 갑니다!!!짱!!