posted by By훈트 2011.02.18 11:22

이번에는 Bitmap 데이터 형을 byte Array로 변환하거나 혹은 그 역으로 변환하는 예제를 다루어 보도록 하겠습니다.

해결책

ByteArrayOutputStream 인스턴스를 생성한 후, Bitmap의 compress 메서드를 통해 비트맵을 압축하여 stream에 담습니다.

BitmapFactory의 decodeByteArray 메서드를 통해 byte Array를 Bitmap으로 변환합니다.

토의

안드로이드의 Bitmap은 비트맵 데이터를 stream에 넣어주는 compress 메서드를 제공하고 있습니다.

  1. public byte[] bitmapToByteArray( Bitmap $bitmap ) {  
  2.         ByteArrayOutputStream stream = new ByteArrayOutputStream() ;  
  3.         $bitmap.compress( CompressFormat.JPEG, 100, stream) ;  
  4.         byte[] byteArray = stream.toByteArray() ;  
  5.         return byteArray ;  
  6.     }  

compress 인자 값에는 압축 옵션( JPEG, PNG ) 와 품질 설정 ( 0 - 100까지의 int형 ), 그리고 압축된 바이트배열을 담을 stream을 넘겨줍니다.

byteArray는 stream의 toByteArray() 메서드를 통해 반환받을 수 있습니다.

다음은 역으로, 바이트 배열로부터 비트맵을 생성하는 코드 입니다.

  1. public Bitmap byteArrayToBitmap( byte[] $byteArray ) {  
  2.     Bitmap bitmap = BitmapFactory.decodeByteArray( $byteArray, 0, $byteArray.length ) ;  
  3.     return bitmap ;  
  4. }  

바이트 배열로부터 비트맵 생성은 BitmapFactory의 decodeByteArray의 메서드를 통해 간단히 생성할 수 있습니다. decodeByteArray의 메서드 인자값으로 바이트 배열과 offset(배열의 시작점), length(decode할 바이트 배열의 길이)를 넘겨줍니다.

결과

관련예제

안드로이드 카메라 캡쳐해서 bitmap 얻어오기



[출처] 시스님의 블로그

신고
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by By훈트 2010.08.10 08:45

[View Attribute]


XML에서 각각의 뷰가 가지는 속성을 Attribute로 지정해할 수 있습니다. 모든 View가 공통적으로 가지고 있는 Attribute에 대해서 먼저 설명하도록 하겠습니다.




layout_width, layout_height 


뷰의 넓이와 높이를 지정합니다. 


값으로 fill_parent, wrap_content 혹은 절대적인 수치를 가질 수 있습니다. 

fill_parent는 컨테이너 즉 부모가 가지는 길이를 모두 채울때 사용하고, 

wrap_content는 해당 뷰가 그려질 수 있게 필요한 길이만 차지한다는 것을 나타냅니다. 


절대적인 값도 넣을 수 있는데 픽셀의 경우 "100px", "100dp", "100sp" 처럼 수치와 단위를 써서 지정해줍니다. 

사용할 수 있는 단위는 px, in, mm, pt, dp, sp등이 있는데 주로 dp, sp, px이 주로 쓰입니다. 

px는 픽셀을 나타냅니다.

dp는 Density-independent Pixel이라고 화면의 밀도의 변화에 독립적으로 1dp는 160dpi의 화면에서의 1px에 대응됩니다. 

sp는 Scale-independent Pixel 이라고 하여 사용자의 폰트 선호도에 따라 크기가 달라지며 주로 폰트 사이즈 설정에 사용됩니다.



background


 배경색 혹은 그림을 지정해줍니다.

색은 #RGB, #ARGB, #RRGGBB, #AARRGGBB 의 포맷으로 지정해 줄 수 있습니다. 

통일성을 위해 보통 #AARRGGBB 포맷을 사용합니다. 

제일 앞에 AA는 투명도를 의미하고 나머지 부분은 RGB값을 의미합니다. 

투명도인 AA는 00이 완전 투명, FF가 불투명이 됩니다. 

예를 들어 android:background="#FFFF0000"로 지정해주면 빨간색으로 배경을 칠하게 됩니다. 

배경그림을 지정해줄 수도 있는데 android:background="@drawable/background_image" 와 같은 형태로 사용가능합니다. 

배경 그림은 리소스에 들어있는 jpg, png등의 그림을 배경으로 지정할 때 사용합니다.


visibility 


뷰가 화면에 보이게 할지 안보이게 할지를 설정합니다. 

visible, invisible, gone의 값을 가질 수 있습니다. 


visible 화면에 보임, 

invisible 화면에 보이지 않으나 공간은 차지함, 

gone 화면에 보이지도 않고 공간도 차지 하지 않음

신고
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by By훈트 2010.08.04 11:58
main.xml-------------->
<com.drawbitmap.MyView // 이곳에 package 경로와 클래스명을 적는다.
android:id="@+id/myView"
android:layout_below="@id/top"
android:layout_above="@id/btn"
android:layout_width="fill_parent" 
android:layout_height="wrap_content"
/>

MyView.java------------>
// 사용하려는 목적에 따라 기타 함수는 다르겠지만 아래의 것들은 꼭 있어야 한다.
// 없으면 xml에서 속성들이 적용되지 않아서 컴파일은 되어도 실행이 안된다.
public class MyView extends View {
public MyView(Context context) {
super(context);
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by By훈트 2010.08.02 12:13

이번에 정리해 볼 이슈는 안드로이드 개발에 반드시 사용하게 되는 에뮬레이터의 관한 이슈이다.
에뮬레이터가 특별한 이슈가 될 것은 없지만 Network programming 을 할 때는 이슈가 발생한다.
특히, 안드로이드 애플리케이션이 서버로 동작할 때는 더욱더 그러하다.

들어가기에 앞서, 에뮬레이터를 클라이언트로 이용해서 사용하는 경우에는 별다른 이슈가 없다고 하였는데 이미 에뮬레이터에는 브라우저도 있고, WebView 클래스를 이용한 Webkit controller도 띄우는 예제가 있다. 다만, 외부로 접속하고자 할 경우(즉, 인터넷을 사용하는 경우에는) user-permission 셋팅을 해 주어야 하는 것을 잊지 말자.

AndroidManifest.xml 파일의 가장 상위 엘리먼트인 <manifes> 바로 다음 자식 엘리먼트로 다음을 넣어주면 된다.

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

이 부분에 대한 간략한 설명은 이전 포스트에도 살펴볼 수 있다.

http://www.wiseant.net/blog/7 : android.webkit.WebView 를 이용한 데모

자! 그러면 여기서 살펴보고자 하는 것은 안드로이드 애플리케이션을 SocketServer를 이용한 서버로 띄웠을 때의 이슈이다.

그렇다면, 이에 해당하는 부분을 안드로이드 문서에서는 어떻게 정의해 두었을까? 다음의 링크를 통해서 확인할 수 있다.

# emulator reference

# emulator reference networking

일종의 제약 사항이라고 할 수 있는데 에뮬레이터의 네트워크 아키텍쳐를 virtual router/firewall 을 사용하여 내부적으로 에뮬레이터내에 IP를 할당하고 있는 것을 볼 수 있다.
이렇게되어 있다보니 로컬 시스템의 IP를 사용할 것으로 생각하면 오산인 것이다. 일단은 위의 문서를 토대로 대략적인 것을 살펴볼 수 있고, Network redirerction이란 것도 볼 수 있다.

안드로이드 에뮬레이터에서 Network redirection은 에뮬레이터가 가지는 VLAN과 로컬 시스템의 포트를 연결(파이프로 연결한다고 생각하면 된다)해 주는 개념이다.
즉, 로컬 시스템의 포트로 들어오는 패킷을 에뮬레이터의 포트로 넘겨주는 식이다(Forward 개념과 비슷하다).

좀 복잡한 듯 하니 그냥 간단한 테스트 소스와 설정하는 방법을 통해서 알아보자.
먼저, 안드로이드 애플리케이션에 올라가는 간단한 서버 소켓을 여는 프로그램을 만들어보자. 참고로 안드로이드 전체 소스는 생략한다. 많은 안드로이드 기초 강좌 등에서 찾아볼 수 있다.

    private String host = "localhost";
    private String port = 8002;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);

        status = (TextView)findViewById(R.id.status);
        status.setText("do something");

        Button btnRunServer = (Button)findViewById(R.id.runserver);
        btnRunServer.setOnClickListener(new Button.OnClickListener() {
         public void onClick(View v) {
          // run server
          try {
           ServerSocket serverSocket = new ServerSocket(port);
           
           status.setText(status.getText() + " waiting");
           Log.d("Green", "Waiting...");
           
           Socket player1 = serverSocket.accept();

           status.setText(status.getText() + " Connected");
           Log.d("Green", "Connected");

           player1.close();
          }
          catch (Exception ex) {
           status.setText(status.getText() + ex.getMessage());
          }
         }
        });

        Button btnConnect = (Button)findViewById(R.id.connect);
        btnConnect.setOnClickListener(new Button.OnClickListener() {
         public void onClick(View v) {
          // connect to server
          try {
           Socket socket = new Socket(host, port);

           DataInputStream fromServer = new DataInputStream(socket.getInputStream());
           DataOutputStream toServer = new DataOutputStream(socket.getOutputStream());

           status.setText("connected");
           Log.d("Green", "Connected...");
           
           toServer.writeInt(1337);
          }
          catch (Exception ex) {
           status.setText(ex.getMessage());
          }
         }
        });
    }

위의 소스에서는 ServerSocket을 열어놓고(Listening), accept 시에 Connected 메시만을 뿌려주는 간단한 서버용 애플리케이션이다.
connect 버튼을 클릭 시에는 지정된 host로 접속해 보는 소스이다.

안드로이드 에뮬레이터에서 접속 문제를 다루고 있음으로 여기선 ServerSocket 등에 대해서는 자세하게 다루지 않는다.

일단 위의 소스를 기반으로 하여 안드로이드를 구동해 보자.

일단 위와 같이 애플리케이션이 구동되면 첫 번째 버튼을 클릭해서 ServerSocket을 띄워준다. 이제 안드로이드 서버 애플리케이션과 연동할 간단한 클라이언트 소스를 살펴보자.

/**
 * 
 */
package com.mediachorus.test.android.network;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;

/**
 * @author Sang-Hyup Lee
 * @version 1.0
 *
 */
public class ClientTest {

 /**
  * @param args
  */
 public static void main(String[] args) {
  String host = "localhost";
  int port = 8002;
  // TODO Auto-generated method stub
  try {
   Socket socket = new Socket(host, port);

   DataInputStream fromServer = new DataInputStream(socket.getInputStream());
   DataOutputStream toServer = new DataOutputStream(socket.getOutputStream());

   System.out.println("IP:" + socket.getInetAddress().getHostAddress()
       + ", port:" + socket.getPort());
   System.out.println("Connected...");
      
   toServer.writeInt(1337);
   // toServer.write("quit".getBytes());
   toServer.flush();
   
   System.out.println("Done...");
  }
  catch (Exception ex) {
   System.err.println(ex.getMessage());
  }
 }
}

클라이언트 소스 역시 설명할 것도 별로 없다. 자바 네트워크 프로그램으로 서버에 접속해서 패킷을 보내어 본다. 로그를 통해서 접속이 되었는지 확인만 해 보는 것이다.

클라이언트 소스를 실행해 보자. 다음과 같은 Exception을 발생시킨다.

Connection refused: connect

커넥션이 이루어지지 않았다는 말인데, 우리의 의도는 안드로이드 애플리케이션 TCP 서버 소켓에 접속하는 것이다. 동일한 PC 에서 이루어지는데 localhost 라고 하면 되는 줄 알았는데 아니다.

여기서 위의 구글 문서 링크에서 나온 것처럼 Network redirection이 필요하다.
다음과 같이 command 상에서 telnet 접속부터 시작해서 실행해보자. 참고로 에뮬레이터는 5554 포트를 기본으로 할당하여 telnet으로 접속이 가능하다.

telnet localhost 5554
redir add tcp:8002:8002 

사용자 삽입 이미지

위와 같이 로컬 시스템이 8002 포트를 사용하지 않으면 OK 메시지로 응답한다. 참고로 redir 사용법을 보려면 "redir help"라고 입력하면 된다.
위의 명령어 뜻은 다음과 같다.

TCP 형태로 redirection을 하는데, 로컬 시스템의 8002 포트를 VLAN(에뮬레이터에 올라간 안드로이드 애플리케이션) 8002 포트로 연결(redirection) 해 준다.

add <protocol>:<host-port>:<guest-port>

그렇다면 redirection을 해지하는 방법은 add를 del로 바꾸어주면 된다. 다음과 같은 형태이다.

redir del tcp:8002


del 옵션을 사용시에는 system host port만 입력해 주면 된다.

자, 이 상태에서(redirection을 걸어둔 상태에서) 클라이언트 프로그램을 실행해 보자. Connected 메시지를 볼 수 있을 것이다.

이렇게해서 기본적인 Network redirection을 해결할 수 있는데, 클라이언트 소스 코드를 '127.0.0.1'로 host 값을 바뀌어서 해 보자.
(결론은? 잘 된다. 어쩌면 당연한 것을?^^)

하지만, 로컬 시스템이 가지고 있는 IP를 host 값으로 수정하고 실행해 보자. 다시금 "Connection refused: connect" 에러가 발생한다.
그렇다면, 안드로이드 애플리케이션이 실행하고 있는 시스템이 아닌 다른 시스템에서의 접속은? 당연히 안 된다.

문제는 여기에 또 있는 것이다. Server/Client 프로그램은 당연히 서로 다른 시스템의 연결을 지양하고 있는 것인데 이런 문제가 발생한다.
이는 안드로이드 에뮬레이터가 동작시에 localhost에 해당하는 127.0.0.1을 개발 머신의 loopback interface로 alias를 해주기 때문이다.
결국은 로컬 시스템의 IP를 할당하여 수행하지 못한다는 것이다.

이를 해결하기 위해서 다음의 링크를 통해서 stcppipe.exe를 실행해 주어야 한다. 링크에는 sudppipe.exe도 포함되어 있다. 소스와 함께.

Simple UDP proxy/pipe 0.3a  : http://aluigi.org/mytoolz/sudppipe.zip
Simple TCP proxy/pipe 0.4.4a : http://aluigi.org/mytoolz/stcppipe.zip

사용법은 다음과 같다.

stcppipe.exe -b <local IP> <remote hosts> <local port> <remote port>
remote hosts : 127.0.0.1
remote port : emulator 의 host port

이를 응용해서 실행해 보면 다음과 같이 입력할 수 있다.

stcppipe -b 192.168.0.86 l27.0.0.1 8002 8002

이렇게 하고 다시금 로컬에서든 다른 시스템에서든지 Client 프로그램을 실행해보자.
stcppipe 프로그램을 통해서 IN/OUT 되는 포트도 확인해 볼 수 있다. UDP도 마찬가지이다. 각자 테스트해 보는 것도 좋을 거 같다.


이렇게해서 안드로이드 에뮬레이터의 Network redirection 이슈를 마친다. 끝으로 이 문제는 혼자서 고민하고 해결한 것이 아니라 kandroid.org 의 운영자이신 들풀님의 큰 도움이 있었다. 이에 감사의 뜻을 전하며 해당 부분을 Q&A를 통해서 해결하였는데, 링크를 걸어둔다.


# 처음 Emulator IP 관련된 질문후, redir (option)에 대해서 알게된 링크

# 로컬 시스템 내에서의 접속이 아닌 원격 시스템에서의 접속 처리를 해결하게 된 링크

두 번째 링크에도 포함된 링크인데 구글 그룹스에서도 똑같은 고민을 했었고 동일하게 해결한 것을 찾을 수 있다.



다시금 함께 고민해 주신 들풀님에게 감사의 뜻을 전한다.


[마치며]
지금까지의 Network redirection을 통해서 다양한 것을 개발해 보았다. 하지만 실제 개발에서 사용하는 것이 TCP, UDP를 함께 사용하면서 까다로운 네트워크 프로그램을 처리하는 것이었다. 특이한 점은 윈도우에서는 정상적으로 처리되지 않을 때가 많았다.
그래서 Ubuntu 에서 실행해 보니 접속에 대한 문제는 거의 발생하지 않았다. 이러한 원인에 대한 분석은 현재로서는 어려울 것 같아서 다루지 않겠다.
그냥 경험담이라고 생각해 주면 좋겠다.

모두들... 더 좋은 정보나 자료가 있으면 공유해 주세요~^^
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by By훈트 2010.08.02 10:37
안드로이드에서 HTTP를 통한 데이타를 가져오는 방식은,
URL클래스 또는 HttpClient를 사용하는 방법이 있다.

1. URL 클래스 사용

 GET 방식으로 간편히 사용할수 있지만, POST방식은 파라미터를 전달하는 방식이 다르므로
이 대로는 파라미터를 전달할수 없다.

2. HTTPClient 사용
잘못된 예1

HttpPost에 URL과 전달할 파라미터들을 헤더에 추가하여 결과를 얻는다.
HttPost 에 정보 담기
-> HttpClient에서 요청을 실행 HttpResponse로 결과 리턴
-> HttpResponse의 getEntity로 inputstream을 얻어서 결과 얻기

결과를 얻어왔지만,
ㄱ. 파라미터가 제대로 넘어가지 않는 문제와
ㄴ. 한글을 인코딩에서 문제 발생

잘못된 예2

HttpParams 를 사용하여 파라미터를 전달하려함 (후에 안것이지만 HttpParams는 이런 용도가 아니라고 함)

그래서 사용한 방법은
NameValuePair 목록을 가지는 List를 활용하는 방법로 파라미터명 - 값을 List<NameValuePair>로 모아
HttpPost요청에 setEntity(new UrlEncodedFormEntity()) 한다.

결과를 얻어왔지만,
ㄱ. 파라미터가 제대로 넘어가지 않는 문제와
ㄴ. 한글을 인코딩에서 문제 발생

3. 성공한 예

HttpURLConnection을 사용.
PrintWriter를 통해 데이타를 보내고, HttpURLConnection을 통해 InputStream을 얻어 결과를 만든다. -> 파라미터 전송 성공

한글문제는 보내거나 받을때, 모두 최초의 스트림을 만들때 인코딩 문자열을 넘길수 있는 생성자를 통해 한글 인코딩을 전달하여 생성하니 한글도 정상적으로 동작.
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by By훈트 2010.07.29 21:26

이미지에 관련된 전반적인 사항이니 참고하세요.

 

1. 기본적으로 resource에 저장되어 있는 이미지의 경우 Drawable이라는 오브젝트를 구해와서 화면에 그릴 수가 있습니다.

 

Drawable drawable = getResources().getDrawable(id);

drawable.setBounds(0,0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());  // drawable을 어느 영역에 그릴 것인가?

 

onDraw(canvas canvas) {

           drawable.draw(canvas);

}

 

setBounds에 설정한 값에 따라서 자동으로 이미지가 scaling이 됩니다.

 

원본 이미지 사이즈가 100*50인데 bounds를  (0,0, 200, 100)이라고 설정하면 가로 세로가 2배로 확대되어서 그려지겠죠.

 

2. 임의의 bitmap을 생성하고 bitmap에 원하는 내용그리기

 

다음과 같이 임의의 bitmap을 생성합니다.

Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);

 

Config.ARGB_8888말고 Config.RGB_565 있고 몇가지 있습니다.

 

원하는 걸로 생성하면 되는데 ARGB8888 생성할 경우 투명값을 지정할 수가 있는 반면 RGB_565 생성하시면 불투명한 이미지만 가능합니다.

 

이렇게 만들어진 bitmap에 직접 그림을 그리거나 다른 이미지를 그릴려고 하면 아래와 같이 새로운 canvas를 만들어야 합니다.

 

Canvas canvas = new Canvas();

canvas.setBitmap(bitmap);

 

그러면 향후에 canvas에 그리는 모든 작업은 bitmap에 반영이 됩니다.

 

3. Bitmap Drawable간의 변환

 

안드로이드에서는 bitmap을 직접 다루기보단 대부분 Drawable이라는 wrapping된 형태로 이미지를 처리하기 때문에

 

Bitmap의 경우 종종 Drawable로 변환해야 하는 경우가 있습니다.

 

이를 위해서 BitmapDrawable이라는 클래스가 존재하고 아래와 같은 식으로 사용이 가능합니다.

 

Drawable drawable = (Drawable)(new BitmapDrawable(bitmap));

 

BitmapDrawable은 Drawable로 캐스팅이 가능하죠.

 

4. canvas 처리

 

w*h크기의 drawable 오브젝트가 있을 때 setBounds를 이용하여 임의의 좌표(x,y)에 원형크기대로 출력할려면 아래와 같습니다.

 

obj.setBounds(x,y,x+w,y+h);

obj.draw(canvas);

 

이 방식의 귀찮은 점은 항상 w,h를 지정을 해줘야 하기 때문에 코드도 상당히 길어지고 지저분해보이는 경우가 많습니다.

(getIntrinsicWidth()/Height()로 항상 구하던지 별도의 변수에 값을 유지해야하죠)

 

그래서 위와 같은 방법보다는 아래와 같이 canvas의 좌표이동 변환식을 이용하는게 깔끔합니다.

 

obj.setBounds(0,0,w,h); // 얘는 drawable을 최초로 생성했을 때 한번만 지정하면 됨

 

canvas.save(); // 현재 변환식을 저장

canvas.translate(x,y) // 좌표이동과 관련된 변환식 적용

obj.draw(canvas); // drawable을 그린다.

canvas.restore(); // 원래 변환식으로 복구

 

canvas.translate(x,y) 를 지정할 경우 출력할 이미지를 (x,y)만큼 이동시켜서 그려줍니다. (좌표이동 행렬식이라고 생각하면 됨)

 

신고
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by By훈트 2010.07.28 16:57

xml코드가 아닌 java 코드단에서 xml의 EditText의 속성중 layout_widthlayout_height값을 변경해보자.




<layout xml 코드>
EditText의 android:layout_width android:layout_height 를 주목하자.
각각의 속성 값을 wrap_content 로 하였기 때문에 EditText의 기본 height 값과 android:text 의 값의 길이만큼의 크기로
실행 화면에 나와야 한다.

<Java Souce 코드>
소스코드에서 setLayoutParams() 메서드를 이용하여 EditText layout_width layout_height 값을 변경해 보자.


<실행 화면>
실행 화면을 보게되면 EditText의 가로 세로 길이가 300,300 으로 설정된 것을 확인할 수 있다.
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by By훈트 2010.07.28 10:39

상용
aiCharts
http://www.artfulbits.com/Android/aiCharts.aspx
상용 차트입니다.
갤러리 - http://www.artfulbits.com/Android/gallery/galleryCharts.aspx
우크라이나 회사 같습니다. 미국에서도 영업합니다.
온라인 결재 299달러 시작

오픈소스
achartengine
http://code.google.com/p/achartengine/
현재도 계속 개발중입니다.
종류
line chart
area chart
scatter chart
time chart
bar chart
pie chart
bubble chart
doughnut chart

chartdroid
http://code.google.com/p/chartdroid/
현재도 계속 개발중입니다.

androidchart
http://code.google.com/p/androidchart/
주식형 차트인데 2008년 이후로 업데이트 되지 않습니다.

http://shaffah.com/droid-analytic-google-analytics-for-android
이런 비슷한 오픈 소스 프로그램이 있나 해서 찾다가 본건데
개발자가 아니어서 사용성까지는 잘 모르겠습니다.


신고
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by By훈트 2010.07.28 01:50

루팅시 발생할 수 있는 제(벽돌... A/S불가)에 대해서는 글쓴이는 책임지지 않습니다!!!

누구든 얘기하지만 자기가 책임질수 있으면 하는겁니다. 저한테 뭐라 탓하지 마세요.

 

이 글 설명에 앞서 출처는 http://www.androidpub.com/phone_sirius/578769 GOTOFBI님 게시글입니다. 제가 알아낸것 아닙니다.

또한 카페의 M16요원님께서도 많은 정보 주셨습니다. 감사합니다.

 

 

 

가장 기초!!! 컴퓨터에 Usb 드라이버는 깔려있어야 하고, 연결 해 놓으시는것 아시죠?

 

두번째!! 핸드폰의 설정 - 응용프로그램 - 개발 에서 USB 디버깅에 체크해주시고

 

세번째!! 핸드폰의 화면 조명 설정을 30분으로 해주세요!!!(제 기분상 이렇게 하는게 편하겟더라구요 막 뜨는거 없나 살펴볼라고)

 

여기까지 준비가 되셨으면 먼저 제가 첨부한 압축파일을 다운받아 c:드라이브에 저장합니다.

(C드라이브에 들어가면 adb폴더가 있어야 합니다. 물론 다른곳도 괜찮지만 편의를 위해 저는 이곳을 정하겠습니다.)

 

그리고 실행 - cmd를 치시고 C드라이브 adb 폴더안에 들어갑니다.

 

이때, 하위 폴더로 가고자 할때는 cd.. 이 명령어를 치고 엔터를 치다보면

 

C드라이브로 가게됩니다.

 

이때 cd adb 이 명령어를 치시면 adb폴더로 들어가게되는데, 여기서부터 아래 명령어를 차례대로 써주시면 됩니다.

 

한줄씩 작성하시고, 반응이 없을때 써주세요. 그냥 주구장창 타자치기도 힘들지만 그렇게 하면 안됩니다.

 

 

 

adb push Superuser.apk /sdcard/Superuser.apk


adb push su /sdcard/su


adb push busybox /sdcard/busybox


adb push exploid /sqlite_stmt_journals/exploid

 

adb push busybox /sqlite_stmt_journals/busybox

 

adb shell

 

(여기서부터 $가 나옵니다.)


cd sqlite_stmt_journals


chmod 755 exploid


chmod 755 busybox

 

다음단계를 하기전에 설정에서 wifi를 바로 켜고/끌 수 있는상태로 핸드폰을 세팅해놓음

 

./exploid

 

위 단계를 실행 하자마자 wifi를 켜기/끄기 실행(켜진걸 꺼따가 다시 켜시거나, 꺼진걸 켰다가 다시 끄시면 됩니다.

 

rootshell

 

secretlol

 

(여기서부터 #이 나옵니다)

 

./busybox cp /sdcard/Superuser.apk /system/app/Superuser.apk


./busybox cp /sdcard/su /system/bin/su


./busybox cp /sdcard/busybox /system/bin/busybox


chmod 4755 /system/bin/su


chmod 4755 /system/bin/busybox


rm /system/bin/rootshell

 

(다음 중요합니다)

 

su

 

이렇게 쳤을때 #이 나오면 루팅 성공입니다.

 

 

제가 캡쳐한 그림을 보시고 고대로 따라하셔도 됩니다. 여기서 exit명령은 나가겠다는 뜻입니다.

 

그리고 마지막에보시면 adb shell 명령을 다시 주었는데 이는 제대로 되었는지 확인해 보려고 한 겁니다.

 

마찬가지고 su명령을 내리니 #이 뜨게됩니다. 성공이지요.

 

근데 인터넷 검색해보니깐 안되는 사람들도 있는것 같습니다. 그부분에대해서는 잘 모르겠습니다.

 

이 방법만 잘 따라온다면 별 문제 없을거라 예측됩니다.

 

루팅이 되었는지 확방법은 많습니다. 어플 목록이 있는곳에 Superuser Permissions라는 어플이 깔려있을 것이고

 

제가 확인한 방법으로는 Root Explorer 설치,

 

Quick App Clean Cache에서 Clear all caches 버튼이 있는데 이 버튼이 root권한이 없으면 실행이 안됬었는데 실행되는군요.

 

하는 중간에 핸드폰에 llow 무슨 창이 뜰수잇는데 그때 allow버튼을 눌러주셔야 합니다.

 

여기까지가 루트권한을 얻는 방법이고 뭐 이후에 오버클럭이나 skaf삭제는 취향것 하시면 될것 같습니다.

 

인터넷 검색이 짱입니다요. 많이 있으니까 찾아보시길 바랍니다.

 

아마 많은 분들께서 하신다면 그에 따른 유용한 방법들이 나오겠지요!!

 

이상입니다. 수고하셨습니다.

 

 

 

 

아,,, 그리고 루팅 후 펌업하면 복구됩니다. 확인했습니다.(장담은 아닙니다)

신고
크리에이티브 커먼즈 라이선스
Creative Commons License
posted by By훈트 2010.07.27 22:09
일반적으로 어플리케이션에서 자료를 저장할 때 데이터베이스를 주로 사용합니다. 그런데, 한 어플리케이션 내에 저장되어 있는 데이터베이스에는 해당 어플리케이션 외에 다른 어플리케이션이 접근하는 것이 불가능합니다. 그렇다면, 다른 어플리케이션의 데이터에 접근할 수 있는 방법은 아예 없는 것일까요? 그렇지 않습니다. 만약 이렇게 데이터베이스 공유가 "완전히" 불가능할 경우 엄청난 재앙(?)이 발생합니다.

다른 어플리케이션에서 특정 어플리케이션의 데이터베이스에 직접 접근하는 것은 불가능합니다.


주소록 어플리케이션은 주소록 데이터를 데이터베이스에 저장하게 되는데, 이 주소록 데이터베이스에 주소록 어플리케이션만 접근 가능하고 다른 어플리케이션에서는 접근이 불가능하다면 주소록 정보를 이용하여 다른 서비스를 연동하는 것은 불가능하겠지요? 자칭 "경계가 없는 어플리케이션"을 추구하고 있는 안드로이드에서 기본적인 데이터 공유도 되지 않는다면 그건 말도 안되는 일이겠지요..

이 문제를 종합해보자면, 외부 어플리케이션이 마음대로 내 데이터베이스에 접근하지는 못하게 함과 동시에 내가 가진 데이터베이스 중 원하는 것들만 공유할 수 있도록 해주는 수단이 필요합니다. 안드로이드에서는 이런 역할을 컨텐트 프로바이더(Content Provider)라는 녀석이 해주게 됩니다.

컨텐트 프로바이더는 어플리케이션 내의 데이터베이스를 다른 어플리케이션이 사용할 수 있는 "통로"를 제공해줍니다. 이 과정에서 컨텐트 프로바이더를 통해 외부 어플리케이션이 접근할 수 있는 범위를 정해줄 수 있어, "공유할 것만 공유하는" 것이 가능합니다.

컨텐트 프로바이더와 컨텐트 리졸버

컨텐트 프로바이더를 사용하여 안드로이드 시스템의 각종 설정값이나 SD카드 내의 미디어 등에 접근하는 것이 가능합니다. 컨텐트 프로바이더에 접근하기 위해서는 해당 컨텐트 프로바이더의 주소가 필요합니다. 

컨텐트 프로바이더에 접근할 때는 컨텐트 프로바이더의 주소와 컨텐트 리졸버(Content Resolver)가 필요합니다. 컨텐트 리졸버는 컨텐트 프로바이더의 주소를 통해 해당 컨텐트 프로바이더에 접근하여 컨텐트 프로바이더의 데이터에 접근할 수 있도록 해주는 역할을 합니다.

컨텐트 리졸버는 액티비티 클래스 내의 getContentResolver()메소드를 통해 인스턴스를 받아올 수 있습니다. 일단 컨텐트 리졸버의 인스턴스를 받아온 후에는 query, insert 등의 메소드을 통해 데이터를 받거나 입력, 수정하고 싶은 컨텐트 프로바이더의 URI(Uniform Resource Identifier)를 넘겨주면 해당 컨텐트 프로바이더에 접근하여 요청한 작업을 수행할 수 있습니다. 

컨텐트 리졸버 및 컨텐트 프로바이더를 통한 데이터베이스 접근



컨텐트 프로바이더의 주소 구성

컨텐트 프로바이더의 주소는 컨텐트 프로바이더를 생성할 때 지정하며, URI(Uniform Resource Identifier) 형식으로 구성되어 있습니다. URI라는 단어 자체가 좀 생소할지도 모르겠습니다. 하지만 어렵게 생각할 것은 없습니다. URI는 우리가 인터넷 상의 자원의 주소를 표시할 때 쓰는 URL(Uniform Resource Identifier)의 상위 개념으로, 어떠한 자원의 위치를 표기하기 위한 형식입니다.

컨텐트 프로바이더의 주소(URI)는 일반적으로 아래와 같은 모습을 하고 있습니다.

content://AUTHORITY/PATH

인터넷 주소가 http:// 로 시작하는 것처럼, 컨텐트 프로바이더는 content://로 시작하는 주소를 가지고 있습니다. URI에서 http, content 등을 스키마(Scheme)라 합니다.

다음으로, AUTHORITY 부분입니다. AUTHORITY는 컨텐트 프로바이더의 고유 주소로, 뒤에 붙에 될 PATH와 함께 다른 어플리케이션에서 해당 컨텐트 프로바이더에 접근하기 위한 주소를 구성합니다. AUTHORITY는 다른 어플리케이션과 중복되면 안되므로, 일반적으로 자바 패키지 이름을  짓는 방식을 따라 이름을 지어줍니다. (예 : com.androidhuman.example) 인터넷 주소(URL)으로 치자면 사이트의 주소 (예:www.google.com) 부분이라 보시면 됩니다.

마지막으로 PATH(경로)는 즉 해당 프로바이더에서 제공하는 구체적인 데이터의 위치를 나타냅니다. 인터넷 주소로 치자면 세부 주소 (예: www.google.com/phone에서 phone 부분)라 할 수 있습니다.


컨텐트 프로바이더에서 제공하는 자료의 유형 구분

컨텐트 리졸버와 컨텐트 프로바이더의 주소를 통해 컨텐트 프로바이더에서 제공받는 데이터는 하나의 데이터일 수도 있고, 어떤 유형의 데이터 목록일 수도 있습니다. 이는 일반적으로 컨텐트 프로바이더의 주소를 통해 구분할 수 있지만, 좀 더 명확하게 해주기 위해 타입(MIME Type)을 지정해줍니다.

만약, 아래와 같은 컨텐트 프로바이더의 주소가 있다고 가정해봅시다.

contents://com.androidhuman.phoneprovider/phones

위의 컨텐트 프로바이더는 휴대폰 정보를 제공하는 컨텐트 프로바이더라 가정해보겠습니다. 위의 컨텐트 프로바이더의 AUTHORITY는 com.androidhuman.provider이고, Path는 phones 임을 알 수 있습니다. 위와 같은 형태의 주소는 일반적으로 어떤 항목에 해당하는 모든 데이터를 반환합니다. 위와 같은 경우는 모든 휴대폰 번호를 반환할 것이라 예측할 수 있죠.

Path는 컨텐트 프로바이더에 따라 여러 구조를 가질 수 있습니다. 아래와 같이 제조사별 휴대폰 목록을 제공하는 컨텐트 프로바이더가 있을 수도 있지요.

contents://com.androidhuman.phoneprovider/phones/lg
contents://com.androidhuman.phoneprovider/phones/samsung
contents://com.androidhuman.phoneprovider/phones/htc
contents://com.androidhuman.phoneprovider/phones/motorola

이런 식으로 "여러 개의 데이터"를 반환하는 컨텐트 프로바이더 주소(URI)는 타입으로 아래와 같은 형식을 갖습니다.

vnd.android.cursor.dir/vnd._CUSTOM_NAME_

위의 휴대폰 정보를 제공하는 컨텐트 프로바이더에서 휴대폰 목록을 제공하는 URI의 타임은 아래와 같이 지정할 수 있겠죠.

vnd.android.cursor.dir/vnd.androidhuman.phone

위와 같이 여러 개의 자료가 아닌, 딱 하나의 자료를 가리키는 컨텐트 프로바이더의 주소도 있습니다. 일반적으로 아래와 같은 형태를 하고 있지요.

contents://com.androidhuman.phoneprovider/phones/lg/1
contents://com.androidhuman.phoneprovider/phones/samsung/3

하나의 데이터를 가리키는 컨텐트 프로바이더의 URI는 위와 같이 뒤에 해당 데이터의 ID를 붙인 형태를 띕니다. 이러한 컨텐트 프로바이더 URI는 타입으로 아래와 같은 형태를 갖습니다.

vnd.android.cursor.item/vnd._CUSTOM_NAME

위의 컨텐트 프로바이더에서 휴대폰 하나를 가리키는 URI의 타입은 아래와 같이 표현할 수 있겠죠.

vnd.android.cursor.item/vnd.androidhuman.phone


컨텐트 프로바이더 URI 정리

컨텐트 프로바이더 URI에 대해 다시 한번 정리해보도록 합시다.



1. 컨텐트 프로바이더에 의해 제공되는 데이터임을 알립니다. 이 부분은 변하지 않습니다.
2. 컨텐트 프로바이더의 authority부분입니다. 각 컨텐트 프로바이더의 고유 이름입니다.
3. 컨텐트 프로바이더의 Path 부분이며, 어떤 데이터를 반환할지를 이 부분을 통해 지정합니다. 
4. 3번 부분의 Path 하위의 데이터 중 하나를 가리키는 것으로, 해당 데이터의 ID를 나타냅니다.


컨텐트 프로바이더는 일반적으로 아래와 같은 구조를 가집니다.

  • 어플리케이션의 컨텐트 프로바이더의 고유 주소 (AUTHORITY)
  • URI 필터링을 위한 UriMatcher객체 및 컨텐트 프로바이더가 처리할 수 있는 URI들
  • URI에 따른 Type을 반환하는 메소드
  • insert, update, delete, query 메소드
  • 어플리케이션 데이터베이스 정의부

[출처] http://androidhuman.tistory.com/279

신고
크리에이티브 커먼즈 라이선스
Creative Commons License

티스토리 툴바