reCAPTCHA를 웹서비스에 적용시켜 보거나 또는 적용된 웹서비스를 이용하면서 두 단어를 입력하는 것에 대해서 더 정확하게 판별을 할려나 보다 외에는 별다른 생각이 없었다. 몇일전 TED에서 reCAPCHAR를 만든 루이스 폰 안의 '대규모 온라인 협업'이란 강연을 보면서 그 이유를 알 수가 있었다.



reCAPCHA의 주목적은 내가 알고 있던 실제 인간을 판별하기 위한 것 뿐만 아니라 책들을 디지털라이징을 하는데 도움을 주기위한 것도 있었다. 스캔후 OCR로 판독하기가 어려운 상태가 좋지 않은 문자들을 reCAPTCHA에 구별을 위한 문자와 같이 보여줌으로써 인간의 도움을 빌린다는 것이다. reCAPTCHA 인증시 나오는 단어중 하나만 실제 인간인지 판별하는 용도로 사용되고 나머지 하나는 컴퓨터가 판독하기에 불분명한 단어들을 확인하기 위해 사용한다는 것이다. 참으로 기발한 아이디어인 것 같다.

다만 reCAPTCHA를 이용하는 서비스 사용자들의 책들의 디지털라이징에 도움을 주는 이러한 참여가 누구를 위한 것인지는 의문이 든다. reCAPTCHA는 구글에 인수되었는데 구글북스의 디지털라이징에 사용되는지는 모르겠다. 광고를 보고 클릭함으로써 구글의 서비스를 무료로 이용하는 것처럼 문자 판독에 작은 도움을 주고 서비스들을 무료로 사용하는 대가중 하나로 봐야 하는 것인인지...

용도와 목적이야 어찌되었던 이런 개인들의 작은 노력이 합쳐져 커다란 결과물을 낼 수 있는 도구들이 많아 진다는 것은 좋은 현상인 것 같다. 물론 그 목적이 모두가 누릴 수 있는 공익이라면 더 보람과 가치가 있을 것이다. 그동안 IT에 별로 관심이 없었더니 오래전 부터 시작된 일을 이제서야 혼자 감동 받고 뒷북을 치고 있으니 조금 난감하기는 하다.

루이스 폰 안은 위의 TED 강연에서 Duolingo란 새로운 서비스를 소개한다. 웹사이트들을 많이 사용되는 여러 언어로 번역을 하는 서비스이다. 이 역시 여러 사용자들의 자발적인 참여를 통해 번역을 하게되며 사용자들은 Duolingo 서비스를 통해 번역할려는 다른 외국어를 학습하며 번역을 한다.


사이트를 가보니 베타 테스트 중이며 아직 지원하는 언어가 많지 않은 것 같다. 어떤 방법으로 사용자에게 외국어 학습과 함께 번역에 기여할 수 있게 하는 가는 잘 모르겠지만 뭔가 재미있는 것이 나올 것 같기도 하다. 영어가 모국어인 사람들도 많지만 전체로 보면 영어를 배우고 싶어하는 사람이 더 많을 것이다. 그런데 현재 모습만 보면 왠지 외국어를 배우고 싶어하는 영어 사용자들을 위한 단방향 서비스인 것 같기도 하다. 영어에 익숙해지기 위해 많은 시간을 투자해야만 하는 한국에서 이런 비슷한 서비스가 한글 전용으로 나오는 것도 괜찮을 것 같다.

'이야기들 > 소소한 이야기' 카테고리의 다른 글

Xcode 재설치  (6) 2012.03.09
reCAPTCHA와 집단지성의 활용  (0) 2012.01.31
꿩 대신 닭?  (2) 2012.01.11
2012년...  (0) 2012.01.02
아이맥 구입  (8) 2010.04.25
아이폰 개발자 프로그램 갱신  (2) 2009.11.05

개발 툴 2010.02.27 19:31
작년말 구글에서 나온 새로운 개발언어인 Go를 맥에 설치해 보았습니다. 시스템 프로그래밍을 위한 언어라고 하는데 아직 자세히 살펴보지는 못하고 설치만 해보았습니다. 제가 사용한 설치 방법입니다.

1. 다운로드
* MacPorts
설치가 안되어 있을 경우에는 해당 사이트에서 다운로드 받아서 설치합니다. 설치파일이 있어 간단히 설치할 수 있습니다.

* gmake
MacPorts 설치후에는 터미널에서 아래와 같이 gmake를 설치합니다.
> sudo /opt/local/bin/port install gmake

* mercurial
해당 사이트에서 OS X 버젼에 맞는 파일을 다운로드 받아서 설치합니다. MacPorts와 마찬가지로 간단히 설치할 수 있습니다.

2. 설치
Go가 설치될 디렉토리를 계정 루트에 생성합니다.
> mkdir go
> mkdir bin

설치에 앞서 설치환경을 먼저 설정합니다.
> export GOROOT=$HOME/go
> export GOARCH=386
> export GOOS=darwin
> export GOBIN=$HOME/bin

이제 아래와 같이 Go를 설치합니다.
> hg clone https://go.googlecode.com/hg/ $GOROOT
> cd go/src/
>./all.bash

vi와 같은 에디터를 이용하여 bin path를 .bash_profile에 추가합니다.
export PATH=${PATH}:${HOME}/bin

3. Hello, World
새로운 언어를 설치하였으니 Hello, World를 출력해 봅니다. vi등 에디터를 이용하여 아래와 같이 입력하고 hello.go라는 이름으로 저장합니다.

hello.go
package main

import "fmt"

func main() {
    fmt.Printf("Hello, world!\n");
}

터미널에서 아래와 같이 컴파일하여 실행합니다.
> 8g hello.go
> 8l hello.8
> ./8.out
Hello, world!

'개발 툴' 카테고리의 다른 글

PhoneGap 설치  (4) 2012.02.14
OS X에서 Go 설치  (0) 2010.02.27
실버라이트2 둘러보기  (10) 2008.12.16
프로젝트 관리 도구 OpenProj  (2) 2008.03.21
적당히 참견하는 Xcode  (4) 2008.02.25
OS X의 파이썬  (0) 2008.02.20

이전에 포스팅한 "NSXMLParser로 RSS 읽어오기"와 유사한 방법으로 구글 날씨 RSS를 가져오는 것을 만들어 보았습니다. 그런데 한글이 깨져나와 확인해 보니 문자셋이 euc-kr이었습니다. 문자셋을 확인하는 방법은 URLConnection의 델리게이트 메소드에서 확인할 수 있습니다.
  1. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
  2.     NSLog(@"Encoding: %@", [response textEncodingName]);
  3. }

전송이 끝난 후에 아래와 같이 NSData를 euc-kr을 utf-8로 변환하여 사용할 수 있습니다. 변경된 data를 NSXMLParser의 initWithData의 인자로 사용하면 됩니다.
  1. - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
  2.     NSString *str = [[NSString alloc] initWithData:receiveData encoding:0x80000000 + kCFStringEncodingDOSKorean];
  3.     NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
  4.    
  5.     NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
  6. .
  7. .
  8. .
  9. }

한가지 이상한 점은 웹브라우저에서 확인하면 같은 URL이지만 utf-8로 넘어 옵니다. 아마 서버에서 헤더를 검사에서 각각 다른 인코딩으로 넘겨주는 것이 아닌가 하는 생각이 듭니다. 헤더의 항목들을 변경해서 보았는데 User-Agent를 설정해서 보내보니 euc-kr이 아닌 utf-8로 넘어 왔습니다.
  1.     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/ig/api?weather=seoul"]];
  2.      
  3.     [request addValue:@"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; ko; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2" forHTTPHeaderField:@"User-Agent"];
  4.  
  5.     xmlConnection = [[NSURLConnection alloc]
  6.                      initWithRequest:request
  7.                      delegate:self];


구글의 날씨 API에서는 이와 같이 User-Agent를 보내면 utf-8로 보내기때문에 위와같이 인코딩의 변환이 필요하지 않습니다. 아마 예측가능한 User-Agent는 utf-8로 보내고 그외에는 euc-kr로 보내는 것 같습니다. 이는 영문도 마찬가지이며 http://www.google.com/ig/api?weather=seoul와 같이 co.kr에서 com으로 변경하면 문자셋이 iso-8859-1로 넘어 옵니다. User-Agent를 추가하면 역시 utf-8로 넘어 옵니다.



이전부터 그냥 복사해서 올렸는데 오늘 보니 아래와 같이 나오는 건 너무 보기가 힘든 것 같아서, 예제코드를  Quick Highlighter를 사용해서 정리해 보았습니다.
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com/ig/api?weather=seoul"]];
     
    [request addValue:@"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; ko; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2" forHTTPHeaderField:@"User-Agent"];

    xmlConnection = [[NSURLConnection alloc]
                     initWithRequest:request
                     delegate:self];

보기도 조금 나아지지만 해당 클래스에 대한 애플의 문서로 바로 링크가 되는 것도 좋은 것 같습니다.


안드로이드 개발환경을 조금 더 살펴 볼려고 간단히 어플리케이션을 만들어 보았습니다. 처음 대쉬보드 바이오리듬을 시작한뒤로 바이오리듬을 너무 우려먹고 있는 것 같습니다. SDK의 설치나 사용방법은 이전에 포스팅한 구글 Android 개발환경 둘러 보기를 참조하시면 좋을 것 같습니다. 아래의 이미지는 에뮬레이터에서 실행한 모습입니다.


요즘 개발환경으로는 드물게 마우스 사용없이 GUI를 구현해야 하지만 레이아웃을 편집하면서 확인할 수 있으니 큰 불편은 없는 것 같습니다. 아래는 사용한 소스들과 간단한 설명입니다. 이클립스에서 안드로이드 프로젝트로 Biorhythm을 생성하고 각각의 소스를 아래와 같이 수정하시고, BioView.java를 추가하시면 위와 같이 실행해 보실 수 있습니다.

* Biorhythm.java
package com.zzerr;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class Biorhythm extends Activity {
    private BioView bioView;
    private EditText inputYear, inputMonth, inputDay;
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       
        setContentView(R.layout.main);
       
        bioView = (BioView)findViewById(R.id.myView);
       
        inputYear = (EditText)findViewById(R.id.inputYear);
        inputMonth = (EditText)findViewById(R.id.inputMonth);
        inputDay = (EditText)findViewById(R.id.inputDay);
       
        /** 버튼이 클릭되었을 경우 바이오리듬 출력 */
        Button button = (Button)findViewById(R.id.showButton);
        button.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                bioView.setBirthDay(Integer.parseInt(inputYear.getText().toString()),
                        Integer.parseInt(inputMonth.getText().toString()),
                        Integer.parseInt(inputDay.getText().toString()));
               
                bioView.invalidate();
            }
        });
    }
}


* BioView.java
View 클래스에서 상속 받아 main.xml에서 정의한 myView를 서브클래싱하는 클래스입니다. 바이오리듬을 계산한 후에 출력을 합니다.
package com.zzerr;

import android.view.View;
import android.content.Context;
import android.util.AttributeSet;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;

import java.util.Date;

public class BioView extends View {
    /** 상수 */
    private static final int mMaxDays = 30;
    private static final int mMaxType = 3;
    private static final long mTDV = (60*60*24*1000);
    private static final double mPI = 3.14159;
   
    private static final double mBioValues[] = { 23.0, 28.0, 33.0 };
    private static final int mColors[] = { 0xff0000ff, 0xffff00ff, 0xff00ffff };
   
    /** 멤버변수 */
    private Paint mPaint;
    private Rect mRect;
    private double mStartDays;
    private Date mBirthDate, mTodayDate;
       
    public BioView(Context context, AttributeSet attrs) {
        super(context, attrs);
       
        mRect = new Rect();
        mPaint = new Paint();
       
        mRect.top = 0;
        mRect.bottom = getWidth();
        mRect.left = 0;
        mRect.right = getHeight();

        mTodayDate = new Date();
        Date startDate = new Date(mTodayDate.getYear(), mTodayDate.getMonth(), 1);
       
        mStartDays = startDate.getTime()/mTDV;
        mBirthDate = new Date();
       
        mBirthDate.setYear(0);
    }
   
    public void setBirthDay(int year, int month, int day) {
        mBirthDate.setYear(year);
        mBirthDate.setMonth(month);
        mBirthDate.setDate(day);
    }

   @Override
   protected void onDraw(Canvas canvas) {
        int cellWidth = getWidth()/mMaxDays;
       
        mRect.top = 0;
        mRect.bottom = getWidth();
        mRect.left = 0;
        mRect.right = getHeight();
       
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(0xFFFFFFFF);

        int x = 0, y = 0, oldY = 0;
         
        // 세로줄 출력
        for (int i = 0; i <= mMaxDays; i++) {
            x += cellWidth;
            canvas.drawLine(x, mRect.top, x, mRect.bottom, mPaint);
        }
         
        // 가로줄 출력
        canvas.drawLine(0, mRect.bottom/2, mRect.right, mRect.bottom/2, mPaint);
      
        // 오늘 날짜 출력
        mPaint.setColor(0xFFFFFF00);
        x = cellWidth * mTodayDate.getDate();
        canvas.drawLine(x, mRect.top, x, mRect.bottom, mPaint);
              
        // 바이오리듬 출력
        if (mBirthDate.getYear() != 0) {
            Log.e("LOG", "year:" + mBirthDate.getYear() +
                    "month:" + mBirthDate.getMonth() +
                    "day:" + mBirthDate.getDate());
           
            double startDays = mStartDays;
            double birthDays = mBirthDate.getTime()/mTDV;
                 
            for (int k = 0; k < mMaxType; k++) {
                x = 0;
             
                mPaint.setColor(mColors[k]);
             
                for (int i = 0; i <= mMaxDays; i++) {
                    double gab = birthDays - startDays;
                    double p = (int)(Math.sin((gab/mBioValues[k]) * 2.0 * mPI) * 100.0);
   
                    y = mRect.bottom/2 + (int)(p * ((mRect.bottom/2.0)/100.0));
                   
                    if (i != 0)
                        canvas.drawLine(x, oldY, x + cellWidth, y, mPaint);
                   
                    oldY = y;
                    startDays++;
                    x += cellWidth;
                }
            }
        }
        
        super.onDraw(canvas);
    }
}

* main.xml
GUI를 정의하는 곳입니다. 이곳에서의 수정은 아래의 R.java의 R 클래스에 자동으로 적용이 됩니다. com.zzerr.BioView와 같이 사용자 클래스도 정의하여 사용할 수 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#666666"
    >

<com.zzerr.BioView android:id="@+id/myView"
    android:layout_width="fill_parent"
    android:layout_height="330px"
    android:background="#000000"
    />
   
<TextView android:id="@+id/helpLabel"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/myView"
    android:layout_marginTop="20px"
    android:text="생년월일을 입력후에 보기버튼을 클릭해 주세요."
    />

<EditText android:id="@+id/inputYear"
    android:layout_width="80px"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:text=""
    />

<EditText android:id="@+id/inputMonth"
    android:layout_width="60px"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@id/inputYear"
    android:layout_alignTop="@id/inputYear"
    android:text=""
    />

<EditText android:id="@+id/inputDay"
    android:layout_width="60px"
    android:layout_height="wrap_content"
    android:layout_below="@id/myView"
    android:layout_toRightOf="@id/inputMonth"
    android:layout_alignTop="@id/inputMonth"
    android:text=""
    />
       
<Button android:id="@+id/showButton"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_alignParentRight="true"
     android:layout_marginLeft="10px"
     android:layout_toRightOf="@id/inputDay"
     android:layout_alignTop="@id/inputDay"
     android:text="보기"
     />

</RelativeLayout>

* R.java
주석에 설명되어 있는 것과 같이 자동으로 생성해 주는 파일입니다. main.xml을 편집하면 자동으로 그에 맞게 내용이 변경됩니다.
/* AUTO-GENERATED FILE.  DO NOT MODIFY.
 *
 * This class was automatically generated by the
 * aapt tool from the resource data it found.  It
 * should not be modified by hand.
 */

package com.zzerr;

public final class R {
    public static final class attr {
    }
    public static final class drawable {
        public static final int icon=0x7f020000;
    }
    public static final class id {
        public static final int helpLabel=0x7f050001;
        public static final int inputDay=0x7f050004;
        public static final int inputMonth=0x7f050003;
        public static final int inputYear=0x7f050002;
        public static final int myView=0x7f050000;
        public static final int showButton=0x7f050005;
    }
    public static final class layout {
        public static final int main=0x7f030000;
    }
    public static final class string {
        public static final int app_name=0x7f040001;
        public static final int hello=0x7f040000;
    }
}

Xcode와 Objective-C를 사용하는 아이폰 개발과는 달리 많은 개발자들에게 익숙한 이클립스와 Java를 사용하고, 윈도우 PC에서도 개발이 가능하니 시작하기는 더 쉬울 것 같다는 생각이 듭니다. 개발자 등록도 25달러로 더 저렴하고요. ^^

구글이 안드로이드 플랫폼 소스를 공개하였습니다. 플랫폼 전체 를 오픈소스로 만들어 버리는 것을 보면 과연 구글이라는 생각이 듭니다. 좌측은 안드로이드 캐릭터의 오픈소스 버젼입니다. 뚜껑을 열어 머릿속을 훤히 보여 주고 있습니다. ^^

다운로드 받아 볼까 했는데 파일크기가 2.1GB이고 6GB의 공간이 필요하기 때문에 다음 기회로 미루었습니다. '설치를 위해서는 Linux 또는 OS X가 필요하고 윈도우즈는 아직 지원하지 않는다'는 흔히 볼 수 없는 문구도 재미있습니다. 

이와 함께 안드로이드 개발자 블로그를 보면 Android Market: Now available for users란 제목으로 애플의 앱스토어와 유사한 어플리케이션 마켓을 런칭했다는 포스팅이 올라왔습니다. 현재까지는 50개의 어플리케이션이 올라와 있고 10월 27일 부터는 일반 개발자들도 어플리케이션을 등록할 수 있다고 합니다.

흥미로운 것은 개발자들에게 70%의 수익이 돌아 가는 부분은 애플의 앱스토어와 같지만, 나머지 30%에서도 구글은 수익을 가지고 가지 않는다고 합니다. 아무리 구글의 모토가 "Don't be evil"이지만 어지간히 통 큰 기업이 아닐 수 없네요.

개발자는 쉽게 유통시킬 수 있고 사용자는 경쟁적인 저렴한 가격에 소프트웨어를 구입할 수 있으니, SDK를 제공하고 온라인 상점을 이용해 개발자와 사용자를 직접 이어주는 이런 서비스가 많이 생기는 것은 양쪽 모두가 반길만한 일이라고 생각됩니다. 요즘 경제위기와 함께 IT의 빙하기가 도래한 우리나라 개발자들에게는 더 반가운 소식일 것 같습니다.

아이폰을 기다리다 지쳐 아이팟을 구입했는데, 문득 잘 한 것 같다는 생각이 듭니다. 휴대폰은 구글폰으로 구입해서 구글폰과 아이폰을 같이 가지고 다니면 심심할 일이 별로 없을 것 같습니다.

사용자 삽입 이미지
어제 구글의 Android SDK 공개 기사를 보고 설치해 볼려고 Android 사이트를 살펴 보았습니다. 하지만 인텔맥에서만 된다기에 좌절하고 퇴근후에 집의 인텔 맥미니에 설치를 해보았습니다.

좌측의 아이콘은 안드로이드 에뮬레이터 아이콘입니다. 귀엽습니다.

구글폰이나 Android 소식을 간간히 접하면서 맥의 위젯과 같이 막연히 Ajax를 사용하는 자바스크립트를 사용할 것 같다는 추측을 해보았습니다. 구글의 주력 서비스들이 웹 기반이고 구글의 오픈 API와 연동을 위해서도 웹 기반일거라 생각했습니다.

하지만 어제 다운로드 받아서 확인을 해보니 자바 스크립트가 아니고 자바였습니다. 구글의 능력으로 보았을 때는 충분히 새로운 개발환경(IDE)을 배포할 것 같았는데, 이클립스의 플로그인 형태로 배포 되었습니다.

완전히 새로운 개발환경보다는 이클립스라는 익숙한 개발 환경과 자바라는 대중적인 언어를 선택함으로 기존 개발자들이 쉽게 적응할 수 있을 것으로 보여 집니다.


1. Android SDK 및 이클립스 플러그인 설치
Apach Ant
JDK 5/6도 지원하지만 이클립스로 설치해 보았습니다. 구글도 이클립스를 적극적으로 지원하는 것 같습니다.

1) 이클립스 설치
이클립스가 설치되어 있지 않다면 먼저 이클립스를 다운 받습니다. 전 3.2 버젼이 깔려 있었습니다. 그런데 프로젝트를 만들 때 오류 메시지를 표시해 주지 않아서 헤매다가 3.3을 설치하니 정확히 동작했습니다.

2) Android SDK 설치
이제 Android SDK를 다운 받습니다. Android는 OS X 10.4.8 이상의 인텔맥에서만 설치가 가능합니다. 압축파일만 풀면 되니 쉽게 설치하실 수 있습니다. Android SDK의 압축을 풀면 "android_sdk_darwin_m3-rc20a"와 같은 복잡한 이름의 디렉토리가 생성되는데 접근이 용이하게 Android로 변경해 주고 원하는 위치로 이동 합니다. 저는 잠시만 사용해 보고 삭제할 것이기 때문에 데스크탑에다 디렉토리를 가져다 놓았습니다.

설치가 완료되면 실행파일을 위한 패스를 지정해 줍니다. .bash_profile에 패스를 지정해 주거나 각자의 환경에 맞게 터미널에서 아래와 같이 실행합니다.
> export PATH=/Users/zzerr/Desktop/android/tools


3) ADT 설치
이제 ADT(Android Development Tools)라는 이클립스 플러그인을 설치합니다. 안드로이드 사이트에는 선택사항이라고 되어 있지만, 이클릭스를 사용한다면 필수로 설치를 해야 될 것 같습니다.

a. 이클립스의 헬프 메뉴에서 Software Updates > Find And Install...을 선택합니다.
b. Search for new features to...을 선택하고 Next를 클릭합니다.
c. 우측의 버튼중에 첫번째 New Remote Site...를 클릭합니다.
d. 아래와 같이 Name에 Android Plugin을 입력하고 URL에 https://dl-ssl.google.com/android/eclipse/ 을 입력한 후에 OK를 클릭하고 완료되면 Finish 버튼을 클릭합니다.
사용자 삽입 이미지











e. 다음 단계에서 아래와 같이 Android Plugin을 체크하고 Next 버튼을 클릭합니다.
사용자 삽입 이미지




















f. 라이센스에 동의에 체크하고 Next 버튼을 클릭한 후에 Finish버튼을 클릭합니다.
g. Install All 버튼을 클릭하면 설치 후에 이클립스가 재실행 됩니다.

이클립스의 Preferences... 메뉴를 클릭하고 Android를 선택합니다. 아래와 같이 SDK Location에 이전 단계에서 설치한 Android SDK의 디렉토리를 설정합니다.
사용자 삽입 이미지

"이제 사용할 준비가 완료되었습니다."


2. 샘플 프로젝트 작성

1) 프로젝트 생성
이클립스에서 File > New > Project... 를 클릭하고, Android Project를 선택한 후에 Next 버튼을 클릭합니다.

Project name과 Package Name, Activity name, Application Name을 각각 입력하고 완료 버튼을 클릭합니다. 저는 아래와 같이 입력하였습니다. Application name에 testAndriod로 잘 못 입력하여 나중에 에뮬레이터 화면에서도 Andriod로 나옵니다.
사용자 삽입 이미지

2)  코드 작성
완료되면 아래와 같은 안드로이드 이클립스 개발환경이 나옵니다.
사용자 삽입 이미지

여기선 전 샘플코드를 둘러 보다가 그래픽 샘플코드에서 점을 랜덤하게 출력하는 소스를 복사해서 아래와 같이 만들어 보았습니다.

package com.cocoa;

import android.app.Activity;
import android.os.Bundle;
import android.content.Context;
import android.graphics.*;
import android.view.View;

import java.util.Random;
public class hello extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(new SampleView(this));
    }
   
    private static class SampleView extends View {
        private Paint   mPaint = new Paint();
        private float[] mPts = new float[1000];

        public SampleView(Context context) {
            super(context);
           
            Random rand = new Random();
            final int N = mPts.length >> 1;
            for (int i = 0; i < N; i++) {
                mPts[(i << 1) + 0] = rand.nextFloat() * 320;    // X
                mPts[(i << 1) + 1] = rand.nextFloat() * 240;    // Y
            }
        }
   
        @Override protected void onDraw(Canvas canvas) {
            Paint paint = mPaint;

            canvas.drawColor(Color.WHITE);

            paint.setColor(Color.BLACK);
            paint.setAntiAlias(false);
            paint.setStrokeWidth(10);
       
            canvas.drawPoints(mPts, paint);
        }
    }
}


사용자 삽입 이미지
이제 실행해 보면 좌측과 같은 다이알로그 박스가 나오는데 Android Application을 선택하시고  OK버튼을 클릭합니다
 







아래는 에뮬레이터에서 실행된 모습입니다. 이미지 사이즈를 줄였지만 상당히 큽니다. 맥미니에 연결된 24인치 모니터에 아래와 같은 것이 뜨니 처음에는 핸드폰 에뮬레이터가 아니라 무슨 타자기 에뮬레이터가 뜨는 줄 알았습니다.
사용자 삽입 이미지

기존 자바 개발자나 C#으로 윈도우 모바일 개발 경험이 있는 개발자들은 별다른 노력 없이 쉽게 구글폰 어플리케이션을 제작할 수 있을 것 같습니다. 구글에서 많은 상금이 걸린  Developer Challange도 개최하니 우리나라 개발자들이 많은 상금을 가져 올 수 있었으면 좋겠습니다.


3. 사족 - MS Windows Mobile

이런류의 기기들을 좋아해서 오래전 WinCE 1.0이 탑재된 LG PDA를 구입을 시작으로 현재는 윈도우즈 모바일 5.0의 삼성 블랙잭을 사용하고 있습니다. PC와 인터넷에서의 경쟁이 이제 윈도우즈 모바일을 탑재한 스마트폰, 애플의 아이폰, 구글의 구글폰으로 모바일에서 까지 달아 오르는 것 같습니다.

OS/개발환경/브라우져도 그렇고 경쟁자가 없으면 나태해지는 MS도 이제 바짝 달려야 할 것 같습니다. 다른 건 몰라도 디자인적인 측면에서  신경을 좀 써주었으면 합니다.

아래의 이미지가 제 블랙잭의 스크린샷입니다. 초기화면은 어디선가 다운로드 받은 맥 테마를 변경하여 사용하고 있습니다. 여느 아빠들과 마찬가지로 핸드폰 초기화면은 제 아들 녀석이 자리잡고 있습니다.

우측은 윈도우즈 모바일의 탐색기 이미지입니다. 흑백에서 칼라로 바뀐 것을 제외하고는 10년 전에 본 모습 그대로 입니다. 한때 디자이너가 없다던 소문이 돌던 구글 디자인 컨셉 같습니다.
사용자 삽입 이미지사용자 삽입 이미지

모바일 기기의 특성상 가능하면 메모리와 저장 공간을 줄여야 하는 것은 알지만 보기에도 좋았으면 좋겠습니다. 제 취향이 이상한 건지도 모르겠습니다. 간혹 급하게 메모할 일이 생길 때면 기본 메모장을 이용하는데 윈 3.1 시절의 향수를 느끼게 해줍니다. 언제 시간날 때 기능은 없고 보기에는 좋은 메모장이나 하나 만들어 볼려고 합니다.