2013년 8월 16일 금요일

Drawing Shapes











import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

private GLSurfaceView mGLView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);    
     
        //setContentView(R.layout.activity_main);
     
     
        // Create a GLSurfaceView instance and set it
        // as the ContentView for this Activity.
     
        mGLView = new MyGLSurfaceView(this);
        setContentView( mGLView);      
     
    }
 

    @Override
    protected void onPause() {
   
        super.onPause();
     
        // The following call pauses the rendering thread.
        // If your OpenGL application is memory intensive,
        // you should consider de-allocating objects that
        // consume significant memory here.
        mGLView.onPause();
    }
 
    @Override
    protected void onResume() {
   
        super.onResume();
     
        // The following call resumes a paused rendering thread.
        // If you de-allocated graphic objects for onPause()
        // this is a good place to re-allocate them.
        mGLView.onResume();
    }  


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        // getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
 
}


----------------------------------------------------------------------





import android.content.Context;
import android.opengl.GLSurfaceView;


public class MyGLSurfaceView extends GLSurfaceView {

public MyGLSurfaceView(Context context) {

super(context);


// Create an OpenGL ES 2.0 context
setEGLContextClientVersion(2);



// Set the Renderer for drawing on the GLSurfaceView
setRenderer( new MyRenderer());


// Render the view only when there is a change in the drawing data
setRenderMode( GLSurfaceView.RENDERMODE_WHEN_DIRTY);


}


}


----------------------------------------------------------------------




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

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

public class MyRenderer implements GLSurfaceView.Renderer {


private Triangle mTriangle;


@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {

// Set the background frame color
GLES20.glClearColor( 1.0f, 0.0f, 0.0f, 1.0f);

mTriangle = new Triangle();

}

@Override
public void onDrawFrame(GL10 gl) {

// Redraw background color
GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT );


mTriangle.draw();

}


@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {

GLES20.glViewport( 0, 0, width, height);

}


    public static int loadShader(int type, String shaderCode){

        // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
        // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
        int shader = GLES20.glCreateShader(type);

        // add the source code to the shader and compile it
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);

        return shader;
    }


}


----------------------------------------------------------------------





import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import android.opengl.GLES20;

public class Triangle {

    private final String vertexShaderCode =
            "attribute vec4 vPosition;" +
            "void main() {" +
            "  gl_Position = vPosition;" +
            "}";

        private final String fragmentShaderCode =
            "precision mediump float;" +
            "uniform vec4 vColor;" +
            "void main() {" +
            "  gl_FragColor = vColor;" +
            "}";



private FloatBuffer vertexBuffer;
    private final int mProgram;
    private int mPositionHandle;
    private int mColorHandle;

// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;

static float triangleCoords[] = {
0.0f,  0.622008459f, 0.0f,
  -0.5f, -0.311004243f, 0.0f,
0.5f, -0.311004243f, 0.0f
};

    private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
    private final int vertexStride = COORDS_PER_VERTEX * 4; // bytes per vertex



float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };

public Triangle() {



// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(


// (number of coordinate values * 4 bytes per float)
triangleCoords.length * 4

);


// use the device hardware's native byte order
bb.order( ByteOrder.nativeOrder() );

// create a floating point buffer from the ByteBuffer
vertexBuffer = bb.asFloatBuffer();

// add the coordinates to the FloatBuffer
vertexBuffer.put(triangleCoords);

// set the buffer to read the first coordinate
vertexBuffer.position(0);


        // prepare shaders and OpenGL program
        int vertexShader = MyRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
                                                   vertexShaderCode);
        int fragmentShader = MyRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
                                                     fragmentShaderCode);

        mProgram = GLES20.glCreateProgram();             // create empty OpenGL Program
        GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
        GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
        GLES20.glLinkProgram(mProgram);                  // create OpenGL program executables


}


    public void draw() {
        // Add program to OpenGL environment
        GLES20.glUseProgram(mProgram);

        // get handle to vertex shader's vPosition member
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

        // Enable a handle to the triangle vertices
        GLES20.glEnableVertexAttribArray(mPositionHandle);

        // Prepare the triangle coordinate data
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                                     GLES20.GL_FLOAT, false,
                                     vertexStride, vertexBuffer);

        // get handle to fragment shader's vColor member
        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

        // Set color for drawing the triangle
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);

        // Draw the triangle
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }


}











Hello OpenGL











GLSurfaceView 를 상속받아 View 를 만드는 일.


GLSurfaceView.Renderer 를 상속받아 renderer 를 만드는 일.






--------------------------------------------------------------



import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

private GLSurfaceView mGLView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);       
        
        //setContentView(R.layout.activity_main);
        
        
        // Create a GLSurfaceView instance and set it
        // as the ContentView for this Activity.
        
        mGLView = new MyGLSurfaceView(this);
        setContentView( mGLView);        
        
    }
    

    @Override
    protected void onPause() {
   
        super.onPause();
        
        // The following call pauses the rendering thread.
        // If your OpenGL application is memory intensive,
        // you should consider de-allocating objects that
        // consume significant memory here.
        mGLView.onPause();
    }
    
    @Override
    protected void onResume() {
   
        super.onResume();
        
        // The following call resumes a paused rendering thread.
        // If you de-allocated graphic objects for onPause()
        // this is a good place to re-allocate them.
        mGLView.onResume();
    }    


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        // getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}




--------------------------------------------------------------






import android.content.Context;
import android.opengl.GLSurfaceView;


public class MyGLSurfaceView extends GLSurfaceView {

public MyGLSurfaceView(Context context) {

super(context);
// Create an OpenGL ES 2.0 context
setEGLContextClientVersion(2);

// Set the Renderer for drawing on the GLSurfaceView
setRenderer( new MyRenderer());
// Render the view only when there is a change in the drawing data
setRenderMode( GLSurfaceView.RENDERMODE_WHEN_DIRTY);

}


}


--------------------------------------------------------------



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

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

public class MyRenderer implements GLSurfaceView.Renderer {

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Set the background frame color
GLES20.glClearColor( 1.0f, 0.0f, 0.0f, 1.0f);
}
@Override
public void onDrawFrame(GL10 gl) {
// Redraw background color
GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT );
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {

GLES20.glViewport( 0, 0, width, height);
}


}



















2013년 8월 15일 목요일

Google Play




한국은 2010년 10월 부터 유료 앱을 판매할 수 있게 되었다.







Google Play에서 개발자가 앱을 판매하려면 30%의 수수료를 지불해야한다.


수수료
Google Play에서 판매하려는 애플리케이션의 수수료는 애플리케이션 가격의 30%입니다. 예를 들어 애플리케이션을 $10.00에 판매하는 경우 수수료는 $3.00이고 $7.00를 지불 받게 됩니다.



Google Play에서 구매한 사용자는 15분 내에 구매를 취소할 수 있다.


구매 취소
구매자는 Google Play에서 프로그램을 다운로드한 후 15분 내에 구매를 취소할 수 있습니다.이 취소 기간이 만료되면 자동으로 신용카드에 금액이 청구되며 해당 판매 대금 지급 일정에 따라 계정에 지급을 개시합니다.


판매 대금은 전자송금된다.


애드센스 계정이 필요한 지역
2011년 8월 2일 이후에 만든 Google 지갑 판매자 센터 계정을 보유한 대한민국 내 개발자는 판매 대금을 수령하기 위해 애드센스 계정을 만들 필요가 없습니다. 해당 판매 대금은 Google Checkout 계정에서 한국 원(KRW) 단위로 전자송금을 통해 처리됩니다.


1달러 이상인 금액만 송금된다.


지불 또는 송금 시 수익은 최소 미화 1달러여야 합니다.


새 개발자 계정에 가입하는데드는 비용은 2013년 8월 현재 미화 25달러이다.



2013년 8월 현재 Google Checkout 판매자로 등록하여 유료 애플리케이션을 판매할 수 있는 국가는 32개 국이다.


아르헨티나
호주
오스트리아
벨기에
브라질
캐나다
체코
덴마크
핀란드
프랑스
독일
홍콩
인도
아일랜드
이스라엘
이탈리아
일본
멕시코
네덜란드
뉴질랜드
노르웨이
폴란드
포르투갈
러시아
싱가포르
스페인
대한민국
스웨덴
스위스
대만
영국
미국







2013년 8월 현재, 유료 앱 판매가능 국가의 개발자는 134개국에 판매할 수 있다.




알바니아
알제리
앙골라
안티가 바부다
아르헨티나
아르메니아
아루바
오스트레일리아
오스트리아
아제르바이잔
바하마
바레인
방글라데시
벨라루스
벨기에
벨리제
베냉
볼리비아
보스니아 헤르체코비나
보츠와나
브라질
불가리아
부르키나파소
캄보디아
카메룬
캐나다
카보베르데
칠레
콜롬비아
코스타리카
코트디부아르
크로아티아
키프로스
체코
덴마크
도미니카 공화국
에콰도르
이집트
엘살바도르
에스토니아
피지
핀란드
프랑스
가봉
독일
가나
그리스
과테말라
기니비사우
아이티
온두라스
홍콩
헝가리
아이슬란드
인도
인도네시아
아일랜드
이스라엘
이탈리아
자메이카
일본
요르단
카자흐스탄
케냐
쿠웨이트
키르기스스탄
라오스
라트비아
레바논
리투아니아
룩셈부르크
마케도니아 [FYROM]
말레이시아
말리
몰타
모리셔스
멕시코
몰도바
모로코
모잠비크
나미비아
네팔
네덜란드
네덜란드령 앤틸리스
뉴질랜드
니카라과
니제르
나이지리아
노르웨이
오만
파키스탄
파나마
파푸아뉴기니
파라과이
페루
필리핀
폴란드
포르투갈
카타르
루마니아
러시아
르완다
사우디아라비아
세네갈
싱가포르
슬로바키아
슬로베니아
남아프리카 공화국
대한민국
스페인
스리랑카
스웨덴
스위스
대만
타지키스탄
탄자니아
태국
토고
트리니다드 토바고
튀니지
터키
투르크멘
우간다
우크라이나
아랍에미리트
영국
미국(푸에르토리코, 미국령 사모아, 괌, 마샬 제도, 북마리아나 제도, 팔라우, 미국령 버진 제도 등 포함)
우루과이
우즈베키스탄
베네수엘라
베트남
예멘
잠비아
짐바브웨










134개국중에 중국이 없다!
현재 중국은 전체 스마트폰의 86%가 안드로이드 시스템을 사용하고 있는 상황으로, 중국 정부와 구글의 사이악화로 인해 구글플레이 스토어가 활성화 되지 않아 수 많은 안드로이드 마켓들이 시장을 나누어 가지고 있다.















2013년 8월 14일 수요일

AsyncTask



안드로이드는 AsyncTask 제네릭 클래스를 제공한다.


Thread 에서 UI 업데이트하다가 프로그램이 다운되어본 사람만 안다.
AsyncTask 클래스가 얼마나 편리하고, 고마운것인지.













class AsyncTask

protected abstract Result doInBackground(Params... params)
protected void onPreExecute()
protected void onPostExecute(Result result)
protected void onProgressUpdate(Progress... values)
protected void onCancelled(Result result)
protected final void publishProgress(Progress... values)


doInBackground 가 protected 로 되어있다.
상속받아 써야한다.









2013년 8월 8일 목요일

Play스토어 앱개발자의 운명



애플은 90% 이상의 유저가 최상위 OS 버전을 설치하고 있고, 기종(화면크기,해상도)도 하나다.
따라서, 애플앱스토어에서는 전세계유저 6억중 90%에게 즉각적으로 배포가능한 상태가된다.
따라서 지나야할 터널은 국가별 현지화작업 하나면 끝난다.

앱개발자는 안드로이드 시장에서
국가별, 안드로이드 버전별, 기종별(화면크기,해상도) 로 세분화해서 접근해야한다.
안드로이드 장치수가 많다고 해도, 3개의 터널을 지나고 나면, 시장크기가 현저히 줄어들게된다.

구글은 20135월에 9억개의 안드로이드장치가 활성화되었다고 발표했다.
9억이라는 숫자는 활성화된 유저를 뜻하는것이 아니다.
폰을 교체한경우, 이전 폰의 갯수를 빼주어야 실제 활성유저 숫자가 나온다. 이것이 반영되지 않았다. 실제 활성유저는 9억보다 작을것으로 추정한다.
또한 1인당 2개 이상을 가지고 있는 경우도 있으므로, 실제 활성유저는 더 작을것으로 추정한다.
이런 것들은 반영하여, 임의로 50% ~ 70%로 어림잡아보면 안드로이드 실제 유저는 45천만 ~ 63천만 정도로 추정해볼 수 있다. 크게 잡아 6억이라고 쳐주자.

구매력이 높은 앱스토어유저 6억 대 Play스토어 유저 6.
20135월에 와서야 마켓유저수가 얼추 비슷해졌다고 평가할 수 있다.
애플앱스토어개발자는 앱을 개발하면 6억 유저에게 즉시 배포할 준비가 되어있다.
Play스토어개발자는 앱을 개발하면 6억 유저에게 즉시 배포할 수 없다.
이중 Gingerbread 이하버전인 41.3% 를 제외해야한다.
그러면 실제 유저는 35천만이된다. 시장크기가 절반으로 줄어든다.
애플앱스토어와 Play스토어의 앱매출액 74%20% 는 당연한 결과다.

1. 실제유저를 반영한 시장크기가 애플앱스토어의 절반수준이다.
2. 애플앱스토어의 유저는 미국,일본,영국등 구매력이 높은 선진국에 집중분포되어있다.


Play스토어는 앱스토어에 비해, 물리적 시장크기가 절반이고, 유저의 구매력이 약한 국가에 분포되어있다. 74%20% 는 당연한 결과다.









Gingerbread 이하버전을 제외한 35천만이라는 시장크기.
물론 이 시장크기도 작은 시장 규모는 아니다. 큰 규모다.

그러나, Play스토어개발자는 35천만 유저에게 즉각적으로 앱을 배포할 수 없다.
여기서, 기종(화면크기,해상도)별로 다시 앱을 검증해야 한다.

화면크기만 달라도 앱은 제대로 동작하지 않는다.
유저는 동작하지 않는 앱은 바로 삭제한다.

기종은 각 국가별로 판매량이 다르다.
국가별로 검증해야할 기기가 따로 정해져 있는 셈이다.

다행히도 안드로이드 시장은 고속성장중이다.
2~3년 안에 Gingerbread 이하버전은 모두 Jelly Bean 이상으로 교체될것이다.
그때가되면 시장규모는 다시 지금의 2배이상으로 커질것이다.

그래도 화면크기별 검증작업의 짐은 아직도 남아있다.
이것은 Play스토어개발자가 지고 가야할 운명이다.





앱 시장 크기



안드로이드의 앱시장 크기는 현재 확실치 않다.
여러가지 정황증거로 그 시장크기를 추정해볼 뿐이다.


iOS 의 앱시장 크기는 약 6억이다.
미국,일본,영국등 구매력이 큰 국가에 집중되어 있다. 유저당구매율이 높다.







6억의 시장규모로 Android 앱 매출액을 가볍게 눌러버린다.








Top Five Smartphone Operating Systems, Shipments, and Market Share, 1Q 2013 (Units in Millions)
Operating System
1Q13 Shipment Volume
1Q13 Market Share
1Q12 Shipment Volume
1Q12 Market Share
Year over Year Change
Android
162.1
75.0%
90.3
59.1%
79.5%
iOS
37.4
17.3%
35.1
23.0%
6.6%
Windows Phone
7.0
3.2%
3.0
2.0%
133.3%
BlackBerry OS
6.3
2.9%
9.7
6.4%
-35.1%
Linux
2.1
1.0%
3.6
2.4%
-41.7%
Symbian
1.2
0.6%
10.4
6.8%
-88.5%
Others
0.1
0.0%
0.6
0.4%
-83.3%
Total
216.2
100.0%
152.7
100.0%
41.6%



안드로이드는 분기당 1억대 이상씩 늘어나고 있다.
이 숫자는 증가하고 있다.



앞으로 4년간 스마트폰 판매량은 년간 10억대 이상씩 증가할것으로 예측된다.






20126.
4억개의 안드로이드가 활성화되었다. 하루 1백만의 안드로이드가 새로 개통된다.

20129.
5억개의 안드로이드가 활성화되었다. 하루 13십만의 안드로이드가 새로 개통된다.

20135.
9억개의 안드로이드가 활성화되었다. ( 1년전 4억개. 1년만에 시장이 2배로 커짐.)
480억개의 앱이 설치됨.
25억개의 앱이 한달에 설치됨.
안드로이드 앱 개발자에게 돌아가는 매출액이 1년전보다 2.5배 증가함.
( 1년만에 앱 개발자 매출액이 2.5배로 커짐. 시장이 커진비율 만큼, 매출액에 그대로 반영됨. 이것이 사람들이 말하는 규모의 경제.)



안드로이드 시장은 계속 커지고 있다.
세계인구 70억인데, 보급된 안드로이드는 겨우 9억개 뿐이다.


년간 10억대씩 증가한다고 가정하면 앞으로 6년간 시장은 계속 커질것이다.
증가비가 감소한다하더라도 앞으로 10년간 시장은 계속 커질것이다.
통신속도는 더욱빨라질것이고, 하드웨어사양은 더욱높아질것이고, 시장이 열리는 국가는 더욱증가할것이다
3년내에 Gingerbread 비율은 사라질것이고 그자리를 Jelly Bean 이상이 차지할것이다.


<Mar. 5th 2013>

<June 3, 2013>


<August 1, 2012>




2013 년 6월 3일. ~ 2013 년 8월 1일.

단 두달 사이이 변화만 봐도, Jelly Bean 이하 버전의 점유율은 떨어지고 Jelly Bean 이상 버전의 점유율이 상승하고있다.

단 두달사이에 Jelly Bean 이상버전 점유율이 7.5% 상승했다.

1년 후가 되면, 시장의 대부분을 Jelly Bean 이상버전이 차지하고 있을것이라 예상할수 있다.


2013.3.5 에 Jelly Bean 이상 버전 점유율은 16.5%
2013.8.1 에 Jelly Bean 이상 버전 점유율은 40.5%

6개월만에 JellyBean 이상 점유율이 2배이상 증가했다. ( 245 % )

변화의 속도를 느껴볼 수 있다.





<중국 2013 1분기 판매량>
삼성전자                                               18.5% 1분기 판매량 1250
(중국현지제조사{화웨이, ZTE, 레노보쿨패드}  43.6% 1분기 판매량 2940
애플                                                      9.1% 1분기 판매량 610만대



<일본 스마트폰 점유율(2013년 6)>
소니       36% ( 엑스페리아Z, 엑스페리아A ) 4.1젤리빈, 5인치, 1920x1080
애플       25%
삼성전자 13%
샤프       7.9%

( 엑스페리아Z : (20134일본내 판매량 460만대 돌파. )











Eclipse hangs at the Android SDK Content Loader

eclipse -clean