Android/센서 | Posted by 덩치 2013. 11. 28. 16:33

TYPE_MAGNETIC_FIELD 센서로 방위각 구하기

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

가장 기본적이면서 중요한 메커니즘은 SensorEventListener 참조, onResume에서 딜레이 설정이다.


//먼저 액티비티에 SensorEventListener을 implements 해 준다.

public class MainActivity extends Activity implements SensorEventListener{

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);


float[] rotation = new float[9];  

float[] result_data = new float[3];

float[] mag_data = new float[3]; //센서데이터를 저장할 배열 생성 

float[] acc_data new float[3]; //가속도데이터값이 들어갈 배열. 각도를 뽑으려면 가속도와 지자계의 값이 있어야함.

크기가 3인 이유는 센서값 values의 index가 3이기때문(x.y.z)


SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE); //센서매니저 생성

mag_sensor = sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); //마그네틱 필드 센서 생성

}

//센서 읽어들이는 간격 설정(NORMAL < UI < GAME 순 속도)

protected void onResume(){

super.onResume();

sm.registerListener(this, mag_sensor, SensorManager.SENSOR_DELAY_UI);

}



@Override

public void onSensorChanged(SensorEvent event) {  //센서값 변경을 읽는 리스너

if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)   //센서가 읽어들인 값이 마그네틱필드일때

mag_data = event.values.clone();    //데이터를 모두 mag_data 배열에 저장

if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) // 가속도센서값일때

acc_data = event.values.clone();  //마찬가지

if (mag_data != null && acc_data != null) { //널체크    

       SensorManager.getRotationMatrix(rotation, null, acc_data, mag_data); //회전메트릭스 연산

             SensorManager.getOrientation(rotation, result_data); //연산값으로 방향값 산출

result_data[0] = (float)Math.toDegrees(result_data[0]); // 방향값을 각도로 변환

if(result_data[0] < 0) m_result_data[0] += 360; //0보다 작을경우 360을더해줌

}

}



//종료시에는 반드시 센서의 리스너를 해제해줘야함

public void onDestroy(){

super.onDestroy();

sm.unregisterListener(this);

}


}


빠진부분이나 의문사항 댓글로 남겨주면 답변드립니다.


펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO






11월26일 코엑스 4층 컨퍼런스룸에서 열린 '스마트산업 통합의 키워드 HTML5 컨퍼런스에 다녀왔다.

삼성, SKT, Mozila, LG, KT, 안랩 등 굴지의 기업들이 참가하여 HTML5의 동향과

HTML5를 적용한 사업 방향을 설명하였다.


오전에는 삼성 이원석 수석의 '타이젠'에 대한 설명이 있었다.

타이젠에 대한 소개와 발전방향, 개발자가 나아갈 방향 등을 소개하였는데

솔직히 잘 모르겠다. 타이젠이 시장에서 먹어줄지, 그전에 타이젠이 완성도있게 출시 될지..

타이젠은 삼성 독자적으로 하는게 아니라 인텔, 오렌지 등을 비롯해 여러 기업들이 함께 개발하는 OS인데

컨퍼런스를 보면서도 삼성에서 타이젠을 확실히 밀고 있다는 인상은 받지 못했다.

인상깊었던 부분은 타이젠의 Cross - category Platform. 타이젠 모바일로 TV, camera, printer, pc, refrigerator, wearable등을 제어한다는 부분.

그리고 '파이어폭스 OS는 경쟁자가 아닌 동반자' 라고 말한 부분...

그리고 타이젠 App Challenge를 하는데 1등상금이 게임부문 $200,000 게임 외 부문 $120,000 등으로 어마어마하다

자세한 내용은 http://tizenappchallenge.com 에서 확인가능하다.



그 다음순서로 SKT의 이관재 ES랩장의 '코너스톤'에 대한 설명이 있었다.

이는 HTML5 웹앱 개발 툴로, 소규모개발사, 학생 개발자 등 인디웹앱 개발자들을 위한 툴이라고 소개했다.

HTML5를 배우기 위해서는 함께 배워야할것들이 너무많아 접근성이 떨어지는데

이런 소규모 개발자를 위한 툴을 이용한다면 편하게 개발 할 수 있을것 같다.

역시 SK가 돈이 많기는 많은가보다.



오후 세션1에서 인상깊었던 부분은

한국 Mozila커뮤니티의 윤석찬(직급을 잘 모르겠다)님의 Firefox OS의 현재와 미래 라는 타이틀로 말씀 하셨는데

브라질이나 다른 몇 국가에서는 인지도가 꽤 높은가보더라.

주로 Firefox에 대한 친밀도가 높은 시장에 Firefox OS시장이 구축 돼 있고, 그런 시장에서는 항상 점유율을

50% 이상 차지하고 있다고 한다.

허나 우리나라에서는 IE종속성때문에 당장 경쟁력을 갖기는 힘들것같다고 말했다.

나도 왠지 Firefox OS는 별로 신용이 안간다.  속도나 퍼포먼스측면에서 기존 안드로이드나 iOS에 비해

떨어질 수 밖에 없기때문인가?




오후 세션2에서는 먼저 김기영 안랩 실장의 HTML5 앱 보안기술 동향에 대해 말하였다.

HTML5는 HTML4에 비해 기능적인 측면이 많아졌기 때문에, HTML4에서도 많았던 취약점들이

더욱 많아질 수 밖에 없다고 말하며, HTML5 해킹의 예를 몇가지 보여주었다.

개인이나 영세기업이 보안에 비중을 두기에는 비용이나 기술적인 문제가 따르겠지만, 

개발시 적용할 수 있는 SQL 인젝션 체크나 다른 잘 알려진 보안 이슈에 대한 처리만 하여도 

꽤 안전한 앱을 만들 수 있을것이라고 하였다.



그리고 마지막 가장 기다리던


경품추천. 상품은 넥서스7 2대와 아이패드 미니 1대. 상품이 좀 빈약한것같았다.


나는 1705번이었는데 아이패드 미니는 1713? 분이 가져가셨다.



내가 언급한 주제 외에도 IPTV나 스마트TV, 전자책, WebKit과 Blink, 브라우저 엔진 등에 대한 설명도 많았지만

위에 언급한 내용들이 나에겐 크게 와닿은것 같다.


빨리 HTML5가 표준이 되고 개인 개발자들을 위한 공통 프레임워크가 많이 나왔으면 좋겠다.

Android/History | Posted by 덩치 2013. 10. 28. 13:25

안드로이드는 ?

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

안드로이드(Android)는휴대 전화를 비롯한 휴대용 장치를 위한 운영 체제와 미들웨어, 사용자 인터페이스 그리고 표준 응용 프로그램(웹 브라우저, 이메일 클라이언트, 단문 메시지 서비스(SMS), 멀티미디어 메시지 서비스(MMS)등)을 포함하고 있는 소프트웨어 스택이자 모바일 운영 체제이다. 안드로이드는 개발자들이 자바 언어로 응용 프로그램을 작성할 수 있게 하였으며, 컴파일된 바이트코드를 구동할 수 있는 런타임 라이브러리를 제공한다. 또한 안드로이드 소프트웨어 개발 키트(SDK)를 통해 응용 프로그램을 개발하기 위해 필요한 각종 도구들과 API를 제공한다.


안드로이드는 리눅스 커널 위에서 동작하며, 다양한 안드로이드 시스템 구성 요소에서 사용되는 C/C++ 라이브러리들을 포함하고 있다. 안드로이드는 기존의 자바 가상 머신과는 다른 가상 머신인 달빅 가상 머신을 통해 자바로 작성된 응용 프로그램을 별도의 프로세스에서 실행하는 구조로 되어 있다.


2005년에 안드로이드 사를 구글에서 인수한 후 2007년 11월에 안드로이드 플랫폼을 휴대용 장치 운영 체제로서 무료 공개한다고 발표한 후 48개의 하드웨어, 소프트웨어, 통신 회사가 모여 만든 오픈 핸드셋 얼라이언스(Open Handset Aliance, OHA)에서 공개 표준을 위해 개발하고 있다. 구글은 안드로이드의 모든 소스 코드를 오픈 소스 라이선스인 아파치 v2 라이선스로 배포하고 있어 기업이나 사용자는 각자 안드로이드 프로그램을 독자적으로 개발을 해서 탑재할 수 있다. 또한 응용 프로그램을 사고 팔 수 있는 구글 플레이를 제공하고 있으며, 이와 동시에 각 제조사 혹은 통신사별 응용 프로그램 마켓이 함께 운영되고 있다. 마켓에서는 유료 및 무료 응용 프로그램이 제공되고 있다.


안드로이드의 역사 

- 2005년 7월 구글이 미국 캘리포니아 주의 팔로알토에 위치한 작은 '안드로이드'사를 인수


- 2007년 11월 5일 텍사스 인스트루먼트, 브로드컴 코퍼레이션, 구글, HTC, 인텔, LG전자, 마벨 테크놀로지 그룹, 모토로라, 엔비디아, 퀄컴, 삼성전자, 스프린트 넥스텔, T-모바일의 몇몇 회사로 구성된 컨소시엄인 오픈 핸드셋 얼라이언스(OHA)가 모바일 기기의 공개 표준을 개발하는 것을 목표로 결성되었다. 또한 OHA는 리눅스 커널 2.6에서 빌드된 그들의 첫 번째 모바일 기기 플랫폼 결과물인 안드로이드를 발표.


- 2008년 10월 21일 안드로이드의 오픈소스 선언, 구글은 네트워크와 텔레폰 스택을 포함하는 완전한 소스 코드를 아파치 라이선스로 공개하였다.


- 2008년 12월 9일 ARM 홀딩스, 아세로스(Atheros Communications), 아수스, 가르민, 소프트뱅크, 소니 에릭슨, 도시바, 보다폰으로 구성된 새로운 14개의 멤버가 안드로이드 프로젝트에 참여하였다.


- 2010년 12월 15일 중국산 보급형 태블릿 단말 뿐만 아니라 갤럭시탭, 노션 잉크의 아담 등 하이엔드 유저를 겨냥한 태블릿 단말들이 출시되어 있는 상태로 안드로이드는 휴대전화 뿐 아니라 3G 또는 와이파이 전용 태블릿 단말에도 탑재되어 출시되고 있다.


구조 -


안드로이드의 구조는 위쪽 그림과 같은 구성 요소로 구성되며 이 구성 요소에는 응용 프로그램, 응용프로그램 프레임워크, 라이브러리, 안드로이드 런타임, 리눅스 커널의 총 5개의 계층으로 분류되어 있다.


버전 -

안드로이드는 6개월~12개월에 한번씩 업데이트를 진행한다. 업데이트의 내용은 주로 오류 수정이나 새로운 기능 추가로 구성된다. 하지만 이전 버전을 사용하는 기기들은 바로 업데이트를 제공받을 수 없으며, 기기 제조사에서 구글의 소스를 받아 직접 작업후 배포해야 한다. 이때문에 아직도 구버전 사용자가 많은 것이다. 참고로, 안드로이드의 각 버전들은 알파벳 첫 글자를 오름차순에 맞춘 음식 이름(디저트)을 코드명으로 삼고 있다. 버전은 1.0,2.0...으로 올라가며, 앞자리의 숫자가 올라가면 대규모 업데이트(메이저 업데이트), 소수점 아래 숫자가 올라가면 소규모 업데이트(마이너 업데이트)로 판명한다.


안드로이드는 6개월~12개월에 한번씩 업데이트를 진행한다. 업데이트의 내용은 주로 오류 수정이나 새로운 기능 추가로 구성된다. 하지만 이전 버전을 사용하는 기기들은 바로 업데이트를 제공받을 수 없으며, 기기 제조사에서 구글의 소스를 받아 직접 작업후 배포해야 한다. 이때문에 아직도 구버전 사용자가 많은 것이다. 참고로, 안드로이드의 각 버전들은 알파벳 첫 글자를 오름차순에 맞춘 음식 이름(디저트)을 코드명으로 삼고 있다. 버전은 1.0,2.0...으로 올라가며, 앞자리의 숫자가 올라가면 대규모 업데이트(메이저 업데이트), 소수점 아래 숫자가 올라가면 소규모 업데이트(마이너 업데이트)로 판명한다.


구성 및 특징 -

커널 : 리눅스

그래픽 엔진 : 오픈 GL의 휴대기기용 버전인 오픈GL ES를 채택

폰트 : 프리타입

웹 렌더링 : 웹키트 엔진

보안 모듈 : SSL

개발환경 : 이클립스와 이클립스에 통합된 플러그인 ADT(안드로이드 개발 도구) 사용을 권장하고 있음.



안드로이드 버전별 점유율(13년 8월 1일 기준) -




출처 - 위키백과 ( http://ko.wikipedia.org )

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

public static byte[] shortToByte(short a) {

byte[] shortToByte = new byte[2];

shortToByte[0] |= (byte)((a & 0xFF00) >>> 8);

shortToByte[1] |= (byte)(a & 0xFF & 0xff);

return shortToByte;

}  

   public static byte[] intToByte(int a) {  

     byte[] intToByte = new byte[4];     

     intToByte[0] |= (byte)((a&0xFF000000)>>24);     

     intToByte[1] |= (byte)((a&0xFF0000)>>16);     

     intToByte[2] |= (byte)((a&0xFF00)>>8);     

     intToByte[3] |= (byte)(a&0xFF);   

     return intToByte;  

   }  


-끝-

Android/WI-FI | Posted by 덩치 2013. 10. 23. 16:18

Wifi를 검색하여 자동으로 연결하기

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

wifi를 검색하는 방법에 대해서는 이전 글에서 알아보았다.


wifi에 연결하기 위해서는 보안방식과 비밀번호, ssid가 필요한데

보안방식과 ssid는 이전글의 ScanResult에서 뽑아낼 수가 있다.


비밀번호를 모르면 당연히 보안이 걸려있는 wifi에는 연결이 불가능.


일단 소스를 살펴보자


open일때

wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);

wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);

wfc.allowedAuthAlgorithms.clear();

wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);

 

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

wep일때

wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);

wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);

wfc.allowedProtocols.set(WifiConfiguration.Protocol.WPA);

wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);

wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);

wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);

 

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);

wfc.wepKeys[0] = "123456abcd";   <<--이부분중요. \"부분 빼고 그냥 비밀번호만 넣는다

wfc.wepTxKeyIndex = 0;

wpa나 wpa2일때

wfc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);

wfc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);

wfc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);

wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);

wfc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);

wfc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);

wfc.preSharedKey = "\"".concat("123456abcd").concat("\"");


이렇게 보안방식별로 설정 방법이 다르다.

wpa와 wpa2는 설정이 같다고 하는데 필자의경우 wpa방식은 연결이 안되더라.

실제 테스트해본건 wpa2와 wep, open밖에 없다.

참고로 ScanResult.capabilites에서 뱉어주는 보안방식이 실제 open, web, wpa로 나오는건 아니고

[WPA-PSK-TKIP+CCMP][ESS]

[WPA2-PSK-CCMP][WPS][ESS]  이런식이며, 같은 방식도 length가 다른경우가 있다.

이부분은 알아서 잘 처리해주리라 믿고,



먼저 공통설정을

WifiConfiguration wfc = new WifiConfiguration(); (WifiConfiguration는 전역변수,지역변수 알아서 상황에 맞게 조절한다)

wfc = new WifiConfiguration();

wfc.SSID = "\"".concat(ssid 입력).concat("\"");

wfc.status = WifiConfiguration.Status.DISABLED;

wfc.priority = 40;

이렇게 해준다.


그리고 위의 보안방식에 따른 설정을 해 주고,


int networkId = wm.addNetwork(wfc);

if (networkId != -1) {

wm.enableNetwork(networkId, true);

}


이렇게 해주면 해당하는 wifi에 연결이 완료된다.

open형의 경우에는 level(신호세기)에 따라 정렬을 해 주고, 위의 소스를 적용시키면 가장 신호가 센놈으로

자동으로 연결될듯하다.



-끝-


Android/WI-FI | Posted by 덩치 2013. 10. 23. 16:08

Wifi 목록 검색하는법

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO


전역변수로 

ScanResult scanResult;

WifiManager wm;

List apList;


WifiManager 초기화

wm = (WifiManager) getSystemService(WIFI_SERVICE);


검색

wm.startScan(); 때려주고


IntentFilter filter = new IntentFilter();

filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);

registerReceiver(wifiReceiver, filter);

이렇게 브로드캐스트리시버를 사용해줘야한다.

이유는 스캔이 끝났을 때를 체크하기 위해서이다


브로드캐스트리시버 선언

private BroadcastReceiver wifiReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {

searchWifi();

}

}

};

스캔이끝났다는 방송이 전달되면 searchWifi() 호출


searchWifi를 보면

public void searchWifi() {

apList = wm.getScanResults();

if (wm.getScanResults() != null) {

int size = apList.size();

for (int i = 0; i < size; i++) {

scanResult = (ScanResult) apList.get(i);

}

}

}


이렇게 하면 scanResult에 Wifi에 대한 정보들이 입력된다. 호출은 반복문 안에서나 원하는 위치에서

scanResult.SSID 등으로 이용할 수 있다.

Wifi가 on인지 off인지 모를때는 필터액션에 와이파이 스테이트 체인지액션까지 넣어주면 더욱좋다


-끝-

Android/Adb | Posted by 덩치 2013. 10. 22. 13:58

자주 사용하는 ADB 명령어

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

Adb의 개념에 대해서는 이 전 글에서 알아봤으니, 이번에는 명령어에 대해 알아보자


다음 명령어들은 Path설정이 돼 있다면(이전 글 참조) 다른 준비작업 없이

커맨드라인에 그냥 입력하면 된다.


adb devices

현재 컴퓨터에서 인식하고 있는 Device 또는 Emulator 목록을 출력한다.

다른 작업을 하기 전 우선 단말이나 에뮬이 제대로 인식되었는지 확인차 사용한다.


adb install filename

filename은 apk파일의 이름이다. Device나 Emulator에 filename에 해당하는 어플을 설치하라는 

명령이다. 추가옵션으로 -r과 -l을 설정해 줄 수 있다.

-l은 어플이 다른 장치로 복사되는것을 막는 옵션, -r은 이미 존재하는 어플을 삭제하지 않고 설치


adb uninstall 패키지경로

ex ) com.android.test  (.apk를 제외한 패키지 전체경로 입력)

해당하는 어플이 삭제된다


adb push local_파일명 remote_파일명

개발자 컴퓨터의 파일을 타겟에 복사한다.


adb pull remote_파일명 local_파일명

타겟의 파일을 개발자 컴퓨터로 복사한다.


adb shell

Device에 직접 접속하는 명령어. 이 명령어를 통해 android console에 직접 접속할 수 있다.

디바이스를 루팅하지 않으면 리눅스에서는 먹히는 명령이 먹히지않는경우가 많다.


adb kill-server

adb에 문제가 있을 경우, adb를 종료시킨다. (단말기와 노트북의 케이블을 뺏다꽂아도된다)


adb start-server

종료된 adb를 실행시킨다.


adb reboot

Device를 재시작한다. (리부팅)


이정도가 자주사용되는 명령어들이고,


그 외 명령어들이 궁금하다면 그냥 adb 만 입력하면 도움말이 나온다.


디벨로퍼 사이트에서 좀 더 자세한 사항을 알아보고싶다면

http://developer.android.com/tools/help/adb.html 로 이동하면 된다.


-끝-




'Android > Adb' 카테고리의 다른 글

Adb에 대해 알아보자  (1) 2013.10.22
Android/Adb | Posted by 덩치 2013. 10. 22. 11:27

Adb에 대해 알아보자

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

이 글에서는 Adb의 개념과 사용을 위한 환경구축에 대해 다뤄보겠다.

명령어나 사용법은 다음 글에서 다룬다.



ADB(Android Debug Bridge)란 ?

안드로이드 SDK에 포함되어 있는 기능으로, 안드로이드 디버그에 관련된 툴

따라서 SDK의 설치가 필수적 (http://developer.android.com/sdk/index.html)이며, 기능으로는

어플리케이션 설치, 디바이스 접속 및 관리, 파일 업/다운로드, 시스템 로그출력, shell 접속 등이 가능하다.

특히 shell 접속 후 커맨드라인을 통하여 다양한 작업이 가능하다.

android는 리눅스 기반 운영체제이기때문에, shell에 접속하여 리눅스의 명령어를 사용 할 수 있다.

(모든 명령어를 지원하지는 않지만...)


ADB를 사용하기 위해서 -

adb명령을 사용할 때 마다 경로를 입력하기 번거로우니 환경변수를 등록 해 준다.



컴퓨터 마우스 우클릭 > 속성 > 고급 시스템 설정 > 환경변수 선택




Path 선택 > 편집 클릭



맨 뒤 ; 다음 sdk의 platform-tools경로 입력

(필자는 C:\Program Files\adt-bundle-windows-x86_64-20130522\sdk\platform-tools) > 확인


이러면 환경변수는 등록이 끝났다.


잘 등록되었는지 확인을 해 보자





명령프롬프트창 (윈도우키+R)을 띄운 뒤 adb 엔터 했을때 이렇게 글이 막 나온다면 성공, 사용 준비 끝


명령어나 사용하는 방법은 다음 글을 참고하기바란다


-끝-


'Android > Adb' 카테고리의 다른 글

자주 사용하는 ADB 명령어  (0) 2013.10.22
Android/Compile | Posted by 덩치 2013. 10. 21. 17:17

apk파일 디컴파일하기

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

apk파일을 디컴파일하게되면 원본 소스코드를 100%는 아니더라도 확인이 가능하다.

다만, 소스코드 난독화(proguard등)가 적용되어 있다면 코드의 해석은 상당히 힘들게된다.

그럼에도 불구하고 필요한 소스코드가 있다면 디컴파일하여 쓸만한 건덕지를 찾아봐야하니 디컴파일은 중요하다고

할 수 있다. (개발자의 경우 상당히 기분나쁜부분, 우리는 참고용으로만 사용하자)

디컴파일 전에 몇가지 준비사항이 필요하다.


1. https://code.google.com/p/dex2jar/downloads/list 

여기서 dex2jar 다운로드 > 

C:\Program Files\adt-bundle-windows-x86_64-20130522\sdk\platform-tools\dex2jar-0.0.9.15 경로에 압축해제 

(위 경로는 본인의 경우이고, sdk가 있는 경로상에 집어넣어주면 된다.)

dex2jar.bat 파일 우클릭 후 편집 > echo off 를 echo on 으로 수정



2. http://varaneckas.com/jad/

여기서 최신버전 Jad (자바 디컴파일러) 다운로드 > 압축해제


이제 디컴파일 준비는 끝났다.


시작




- 우선 디컴파일할 apk파일의 확장자를 apk 에서 zip로 바꾸면 zip파일이 된다.

- 압축해제하면 classes.dex 파일이 나온다. 이것만 있으면 된다






그렇게 나온 classes.dex 파일을

아까 받은 dex2jar 폴더로 이동시킨다





그리고 현재 위치의 경로를 복사 한 뒤

시작 > 실행 > cmd > cd적은다음 한칸띄고 마우스 우클릭 > 붙여넣기 > 엔터 하면

위의 경로로 이동





이제 d2j-dex2jar.bat classes.dex를 적고 엔터를 누르면 사진과같이 이상한글이 쫘르륵 나오고

경로에 classes-dex2jar.jar 파일이 생성된다.

버전에 따라 d2j-dex2jar.bat가 아니라 dex2jar.bat 인경우도 있는듯 하니 파일명을 잘보고 알아서 입력한다


그리고 생성된 파일을 압축해제하면 클래스파일들이 나오게 된다.




필자는 proguard를 적용한 apk를 사용했기때문에 보는바와같이 클래스명이 저렇게 지맘대로다.

이제 MainActivity.class를 java파일로 변환해줘야 소스코드를 확인할 수 있다.


MainActivity.class파일을 복사하여 2번에서 설치한 Jad가 설치된 경로에 붙여넣어준다





그리고





다시 시작 > 실행 > cmd > jad 경로로 이동 후


jad -o -sjava MainActivity.class  엔터




그러면 이렇게 MainActivity.java 파일이 생긴다 ! 실행해보자




다시말하지만 필자는 코드난독화(proguard)를 적용했기에 변수명이 이렇게 알아먹기 힘들게 표시된다.

(적용하지 않으면 대부분의 소스코드를 볼 수 있다)

오랜시간 해석한다면 불가능하진 않지만 상당한 곤욕을 치루는것은 어쩔 수 없다.


proguard에 관한 포스팅은 이전글을 참고하길 바라며


-끝-

펌 OK (출처 표시), 상업적 이용 NO, 컨텐츠 변경 NO

프로그램 코드 난독화는 특정 난독화 알고리즘(Layout, Data, Control Obfuscation)을 적용하여 소스코드를 분석하기 어

렵게 변환해주는 시스템이다. 본 시스템의 목적은 상세설계에 준하는 설계구조와 주석문, 프로그램 처리방식, 기능 배치, 

구성 등의 설계아이디어 또는 해당하는 알고리즘이나 성능 및 최적화를 위한 구현 노하우 등이 내포되어 있는 SW 소스코

드의 원천기술 유출을 방지하는 것이다.

여기서는 안드로이드의 Proguard를 이용해 코드난독화를 적용한다.

구버전의 포스팅을 보면 proguard.cfg 파일에 대한 언급이 중요시다뤄지는데,

지금의 버전에서는 해당 파일의 유무는 신경쓰지 않는다.


proguard가 적용되는 시점은 프로젝트를 Export할 때 적용되므로, 배포용 apk를 추출하는 방법을 

알고있다면 더 쉽게 할 수 있다. 

(이전 포스팅글 : http://biig.tistory.com/entry/%EC%96%B4%ED%94%8C-%EB%B0%B0%ED%8F%AC%EB%A5%BC-%EC%9C%84%ED%95%9C-keystore%EC%83%9D%EC%84%B1-%EB%B0%8F-%EB%B0%B0%ED%8F%AC%EC%9A%A9-apk-%EC%83%9D%EC%84%B1)




시작


먼저 - adt를 최신버전으로 업데이트시켜준다 ( Help > Check for Updates)

그다음



해당 프로젝트의 project.properties를 실행시켜 표시된부분의 주석을 해제한다.





그리고 해당 프로젝트 우클릭 > Export... 선택





Android 폴더의 Export Android Application 선택후 넥스트




Project명은 자동으로 입력되니 넥스트




keystore 생성하는법은 이전 글에 나와있으니 참고하시고, 이미 키가 있다면 Use existing keystore 선택 후

Browse... 눌러서 원하는 키 선택후 키의 비밀번호 입력 > 넥스트





키 만들때 Alias와 함께 넣은 비밀번호 입력 후 넥스트





apk가 저장될 위치를 설정하고 난 뒤 Finish를 눌러 마무리



그런데 warning이 뜨면서 프로가드가 적용이 안되는 경우가 있다.


그럴때는 어떤 클래스에서 warning이 뜨는지를 파악한 후




이런식으로 해당 클래스에 예외를 걸어줘야한다. proguard warning 등으로 검색하면


많은 정보들을 찾을 수 있을것이다.


-끝-



이렇게하면 proguard가 적용되어 코드난독화가 적용된 apk파일이 생성된다.


이렇게 해줘야 내가 힘들게 짠 소스코드를 다른사람이 디컴파일해서 재사용하는것이 힘들게 할 수 있다.


proguard가 적용되면 어떤 차이가 있는지는 다음 글에서 apk 디컴파일 방법과 함께 소개하겠다.



'Android > Compile' 카테고리의 다른 글

apk파일 디컴파일하기  (12) 2013.10.21
어플 배포를 위한 keystore생성 및 배포용 apk 생성  (0) 2013.10.21