안드로이드 개발자랩

오늘 오후 1시부터 리츠칼튼 호텔에서

안드로이드 개발자랩 행사가 열렸습니다.

사전에 신청을 하고 초청되어 방문하게 되었지요.

리츠칼튼 호텔이 외부에서만 보다가 

들어서보니 무척이나 고급스러운 호텔이었습니다.

학생차림들의 사람들이 여기에 모이는 것이

이상스러울 수도 있겠더군요.

호텔직원의 안내를 받고 내려가 보니 안드로보이가 행사장을 가리키고 있었습니다.



도착하니 막 행사를 시작하려고 준비중이었습니다.

홀에는 admob을 홍보하는 부스와 이름표를 나누어 주고 있더군요. 
발표장은 입장을 제한하고 있어서 한산했고 리허설 중이었습니다.



행사가 시작되고 다음의 순서로 진행되었습니다.

1. 인사말 : 조원규, 구글코리아 R&D 센터 총괄
2. 안드로이드 플랫폼 및 마켓 최신정보소개 : Bill Luan, Developer Technical Program Manager
3. UI 디자인패턴과 애플리케이션 팁 : Ken Liu, Developer Advocate
4. 안드로이드 마켓 라이센싱: Tony Chan, Developer Advocate
5. 안드로이드 NDK 및 C++ 개발정보 : Cris Pruett, Senior Developer Advocate
6. 구글광고를 활용한 모바일 트래픽 수익 극대화 방안 : 민경환, 구글코리아
7. 한국개발자 쇼케이스 : 강순권, Neowiz

우선 조원규 센터장이 나와서 개발자 행사를 하개된 내용 등 소개를 했습니다.
여기서 에릭 슈미트가 얼마전 모바일 콩그레스에서 한 말을 인용했습니다.
"Mobile First" 
구글도 모바일이 얼마나 성장하고 있는지 알고 있으며 이 방향으로 나간다고 하더군요.



그 다음 "Bill Luan" 이라는 분이 나왔습니다.
다음 세가지 주제로 얘기했습니다.

1. Mobile Market Trend
2. Opportunities
3. Android Market

우선 첫번째는 다음의 다섯가지 트렌드를 얘기 했습니다.
1. 더 많은 디바이스들이 만들어 지고 있고,
2. 데스크탑보다 더 빨라지고 있으며
여기서 다음 5가지 융복합 트랜드를 강조했지요.
(3G + Social Network + Video + VoIP + Impressive Mobile Device)
3. Wealth creation
4. New App이 새로운 비지니스를 만든다.
5. 개발자와 OEM사들이 개방된 안드로이드를 사용한다.
대부분 알고 있는 얘기이긴 합니다.
여기서 더욱 강조하는 부분은 매일 20만대의 안드로이드폰이 Activation 되고 있다는 것이 었지요.

두번째는 앱의 새로운 영역에 대한 내용이었습니다.
1. Location based service 
2. Transparent pricing
3. Deep discount
4. Immediate gratification

세번째는 안드로이드 마켓에 대한 강점부분이었습니다.
앱의 랭킹은 다음의 내용으로 순위가 매겨진다고 하는 군요.
 - relevance, downloads, ratings, retention, others



그 다음은 UI Design pattern 에 대한 내용으로 Ken Liu 라는 개발자가 발표했습니다.
이 발표가 전체 내용중 가장 재밌고 퀴즈와 상품이 많았지요.
여기서 꽤 많은 유익한 내용들을 설명했습니다.
주요한 Design Pattern은 다음과 같습니다.
Dashboard
Action Bar
Quick Action
Search Bar
Companion Widget

아이폰과 달리 안드로이드에서 강조하는 UI 패턴들입니다.
좋은 인터페이스 디자인의 원칙은 다음과 같습니다.
1. Focus on the user
2. Make the right thins visible
3. Show proper feedback
4. Be predictable
5. Be fault-tolerent

이외에 해야할 것과 하지 말아야 할 것들도 알려주었는데, 다음에 정리하겠습니다.



이후 쉬는 시간이 이어지고 커피와 다과를 먹을 수 있었습니다.
홀에는 안드로보이 분장을 한 두명이 돌아다녔고 사람들과 사진을 찍었습니다.



이후 세션에는 마켓 라이센싱이라는 주제로 Tony Chan 이라는 개발자가 발표를 했고
발표자료를 읽으면서 하는 스타일이라 좀 졸립긴 했습니다.
이 내용에서는 License Verification Library 즉 LVL 을 설명했고, 앱과 결합하여 라이센스를 지켜주는 역할에 대해 설명했습니다.


그 다음 세션은 안드로이드 NDK 개발에 대한 내용을 Chris Pruett 라는 개발자가 발표했습니다.
C++로 만들어진 라이브러리를 안드로이드에서 활용하는 기법에 대해 설명했는데, 
이 부분은 아직 관심이 없어 집중력이 좀 떨어졌습니다.
기존에 레거시 프로그램이 있는 회사 혹은 개발자라고 하면 꽤 비중있게 생각될 수 도 있는 부분입니다.
발표한 개발자가 게임을 개발했는데, OpenGL 이나 오디오 등의 라이브러리를 NDK를 이용해서 개발했다고 하네요.
여기에 관심이 좀 더 있었으면 좀 더 잘 알 수 있지 않았을까하는 아쉬움도 조금 남더군요.



그 다음 모바일 트래픽 수 극대화 방안을 민경환 씨가 발표했습니다.
오른쪽 사진에서 도표가 admob을 이용한 마케팅의 사례였습니다.
상위권 앱에 속한 후 광고비를 줄여나가는 방식에 대해 설명했습니다.
admob을 구글에서 인수한 만큼, 많은 자료들이 admob에서 조사된 내용이었습니다.



마지막 Neowiz 랩의 강순권씨의 발표에서 주 내용은 웹개발자들은 안드로이드 개발에 접근하기 쉽다는 것이었습니다.
발표자가 웹개발자였고 그 경험에 따르면 접근하기 쉬운 개념은 아래였고,
 . Layout, Intent, Acivity/Task, Sqlite, Http, JSON, XML
어려운 개념은 아래였습니다.
. Thread(Async Task), Life cycle, 2D graphic, 3D on OpenGL

이 후 Q&A 를 가졌는데요.
여러 질문들이 있었는데, 동시통역이 좀 원만하지 않은 것 같아서 좀 아쉬웠습니다.
기억할 만한 질문은 로드맵에 대한 것이었습니다. 모바일이후의 로드맵에 대해서는 이들도 모른다는 것이었습니다.
구글회사가 그들에게 공유해 주지 않았다기 보다 로드맵을 세우기가 시장이 너무 급변해서 그런게 아닐까 하는 생각이 들었습니다.



모든 행사가 끝나고 다들 설문지 내고 선물을 받아가느라 매우 혼란스럽더군요.

선물은 T셔츠만 있는줄 알았더니, 귀마개랑 USB메모리도 있더군요.



안드로이드에 대해 구글에서 열리는 공식적인 행사라 더욱 뜻깊었던것 같습니다.

개발자 커뮤니티에도 좀더 관심을 보여줬으면 하는 아쉬움과 기대가 남네요...

구글에서 제공해주는 저녁이 있었으면 더 좋았을텐데 하는 생각도 해봅니다...^^


  363번 포스트에 대한 질문을 정리해 봅니다.

  질문은 3D 모델을 안드로이드에 가져왔을때

  배경이 검게 나오는 상황입니다.

  모델은 어떤 그래픽 툴에서 그렸건 상관없을 것 

  같네요. 지금 전 Blender 를 선호하고 있지만,

  익숙한 툴을 사용하는게 제일 좋을 것 같고요.

  어찌됐건 안드로이드에서 보이기 위한 데이터는 

  vertices, colors, indices 로 각각 배열값을 가지고 있을 거라고 봅니다.

  모델은 잘보이는 것 같고요. 단지 배경이 검게 나오는 것이 문제로 보이는데

  363포스트에서 코드앞에 언급했다시피, 

  Cube.java 와 CubeRenderer.java 를 참조하고 있습니다.

  Cube.java 는 단지 모델을 그리는 용도이고, CubeRenderer.java 는 

  렌더링하는 속성들을 가지고 있다고 볼 수 있지요.

  카메라와 OpenGL을 동시에 오버레이 해서 보여줄려면, 

  우선 OpenGL의 그리는 배경속성이 투명해야 합니다.

  그래서 CubeRenderer.java 파일을 한번 보겠습니다.
----------------------------------------------------------------------------
package com.google.android.XXXXXX;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView;

/**
 * Render a pair of tumbling cubes.
 */

class CubeRenderer implements GLSurfaceView.Renderer {
    public CubeRenderer(boolean useTranslucentBackground) {
        mTranslucentBackground = useTranslucentBackground;
        mCube = new Cube();
    }

    public void onSensor(float x, float y){
     //float dx = x - mPreviousX;
        //float dy = y - mPreviousY;
     mAngleX = x; //+= dx ;
        mAngleY = y;//+= dy ;
     //return true;
    }
    
    public void onDrawFrame(GL10 gl) {
        /*
         * Usually, the first thing one might want to do is to clear
         * the screen. The most efficient way of doing this is to use
         * glClear().
         */

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        /*
         * Now we're ready to draw some 3D objects
         */

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
       
        gl.glTranslatef(0, 0, -3.0f);
        gl.glRotatef(mAngleX, 0, 1, 0);
        gl.glRotatef(mAngleY, 1, 0, 0);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

        mCube.draw(gl);

    }

    public int[] getConfigSpec() {
        if (mTranslucentBackground) {
                // We want a depth buffer and an alpha buffer
                int[] configSpec = {
                        EGL10.EGL_RED_SIZE,      8,
                        EGL10.EGL_GREEN_SIZE,    8,
                        EGL10.EGL_BLUE_SIZE,     8,
                        EGL10.EGL_ALPHA_SIZE,    8,
                        EGL10.EGL_DEPTH_SIZE,   16,
                        EGL10.EGL_NONE
                };
                return configSpec;
            } else {
                // We want a depth buffer, don't care about the
                // details of the color buffer.
                int[] configSpec = {
                        EGL10.EGL_DEPTH_SIZE,   16,
                        EGL10.EGL_NONE
                };
                return configSpec;
            }
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
         gl.glViewport(0, 0, width, height);

         /*
          * Set our projection matrix. This doesn't have to be done
          * each time we draw, but usually a new projection needs to
          * be set when the viewport is resized.
          */

         float ratio = (float) width / height;
         gl.glMatrixMode(GL10.GL_PROJECTION);
         gl.glLoadIdentity();
         gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        /*
         * By default, OpenGL enables features that improve quality
         * but reduce performance. One might want to tweak that
         * especially on software renderer.
         */
        gl.glDisable(GL10.GL_DITHER);

        /*
         * Some one-time OpenGL initialization can be made here
         * probably based on features of this particular context
         */
         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
                 GL10.GL_FASTEST);

         if (mTranslucentBackground) {
             gl.glClearColor(0,0,0,0);
         } else {
             gl.glClearColor(1,1,1,1);
         }
         gl.glEnable(GL10.GL_CULL_FACE);
         gl.glShadeModel(GL10.GL_SMOOTH);
         gl.glEnable(GL10.GL_DEPTH_TEST);
    }
    private boolean mTranslucentBackground;
    private Cube mCube;
    public float mAngleX;
    public float mAngleY;
}

  위의 코드에서 녹색으로 표시된 부분이 투명한 처리를 하는 부분입니다.

즉, 363포스트에서 camGL 클래스에서 초기 생성시에 투명처리를 위해 아래와 같이 하는 부분이 있습니다.

                  mRenderer = new CubeRenderer(true);

        

        mGLSurfaceView = new GLSurfaceView(this);

                  //translucent

        mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);

        mGLSurfaceView.getHolder().setFormat(PixelFormat.RGBA_8888);

        mGLSurfaceView.setRenderer(mRenderer);


translucent 부분이 투명처리하는 부분인데, 카메라부분인 preview 객체를 생성하지 않으면 바탕화면 위에


도형이 그려지는 것을 볼 수 있어야 합니다. 확인하려면, preview 객체 생성부분을 주석처리해서 확인해 보십시오.


만약 거기서도 바탕화면이 투명처리가 안된다면, 다음을 확인해 보시기 바랍니다. (AndroidManifest.xml, 적색코드)


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

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

      package="com.google.android.XXXXX"

      android:versionCode="1"

      android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <activity android:name=".XXXXX"

                  android:label="@string/app_name"

                  android:theme="@android:style/Theme.Translucent">

            <intent-filter>

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

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

            </intent-filter>

        </activity>

    </application>

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

</manifest> 


한번 해보시고 결과를 댓글로 남겨주세요.



Blender 로 3D 도형 만들기 .. 1

  Blender 로 3D 도형을 만들고 

  아이폰에서 OpenGL 로 보이는 것을 쓰겠다고 

  해놓고선 한참지났네요.

  앱의 마케팅을 하느라 해봤지만, 역시나

  8만개나 되는 앱들에 묻혀서 다운수가 늘지가 않는군요..^^;

  지금의 Blender 로 만드는 도형의 방법은 안드로이드에서도 

  동일하게 적용하시면 됩니다. 단, 출력된 값을 정수형으로 변경해야

  하는 것만 유념하면 될 것 같습니다. 아직 시험은 안해봤지만요...

  Blender 는 무료 공개 소프트웨어로 검색하시면 쉽게 다운로드 받을 수 있습니다.

  실행하면 아래와 같습니다.


  기본으로 정육면체가 만들어져 있습니다.
  Blender 웹페이지에 사용법이 있으니 여기서는 자세한 사용법보다는 아이폰에서 사용하기 위한
  용도위주로 설명해보겠습니다.
  Blender 의 사용법은 약간 기존의 마우스와 키보드 사용법과 다르기 때문에 생소할 수 있습니다.
  스페이스바를 누르면 메뉴가 나오게 되고 "Add"를 선택하면 기본 도형을 만들 수 있습니다.
  원통을 만들어 보기로 하죠. Add>Cylinder 를 선택합니다.


  cylinder 를 선택하고 나면 아래와 같이 추가메뉴가 나오는데 반경과 높이 등을 설정하고 나면 도형이 생성됩니다.


도형은 수직에서 쳐도보도록 되어 있는데, 마우스의 볼을 누르고 움직이면 좌표가 회전되는 것을 볼 수 있습니다.


여기서 Edit 모드를 선택하면 꼭지점과 모서리가 선택되어 보여집니다.
아래에서 보듯이 원통에서 원부분은 삼각형으로 나누어져 있고, 통부분은 사각형으로 만들어져 있습니다.
이렇게 되어 있으면 도형의 값을 추출했을때 OpenGL 로 변경하면 이상한 모양으로 변경됩니다.
OpenGL에서 도형을 만들때는 삼각형을 이용하기 때문입니다.
그래서 삼각형으로 도형을 다시 잘라내야 합니다.
Edit>Faces>Convert to Triangles 를 선택하면 도형이 삼각형으로 다시 잘라집니다.


아래를 보시면 도형의 모양이 삼각형으로 되어 있는 것을 볼 수 있습니다.
  


  다음 편에서는 이렇게 만든 도형을 데이터로 뽑는 과정을 정리해 보겠습니다.