2013년 2월 27일 수요일

tizen - Privileged API

대분의 API는 오픈되어 있으며 특별한 권한이 없이 사용이 가능하다.
그러나 Privileged API는 사용하기 위해 manifest.xml에 <features> 태그로 추가를 해주어야 한다.
권한이 필요한 API를 확인하는 방법은 API Reference 문서를 보거나 "API and Privilege Checker" 툴을 이용해 체크하는 것이다.

API Reference 문서의 메소드 설명에 권한이 필요한 메소드는 "Privilege" 항목이 명시되어 있다.


Tizen::Net::Sockets::Socket::Bind 메소드 설명의 예)


Privilege:
    http://tizen.org/privilege/socket


tizen - Native App - I/O overview

타이젠은 리눅스의 파일시스템을 사용하며 다음과 같은 특징이 있다.

- Tizen::Io 네임스페이스의 메소드로 파일시스템 사용가능
- 어플리케이션은 상대경로를 사용할 수 있다.
- 파일시스템은 대/소문자를 구분한다.
- 시스템 설정에 따라 달라질 수 있으나 다음과 같은 제약이 있다.

  • 파일이나 디렉토리 1024개까지 처리
  • 파일이나 디렉토리 이름의 최대 길이는 255까지
  • 전체 경로의 최대 길이는 4096까지


1. 어플리케이션 홈 디렉토리
Tizen::App::App 클래스의 GetAppRootPath() 메소드로 경로를 얻음

홈 디렉토리의 구조
- data : 어플리케이션 개별 데이터 처리에 사용되며 읽기/쓰기 속성
- shared/data : 다른 어플리케이션에 데이터를 공유할때 사용하며 읽기 속성
- shared/res : 다른 어플리케이션에 리소스를 공유할때 사용하며 자신은 읽기/쓰기 속성, 다른 어플은 읽기 속성


2. 미디어 디렉토리
모든 어플리케이션이 엑세스가능하며 읽기/쓰기 속성을 갖는다.
Tizen::System::Environment 클래스의 GetMediaPath() 메소드로 경로를 얻음

미디어 디렉토리의 구조
- Images : 이미지 데이터
- Sounds : 음악
- Videos : 동영상
- Others : 기타


3. 외장 저장공간
모든 어플리케이션이 엑세스가능하며 읽기/쓰기 속성을 갖는다.
Tizen::System::Environment 클래스의 GetPredefinedPath() 메소드로 경로를 얻음

외장 저정공간 디렉토리 구조
- Images : 이미지 데이터
- Sounds : 음악
- Videos : 동영상
- Others : 기타



tizen - out of memory policy

메모리가 부족할 경우 메모리 확보를 위해 이전에 실행된 어플리케이션을 종료하는 동작이 수행된다.
어떤 어플리케이션을 먼저 종료하는지 판단하는 기준은 아래와 같다.

1. Background UI 어플리케이션
2. Service 어플리케이션
3. Background 미디어 플레이어
4. Foreground UI 어플리케이션
5. Foreground  미디어 플레이어
6. 어플리케이션 런처
7. 음성/화상 전화 어플 및 기타 시스템 어플

2013년 2월 25일 월요일

android - security tips

안드로이드 보안의 특징
 - 샌드박스는 다른 어플들에서 데이터 엑세스나 실행을 보호한다.
 - 암호화, 퍼미션, 안전한 IPC 등 일반적인 보안 특징을 제공한다.
 - 메모리 에러를 감소시키는 기술들을 제공한다.
 - 암호화된 파일시스템은 디바이스 분실시 데이터를 보호한다.
 - 사용자 동의의 퍼미션 기능은 사용자 데이터나 시스템 기능의 접근을 제한한다.
 - 어플별로 퍼미션을 설정하여 어플 데이터를 제어한다.

안드로이드는 위와 같은 보안 기능을 제공하나 부주의로 보안에 문제가 발생 할 수있으며, 다음과 보안관련 권고사항을 준수하여야 한다.


1. 데이터 저장
 안드로이드에서 보안 이슈는 대부분 데이터와 관련이 있으며 주요한 3가지 방식을 설명한다.

 1) 내부 저장소 사용
  - 기본적으로 안드로이드 내부 저장소는 자기 자신만이 엑세스 할 수 있다.
  - 일반적인 경우 MODE_WORLD_WRITEABLE, MODE_WORLD_READABLE 설정의 사용을 피해야 하며 만일 외부 어플에 데이터를 공유하고자 한다면 Content Provider를 사용해야 한다.
  - 중요한 데이터에 대한 추가적인 보안 기능 적용을 위해 어플에서 직접 엑세스 할 수 없는 키 데이터로 파일을 암호화한다.

 2) 외부 저장소 사용
  - SD Card와 같은 외부 저장소는 전역에서 읽고 쓰기가 가능하며 모든 어플에서 접근할 수 있기에 중요한 데이터는 저장하지 말아야 한다.
  - 실행파일이나 class를 저장하지 말고 동적로드로 코드를 실행하지 말아야 한다.
  - 만일 실행파일이나 class를 외부 저장소에서 읽어와 실행하고자 한다면 동적 로드전 검증을 해야한다.

 3) Content Provider 사용
  - 컨텐츠 프로바이더는 자신이나 외부 어플에 대해 제한된 접근을 할 수 있는 구조화된 기술을 제공한다.
  - android:exported 속성으로 외부 어플에서 데이터 엑세스를 허용 할 수 있다.
  - android:protectionLevel속성을 signature로 설정하면 같은 key로 signed된 어플만 엑세스 할 수 있게한다.
  - android:grantUriPermissions 속성과 Intent에 FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION flag 사용으로 일기/쓰기 제약을 할 수 있다.


2. 퍼미션 사용
 - 안드로이드는 샌드박스에 의해 제약이 가해져 있기에 카메라와 같은 디바이스 장치나 데이터에 엑세스 하기 위해서는 퍼미션을 명시하여야 한다.

 1) 퍼미션 요청
  - 보안을 위해 필요한 최소한의 퍼미션만 명시하길 권장한다.
  - 사용자 승인의 퍼미션 보단 접근 컨트롤의 사용을 권장한다.(위 1번 데이터 저장의 Content Provider 권한 설정같은)

 2) 퍼미션 생성
  일반적으로 정의된 퍼미션을 최소한으로 사용하여 구현하고 퍼미션의 생성은 다음 사항을 고려하여 신중히 검토 후 만들어야 한다.
  - 퍼미션은 사용자가 보안 항목이라 판단할 수 있는 간결한 문자열을 가져야 한다.
  - 퍼미션 문자열은 다국어를 지원해야 한다.
  - 사용자는 퍼미션이 혼란스럽거나 위험한 것으로 판단되면 설치하지 않을 것이다.
  - 퍼미션이 설치되지 않았다면 어플리케이션은 퍼미션을 요청할 것이다.


3. 네트워크 사용
 - 네트워크는 사용은 데이터를 전송하기에 본질적으로 위험을 내포하고 있다.

 1) IP 네트워크 사용
  - 안드로이드 네트워크는 리눅스와 크게 다르지 않으며 중요한 것은 중요한 데이터의 통신에 적절한 프로토콜을 사용하는 것이다.
  - 모바일 디바이스는 안전하지 않은 공개된 네트워크에 연결하는 경우가 많기에 Secure Socket을 사용하는 것을 권장한다.
  - 보안 상의 이유로 어플간에 localhost를 사용한 데이터 통신을 막았으며 대신 인증이 가능한 Service 같은것을 사용해야 한다.
  - 또한 WebView는 안전하지 않은 HTTP와 같은 프로토콜로 믿을 수 없는 데이터를 다운로드하는 것을 막는 유효성 체크 기능을 제공한다.

 2) 전화 통신 사용
  - SMS는 사용자간 연락을 주 용도로 설계되어 데이터 통신에는 적합하지 않다.
  - SMS의 제약으로 데이터 통신은 Google Cloud Messaging이나 Web 기반의 IP 네트워크를 사용하길 권한다.
  - SMS는 암호화되지도 않으며 강력한 인증을 사용하지도 않는다.
  - 네트워크 상에서 spoofing이나 interception의 대상이 될 수 있다.
  - READ_SMS 퍼미션을 갖는 다른 어플에 의해 수신될 수 있다.


4. Input Validation 수행
 - 안드로이드는 플랫폼 레벨에서 Input Validation에 대응할 수단을 갖추고 있고 이를 잘 활용해야 한다.
 - 만일 Native를 코드를 사용해서 파일이나 네트워크 입/출력을 한다면 노출에 대한 잠재적 위험을 안고 있으며 대부분의 문제는 buffer overflows, use after free, off-by-one errors  등이며 안드로이드는 ASLR, DEP등 문제를 감소시킬 많은 기술을 제공하지만 충분하지 않으며 포인터나 버퍼의 사용에 주의해야 한다.
 - JavaScript, SQL과 같은 문자열 기반의 언어는 escape characters, script injection 등의 문제를 안고 있다.
 - SQL의 경우는 Content Provider를 이용해 parameterized queries방식을 지원하는 것이 이상적이다. (쓰기 권한이 필요없는 데이터는 읽기 권한만 부여한다.)
 - 만일 위와 같은 보안기능을 사용할 수 없다면 데이터를 구조화 시키고 이에 대한 유효성을 체크하는 기능을 부여하라. (데이터 변조를 감지할 수 있는)


5. 사용자 데이터 다루기
 - 사용자 정보와 같은 민감한 데이터에 API 사용을 최소화 하고 사용할 수밖에 없다면 Hash나 non-reversible form을 사용해라.(메모리 덤프 등으로 노출될 가능성을 줄임)
 - 네트워크 전송이나 공유된 저장소에 저장하는것을 피하라.
 - 사용자 정보에 대한 키값으로 폰번호나 IMEI 등을 사용하지 마라.
 - 로그를 남길때 주의하라. READ_LOGS 권한을 갖는 어플도 함께 읽을 수 있다.


6. WebView 사용
 - WebView는 HTML이나 JavaScript와 같은 컨텐츠를 처리하기에 cross-site-scripting(JavaScript Injection)과 같은 웹 보안 이슈에 노출될 수 있다.
 - WebView는 기본적으로 JavaScript를 실행할 수 없으며 컨텐츠에서 JavaScript를 사용하지 않는다면 setJavaScriptEnabled() 호출하지 마라.
 - addJavascriptInteface()를 사용할때 주의해야 한다. 신뢰할 수 없는 스크립트 실행으로 안드로이드 메소드가 실행될 수 있다.
 - local에 저장된 파일을 삭제하기 위해 clearCache() 메소드를 사용할 수 있다.
 - Server에서 헤더에 no-cache옵션을 사용할 수 있다.


7. 자격증명 다루기
 - 일반적으로 자격증명 요청시도를 최소화 하라
 - 사용자명이나 암호를 로컬에 저장하여 인증에 사용하지 말고, 다수 어플에서 사용시 AccountManager를 이용해라.
 - 단일 어플에서만 사용하고자 한다면 KeyStore를 사용해라.


8. 암호화 사용
 - 파일시스템 암호화, 안전한 소켓 채널 등에 더불어 안드로이드는 암호화를 사용한 데이터 보호기능을 제공한다.
 - 안전한 네트워크 통신을 위해 자체 구현된 암호화 기술보단 HttpsURLConneciton이나 SSLSocket을 사용하길 권한다.
 - 암호화 알고리즘을 직접 구현하기 보단 Cipher에서 제공하는 AES, RSA 등을 사용하길 권한다.
 - 암호화 알고리즘에 사용하는 키를 생성시 SecureRandom은 그리 안전하지 않으며 KeyGenerator를 사용하길 권한다.


9. 프로세스 내 통신
 - 일부 어플들은 localhost 소켓, 공유 파일 등전통적인 리눅스 기술을 사용하여 IPC를 구현하였으나 안드로이드에서는 Service와 BroadcastReceiver로 Intent, Binder, Messenger 를 이용하여 안전한 IPC를 구현할 수 있다.
 - 만일 다른 어플에게까지 확장시키지 않으려면 <service> 태그에 android:exported 속성을 false로 주면된다.(이 옵션은 하나의 UID에 다수 프로세스를 사용하는 어플에 유용하다)
 - 다른 어플들에게까지 확장하여 사용한다면 퍼미션을 지정하여 보안정책을 적용할 수 있다.(android:protectionLevel 속성을 signature로 지정하여 같은 key로 signed된 어플들만 허용할 수 있음)


10. Intent 사용
 - Intent는 안드로이드에서 비동기적인 IPC 구현에 사용된다.
 - sendOrderedBroadcast()는 수신자에 의해 소비되어 하나의 수신자만이 받을 수 있다. 퍼미션을 함께 적용하면 꼭 받아야할 하나의 수신자가 받게된다.


11. 서비스 사용
 - 서비스는 종종 다른 어플에게 기능을 제공하기 위해 사용된다.
 - 서비스는 기본적으로 다른 어플에게 확장되지 않는다.
 - <service> 태그에 IntentFilter를 추가하면 기본적으로 다른 어플에게까지 확장된다.
 - android:exported 속성으로 명시적으로 다른 어플에게 확장됨을 지정할 수 있다.
 - 서비스 요청이 왔을때 실행전 checkCallingPermission()으로 퍼미션을 체크할 수 있으나 manifest에 명시적으로 퍼미션을 선언하는 것을 권한다.

 1) Binder와 Messenger 인터페이스 사용
  - 안드로이드에서 RPC 형태의 IPC 구현에 사용된다.
  - 해당 인터페이스를 위한 별도의 퍼미션 설절은 필요하지 않으며 구현된 Activity놔 Service의 퍼미션을 따른다.
 2) BroadcastReceiver 사용
  - Intent에 의한 요청을 비동기적으로 처리한다.


12. 코드의 동적 로딩
 - APK 밖의 코드를 동적 로드하는것을 권하지 않는다.
 - 다운로드된 코드나 SD Card에 존재하는 코드를 동적로드 하는 것은 매우 위험하며 불가피하게 사용해야 한다면 암호화나 위변조방지 기술을 사용해야 한다. (디바이스에서 제공하는 내부 저장공간의 부족등의 이유로 불가피하게 사용하는 경우가 있음)


13. 가상머신에서 보안
 - 안드로이드에서 사용하는 dalvik 또한 다른 가상머신에서 제공하는 보안 코드를 제공하고 있다.
 - 어플을 개발할때 가상머신과 관련해서 보안에 특이하게 고려할 필요는 없다.
 - 안드로이드에서 제공하는 Sandbox는 가상머신이 아닌 OS레벨에서 제공하는 기능으로 Native코드나 dalvik 모두에게 적용된다.


14. Native 코드에서 보안
 - 일반적으로 NDK를 이용한 Native 코드의 사용보단 SDK의 사용을 권장한다.
 - 만일 Native 코드를 개발하고자 한다면 안드로이드는 Linux 커널 기반으로 만들어졌기에 리눅스 개발을 위한 보안 가이드라인을 따르길 바란다.
 - 안드로이드와 리눅스의 가장 큰 차이는 Sandbox이며 Native 코드를 포함한 안드로이드 어플은 Sandbox 안에서 실행된다.


참고 URL)

http://developer.android.com/training/articles/security-tips.html

http://www.securingjava.com/toc.html

http://www.dwheeler.com/secure-programs/

2013년 2월 20일 수요일

android - running in a background service

Background Service 실행

특정 화면내에서 장시간 작업의 수행은 Background Thread를 이용합니다.
그러나 특정 화면에 국한되지 않거나 매우 긴 작업 수행이 필요한 경우 Background Service를 이용할 수 있습니다.

Background Service의 대표적인 예가 IntentService이며 이를 활용하는 방법을 설명합니다.

1.Background Service 생성
 1) IntentService를 상속받는 클래스를 만듭니다.
 2) onHandleIntent() 콜백 메소드를 구현합니다.
  - 해당 메소드의 인자로 받은 Intent로 요청 데이터를 받아 단일 쓰레드로 작업을 처리할 수 있습니다.
 3) AndroidManifest.xml에 service로 등록합니다.

2. Background Service에 작업 요청하기
 1) Intent에 작업 요청을 위한 데이터 세팅
 2) startService() 메소드로 서비스 호출 및 작업 요청
 3) IntentService의 onHandleIntent()가 콜백되어 작업처리
  - onHandleIntent() 메소드가 콜백되어 실행되며 이는 단일 쓰레드 이기에 한번에 하나의 Intent씩 처리됩니다.
  - onHandleIntent() 처리중 다른 요청이 오게되면 이전 작업이 완료된 후 처리됩니다.

3. 작업 상태 레포팅
 1) IntentService에서 작업 상태 레포팅 하기
  - LocalBroatcastManager의 sendBroadcast() 메소드를 이용하여 주기적인 레포팅
 2) BroadcastReceiver를 LocalBroatcastManager로 등록하여 onReceive() 콜백 메소드로 레포팅 결과를 얻을  수 있습니다.

2013년 2월 17일 일요일

android - proguard

코드 난독화 및 최적화를 위한 툴로 Android 2.3인 진저브레드부터 Android SDK에 내장되었습니다.
소스코드에 공개될 경우 문제가 되는 정보가 담겨 있는 경우 반드시 proguard를 적용해야 합니다.


설정방법

1. proguard 설정 파일 지정
project.properties파일에 proguard.config=[프로가드설정파일] 형태로 명시합니다.
 예) proguard.config=proguard-android.txt


2. proguard 설정 파일 생성
Android SDK 홈 디렉토리 밑에 /tools/proguard 디렉토리가 존재합니다.
해당 디렉토리에는 proguard-android.txt 파일과 proguard-android-optimize.txt 파일이 있습니다.
이는 최적화 적용 여부에 따라 두개의 파일로 구분해 놓은 것 입니다.
처음 proguard를 적용하는 개발자라면 proguard-android.txt 파일을 사용하여 적용하길 권장합니다.


3. proguard 설정
proguard-android.txt 파일을 프로젝트 홈디렉토리에 복사하였다면 기본적인 proguard 옵션이 적용이 된 것입니다.

기본 적용된 옵션은 다음과 같습니다.
-dontusemixedcaseclassnames : 대/소문자 섞인 클래스 이름을 허용하지 않음
-dontskipnonpubliclibraryclasses : public library가 아닌것을 무시하지 않게 함
-verbose : 로그를 표시함
-dontoptimize : 최적화를 사용하지 않음
-dontpreverify : 사전 검증기능을 사용하지 않음

기본 적용된 설정은 다음과 같습니다.
- Annotation 유지
- 네이티브 메소드 유지
- android.view.View에서 상속받은 public class의 getter/setter 메소드 유지
- android.app.Activity에서 상속받은 public class의 메소드중 android.view.View 인자를 갖는 메소드 유지
- enumeration class의 일부 static 메소드 유지
- android.os.Parcelable interface를 구현한 class 및 Parcelable$Creator를 리턴하는 메소드 유지
- R 리소스 클래스의 static 필드 유지
- android support 라이브러리 유지

이외 자신이 개발한 프로젝트에 다음과 같은 항목을 사용중이라면 추가적인 적용을 해야 합니다.

 1) 미사용 코드를 제거하는 기능이 있는데 혹 잘못 판단되어 사용되는 코드가 제거 될 수 있습니다. (Injection 패턴과 같이 참조 방식을 사용하지 않은 코드라면 가능성이 높습니다.)
 적용 예)
 -dontshrink

 2) WebView의 addJavascriptInterface() 메소드를 사용하여 Javascript 연동 코드를 사용하신다면 등록되는 Object class의 메소드는 유지되어야 합니다.
 -keepclassmembers class [클래스 풀네임] {
    <methods>;
}

 3) Class.forName과 같이 동적로드를 사용하는 코드에서 로드되는 class는 유지되어야 합니다.
 적용 예)
 -keep public class [클래스 풀네임]

 4) 외부 라이브러리 proguard 적용시 경고 무시
  -dontwarn 명령으로 패키지 명을 지정하여 지정 가능하며 해당 패키지로 시작하는 모든 패키지를 적용할 경우 뒤에 **로 지정
  적용 예)
  -dontwarn [시작 패키지명].**

 5) 외부 라이브러리 사용 설정
  - 사용된 외부 라이브러리를 proguard가 찾지 못할 경우 -libraryjars 명령으로 라이브러리를 지정한다. (APK에 포함되는 라이브러리는 설정 할 필요없음)
  적용 예)
  -libraryjars [라이브러리파일경로]/[라이브러리파일명].jar


참고)
proguard 설정 대상을 지정하는 방법들
 1) 단일 클래스 지정
  [클래스 풀네임]
  예) com.test.main.TestClass
 2) 패키지명 필터링
  [시작패키지명].**
  예) com.test.**
 3) interface 구현 클래스 모두
  class implements [인터페이스 풀네임]
  예) class implements com.test.define.TestInterface
 4) 상속받은 subclass 모두
  class extends [클래스 풀네임]
  예) class extends com.test.AbstractClass


참고 URL
http://developer.android.com/tools/help/proguard.html

http://proguard.sourceforge.net


android - improving layout performance

레이아웃 성능 최적화

1. Hierarchy Viewer를 사용해 Layout를 검사
 - 사용된 뷰 수와 Measure, Layout, Draw 처리 시간을 이용해 성능 저하를 유발하는 뷰를 찾을 수 있다.

2. Layout 재사용
 1) 재사용 할 수 있는 공통 뷰를 Layout을 작성
 2) <include/> 태그를 이용하여 뷰에 사용
 3) 재사용 할 수 있는 뷰의 Layout 작성시 <merge/> 태그를 활용하면 불필요한 View
Group 사용을 줄여준다.

3. 필요한 경우에 뷰를 로딩
 - ViewStub을 이용하면 크기도 없고 보여지지 않는 뷰를 사용자가 원하는 시점에 setVisiblity()나 inflate() 메소드의 호출로 원하는 뷰를 생성하여 표시할 수 있다.

4. ListView의 스크롤 부드럽게 만들기
 - 스크롤을 부드럽게 하려면 Main Thread(UI Thread)를 idle 상태로 유지 해야함.

 1) Background Thread를 사용해라
  - AsyncTask 등을 사용하여 디스크 I/O, 네트워크 I/O, DB I/O 등의 작업 수행은 Background Thread를 사용해야 한다.
 2) getView에서 findViewById() 를 사용하여 View를 얻을때 ViewHolder를 사용하여 한번 find된 View를 다시 find하지 않게 하라.

2013년 2월 15일 금요일

android - best practices for user experience & UI

1. 효과적인 네비게이션 계획

 1) 화면과 각 화면들의 관계를 설계
  (1) 기능 구현에 필요한 데이터와 행위를 정의하고 데이터 관계 다이어그램을 작성
  (2) 필요한 화면 목록을 작성
  (3) 화면별 네비게이션을 정의한 스크린 맵 작성
  (4) 화면을 구성하는 형태에 따라 분류

 2) 다양한 크기의 화면에 대응할 계획
  (1) 스마트폰, 태블릿, TV등에 대응하기 위해  Multi-Pane Layout Design을 고려하여 화면을 그룹으로 묶음
  (2) 디바이스의 방향 전환을 고려하여 stretch, expand/collapse, show/hide, stack 등의 방식을 고려
  (3) 위에서 작성된 스크린 맵에 그룹으로 묶을 화면을 표시

 3) 일반적인 계층형 네비게이션이 아닌 상/하, 좌/우 형태의 네비게이션 제공(descendent navigation, laterial navigation)
  (1) 버튼, 데쉬보드 등 클릭에 의한 동작
  (2) 리스트, 그리드, 캐러셀, 스택 뷰등 선택에 의한 동작
  (3) 탭 뷰
  (4) 가로 페이징(swipe) 동작

 4) Back 버튼 처리 및 상위로 가기 처리
  (1) Back 버튼 처리
   - 이전화면으로 돌아가기를 구현
  (2) 상위로 가기나 어플의 홈화면으로 가기 기능 구현

 5) 위 모두를 조합
  (1) 위 항목들을 적용하여 홈 화면 구성부터 메뉴 구성을 정의
  (2) 디지털 와이어프레임을 작성


2. 효과적인 네비게이션 구현

 1) 좌/우 네비게이션 구현(Lateral navigation)
  - 일반적으로 탭 뷰나 가로 페이징 뷰로 구현

 2) 상위 네비게이션 구현(Ancestral navigation)
  (1) 위로 올라가기 구현
  (2) 홈(어플리케이션 홈)으로 가기 구현

 3) Back 버튼 구현
  - 이전에 보고 있던 화면을 그대로 보여주는것이 가장 좋음

 4) 하위 네비게이션 구현(Descendant navigation)
  (1) 상세뷰 구현
   - 스마트폰과 태블릿에 따라 상세뷰는 Single-pane이나 Multi-pane으로 처리
  (2) 타 어플의 Activity를 호출하는 경우 Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET flag로 호출하여야 런처 아이콘으로 실행시 타 어플이 실행되는 것을 막는다.


3. Notification 기능을 사용
 1) Notification Building
  (1) 디바이스의 OS 버전 호환을 위해 Notification 대신 Android Support Library의 NotificationCompat.Builder 사용할 것을 권장함
  (2) PendingIntent로 Notification 클릭시 동작처리

 2) Notification에서 Activity 실행시 실행된 어플리케이션의 네비게이션 정보를 유지하게 하기
  (1) 어플리케이션에서 사용하는 Activity를 호출시
   - Activity를 상속받은 다른 이름의 Activity를 호출
   - 어플의 Task와는 별도의 Stack으로 처리
   - 런처 아이콘으로 실행시 Notification에 의해 호출된 Activity가 실행되면 안됌
  (2) Notification 전용의 Activity를 호출시
   - 어플의 Task Stack에 들어가지 않게 설정
   - 단일 Activity로 항상 새로 요청받은 정보를 처리하게 구현
   - 런처 아이콘으로 실행시 Notification에 의해 호출된 Activity가 실행되면 안됌

 3) Updating Notifications
  (1) Notification 변경
   - 동일한 ID로 notify를 하면 변경 동작을 수행
  (2) Notification 삭제
   - Notification의 clear all 버튼으로 전체 삭제
   - setAutoCancel 옵션으로 클릭시 자동 삭제
   - ID로 cancel 요청하여 삭제
   - cancelAll 요청으로 어플의 Notification 전체삭제

 4) Big View 사용
  (1) Notification은 normal view와 big view로 나뉘며 big view는 Android 4.1에서 추가되었다.
  (2) NotificationCompat.Builder를 사용하면 big view로 Notification을 처리하면 Android 4.1 미만 버전에서는 해당 옵션이 무시된다.

 5) Notification에 Progress 표시하기
  (1) 정해진 기간 만큼의 Progress 표시
   - NotificationCompat.Builder의 setProgress(max, curr, false)를 사용
   - 작업 Thread에서 Notification 변경 방식으로 curr 값을 바꿈(Thread에서 직접 변경 가능함)
  (2) 정해지지 않은 임의적 Progress 표시
   - NotificationCompat.Builder의 setProgress(0, 0, true)를 사용


4. 검색기능 추가
 1) SearchView는 Android 3.0에 추가된 기능



5. 다양한 화면을 위한 설계

 1) 다양한 화면 크기 호환 처리
  (1) 최소 너비를 기준으로 아래 항목들을 활용하여 화면을 구성
   - wrap_content, match_parent를 사용
   - RelativeLayout을 활용
   - LinearLayout의 layout_weight를 활용
  (2) Size Qualifiers를 사용
   - small, normal, large, xlarge
   - 비효율적이고 리소스 용량이 과도함
   - 다양한 화면 크기를 지원하는데 문제가 있음
  (3) Smallest-Width Qualifiers 사용
   - Android 3.2부터 지원
   - 화면의 너비에 해당하는 dp를 기준으로 Qualifiers 구분
  (4) Layout Aliases 사용
   - Android 3.2 미만의 버전을 지원하려면 Smallest-Width Qualifiers를 사용할 수 없기에 Single-Pane과 Multi-Pane을 구별하여 적용할 기준을 판단하는 방법으로 소스코드에서 레이아웃을 선택하는 방법을 사용해야 함
  (5) Orientation Qualifiers 사용
   - land, port
  (6) Nine-Patch Bitmap 사용
   - 다양한 화면에 맞게 가로, 세로 방향으로 확대되는 이미지는 효과적이다.

 2) 다양항 호면 밀도 호환 처리
  (1) DP(Density-independent Pixels)를 사용
  (2) 선택적인 Bitmap 사용
   - ldpi, mdpi, hdpi, xhdpi에 맞는 개별 Bitmap 사용
   - Nine-Patch Bitmap이 아닌 아이콘, 작은 크기의 다양한 모양을 갖는 이미지등에만 사용하길 권함.
  (3) 적응형 UI 구현
   - 화면 설정에 따라 소스코드에서 레이아웃 선택적 사용(방향, 화면너비 등)
   - Fragments를 사용하여 여러 Activity에서 재사용


6. TV를 위한 설계
 1) TV를 위한 Layout 최적화
  (1) 가로모드를 위한 설계
   - 네비게이션 컨트롤 등을 화면 좌/우에 배치하여 세로 화면을 최대한 확보
   - Fragments를 활용하고 ListView 보단 GridView를 잘 활용하면 가로화면을 효과적으로 활용할 수 있음
   - ViewGroup은 RelativeLayout과 LinearLayout을 활용하여 크기나 배치를 TV에 맞게 적용
   - 충분한 마진을 적용하여 어수선함을 피하라. 
  (2)문자와 컨트롤을 보기 쉽게 표시
   - 글자뒤에 배경 처리를 하여 보기 쉽게
   - 어두운 배경에 밝은색 글자를 사용
   - 얇고 가는 폰트 사용을 피하고 Anti-Aliasing을 적용하여 읽기 쉽게
   - 안드로이드 표준 폰트 크기를 사용
   - 3m 거리에서 충분히 볼 수 있는 크기를 사용
  (3) 고 밀도의 큰 화면을 위한 설계
   - 1080P에 맞추어 설계를 하고 그 이하의 화면은 축소 기능을 사용
   - 확대 기능은 품질이 저하되지만 축소 기능은 품질 저하가 거의 없음
   - 최적의 이미지 품질을 제공하려면 Nine-Patch를 사용
  (4) 큰 Bitmap 이미지를 처리하기 위한 설계
   - 이미지가 화면에 표시될때만 로드해야 함(AdapterView는 getView에 의해 처리될때만 이미지 로드)
   - Bitmap은 더 이상 사용할 필요가 없을때 recycle()호출
   - Bitmap을 메모리에 저장할때(Collection등에) WeekReference 사용
   - 이미지를 네트워크로 다운로드하는 경우 AsyncTask를 사용하여 다운로드하며 빠른 접근을 위해 SD Card에 캐싱한다.
   - 안드로이드는 메모리 제약으로 고해상도 이미지를 처리할때 Out of Memory가 발생할 수 있기에 큰 이미지 파일을 Bitmap으로 디코딩할때 축소 기능을 사용해야 함

(BitmapFactory.Options의 inJustDecodeBounds 옵션으로 헤더만 디코딩하여 이미지 크기 정보를 얻어 온 후 단말의 해상도를 기준으로 축소 여부를 판단)

 2) TV를 위한 네비게이션 최적화
  - TV는 터치스크린이 없기에 이외 다른 방식으로 조작한다는 것을 고려해야함.
  (1) D-pad 네비게이션 지원
   - D-pad로 모든 뷰에 접근이 가능해야 함
   - Up/Down Key로 스크롤링이 되어야 하고 Enter Key로 선택 되어야 함 
   - 컨트롤간 이동은 직관적이고 예측 가능해야 함
   - View의 nextFocusDown, nextFocusUp, nextFocusRight, nextFocusLeft의 속성을 활용

  (2) 포커스된 뷰나 선택된 뷰에 대해 시각적인 표현이 명확해야 함
   - drawable의 states를 활용
  (3) 쉬운 네비게이션을 위한 설계
   - 두세번의 클릭으로 네비게이션이 가능하고 동작에 대한 예측이 가능해야 함
   - 필요하다면 설명기능을 넣음
  (4) TV에서 지원하지 않는 특징에 대한 처리
   - Camera, GPS, Microphone, NFC, Telephony, Touchscreen 등이 없을 수 있기에 제약사항을 제거하거나 소스코드에서 사용가능 여부를 체크하여 처리하게 하여야 함.
   - 제약사항 제거는 AndroidManifest.xml에 <uses-feature>태그로 android:required 속성을 false로 처리
   - 소스코드에서 사용가능 여부를 체크할 때는 PackageManager의 hasSystemFeature() 함수를 사용


7. 사용자 정의 뷰 만들기
 1) 사용자 정의 뷰 클래스 만들기
  (1) 잘만들어진 사용자 뷰는 캡슐화되고 인터페이스 사용이 쉽고 시스템 리소스(CPU, Memory 등)를 효과적으로 사용하며 다음과 같은 기능을 제공해야 한다.
   - 안드로이드 표준 디바이스에서 안정되게 동작한다.
   - XML Layout에서 사용할 수 있는 속성값을 제공한다.
   - Event 처리가 쉽다.
   - 다양한 안드로이드 디바이스를 지원한다.

  (2) Subclass View
   - View를 상속받던지 View의 Subclass를 상속받아 구현해야 함.
   - 최소한 Context와 AttributeSet 인자를 갖는 생성자를 제공해야 함.

  (3) 사용자 정의 속성 정의
   - attrs.xml의 <resources> 요소에 <declare-styleable>로 사용자 정의 속성을 정의한다.
   - 속성은 enum을 포함해 다양한 타입을 지원

  (4) 사용자 정의 속성 구현
   - 사용자 정의 뷰를 사용하는 Layout XML에 네임스페이스를 선언한다.
   - AttributeSet 인자를 갖는 View 생성자 구현하여 Layout XML에서 지정한 속성값을 얻게 함

  (5) 사용자 정의 속성에 대응하는 함수 구현
   - 소스코드에서도 동일한 동작을 수행할 수 있게 함수 제공.

  (6) 접근성 향상을 위한 설계
   - 시각장애자를 위해 android:contentDescription으로 설명 문구 적용
   - AccessibilityEvent를 전달
   - D-pad, Trackball, bluetooth keyboard, mouse 등 Touchscreen 이외 컨트롤러 지원

 2) 사용자 정의 Drawing 구현
  (1) onDraw() 함수 overriding
   - 인자로 전달받는 Canvas 객체로 글자쓰기, 라인 그리기, 도형 그리기 등 가능
   - 그리기 전에 Paint 객체를 만들어야 하며 onDraw 함수 내에서 Paint를 생성하지 말하야 함
  (2) Layout 이벤트 처리
   - 그리고자 하는 영역의 크기를 구하려면 onSizeChanged() 함수를 overriding하여 구함.
   - 자신의 부모 뷰에게서 자신이 그리기 위해 필요한 최소한의 크기를 확보하고자 한다면 onMessure() 함수를 overriding 하면 됨.

  (3) 그리기
   - 그리기위한 다양한 함수 제공

 3) 대화형 뷰 만들기
  (1) 입력된 제스처 처리
   - 터치 이벤트를 처리할땐 onTouchEvent()함수를 overriding 한다.
   - 탭핑, 풀링, 푸쉬, 플리핑, 줌 등 일반적인 제스처를 처리할땐 GestureDetector를 사용한다.
  (2) 부드러운 화면 이동
   - 뷰를 직업이동하면서 이동하는 모습을 처리하면 버벅임
   - 애니메이션으로 이동되는 모습을 표현하고 애니메이션이 끝날때 뷰를 한번에 이동시키면 순간 깜빡임이 발생할 수도 있고 조금 까다로운 처리를 요함
   - Android 3.0 버전 부터는 ValueAnimator를 이용하면 부드럽게 애니메이션이 동작하면서 뷰가 실제 이동됨.

 4) 뷰 최적화
  - 초당 60 프레임을 부드럽게 처리할 수 있게 뷰를 만들어야 한다.
  (1) 빈번히 호출되는 부분에 불필요한 코드를 줄인다.
   - onDraw 함수는 매우 빈번히 불리며 불필요하게 invalidate()함수를 호출하지 말아야한다.
   - requestLayout()은 필요로 하는 크기를 계산하기 위해 뷰 계층 전체에 대해 계산한다.
   - ViewGroup을 상속받은 사용자 정의 뷰를 구현하였다면 자식 뷰들에 대해 계산을 하게하는 방식을 사용하지 않아야 한다.
  (2) 하드웨어 가속기능을 사용
   - Android 3.0 부터 GPU에 의해 2D 그래픽에 대한 하드웨어 가속기능을 지원함.
   - Application, Activity, Window 레벨에서 하드웨어 가속기능 사용여부를 설정할 수 있음.


8. 하위 버전에 대한 호환성 처리


9. 접근성 향상







Qualifiers 설정 참고 URL
http://developer.android.com/guide/practices/screens_support.html#qualifiers


Notification 참고 URL
http://developer.android.com/design/patterns/notifications.html

접근성 향상 참고 URL
http://developer.android.com/guide/topics/ui/accessibility/index.html

사용자 정의 뷰 만들기 참고 URL
http://developer.android.com/training/custom-views/create-view.html


하드웨어가속 참고 URL
http://developer.android.com/guide/topics/graphics/hardware-accel.html


2013년 2월 13일 수요일

android - performance tips

1. 불필요한 객체 생성을 피해라.
- 객체를 새로 생성해서 사용하는것 보다 이미 생성된 객체의 데이터를 초기화 후 재사용 하는 형태의 사용을 권장.

2. 필드에 접근할 필요가 없다면 static 메소드로 구현해라.
- 일반 메소드 접근보다 static 메소드 접근이 빠름.

3. 상수는 static final로 정의해라.

4. 클래스 내부에서 필드에 접근은 getter/setter 형태가 아닌 직접 접근방식으로
- JIT를 지원하지 않으면 소드로 접근이 직접 필드 접근의 3배 비용이 소요된다.

5. JDK1.5에 추가된 enhanced for loop syntax를 사용해라.
- JIT를 지원하지 않으면 가장 빠른 루프처리 이며 JIT를 지원해도 일반 for 루프와 동등함.

6. private inner class 사용을 피해라.

7. floating-point 사용을 피해라.
- float는 integer보다 2배 느리며 double과는 속도 차이가 없다.

8. 직접구현보단 라이브러리 코드를 사용해라.

9. interface로 접근보단 구현 class로 접근하여 사용해라.
- JIT를 지원하지 않으면 2배가랑 속도차이 있을 수 있다.

10. 테스트/최적화 툴을 잘 활용해라.



참고 URL
http://developer.android.com/training/articles/perf-tips.html

android - systrace

멀티쓰레딩 환경에서 타 어플과의 상호 간섭/병목 등에 의해 발생할 수 있는 문제를 찾고 성능을 향상시키고자 할 때 사용


Android 4.1 이상에서만 사용가능


Eclipse Android ADT Plug-In의 Devices 우측 상단의 "Capture system wide trace using android trace" 버튼을 클릭하면,
"Android System Trace: 다이얼로그가 표시됨.
Trace 하고자 하는 항목을 선택 후 "OK" 버튼 클릭.


html기반의 레포팅을 제공하며 긴 시간 실행되는 프로세스(처리 지연등)나  화면 처리 지연등을 파악할 수 있다.


참고 URL
http://developer.android.com/tools/debugging/systrace.html

android - traceview

디버깅과 프로파일링을 위한 툴

- 에물레이터로 실행시 SD Card를 생성해야 함
- Android 1.5는 미지원
- Android 2.1 이하 버전은 SD Card 쓰기 권한 필요
- Android 2.2 이상은 SD Card가 없어도 됨


1. 메소드 프로파일링 코드 추가

어플의 시작부에 Debug.startMethodTracing("파일명"); 추가
어플의 종료부에 Debug.stopMethodTracing(); 추가

2. 실행 및 구현 기능 동작 테스트

3. 생성된 trace 파일 복사

"파일명".trace를 PC에 복사

4. 프로파일링
traceview "파일명"

.
.
.

traceview는 deprecated되었고 monitor 사용을 권장함.
deprecated된 이유는 Thread 이름을 제데로 가져오지 못하는 것과 Thread의 종료와 생성이 반복될때 Thread ID를 재 사용하여 Thread를 구분할 수 없는 문제가 있어서 인 것 같음.


그리고 위 절차가 필요없이(소스코드 수정도 필요없음) Eclipse의 Android ADT Plug-In에 포함된 Devices 뷰를 사용해 쉽게 메소드 프로파일링이 가능함.

Devices 뷰에서 프로파일링 하고자 하는 프로세스를 선택 후 우측 상단의 "Start Method Profiling" 버튼 클릭 후 어플리케이션에 구현된 모든 기능을 동작시킨 후 "Stop Method Profiling" 로 바뀐 버튼을 클릭하면 Timeline Panel과 Profile Panel을 볼 수 있음.

.
.
.

결론은,
안쓰는게 좋겠다.


참고 URL
http://developer.android.com/tools/debugging/debugging-tracing.html



2013년 2월 12일 화요일

android - lint

Lint

잠재적인 버그를 잡아주고 최적화를 위한 도움을 줌.

1. 콘솔에서 사용하기
link --check [체크 리스트] [프로젝트 홈 디렉토리]

2. eclipse ADT plugin에 포함됨


참고 URL
http://developer.android.com/tools/debugging/improving-w-lint.html


android - disassembler / decompile

1. dex 파일 추출하기

 1) apktool을 이용하여 추출
  - 다운로드 : https://code.google.com/p/android-apktool/downloads/list

 2) zip 호환 압축툴을 이용하여 추출
  - apk를 압축파일처럼 읽어들여 압축해제하면됨

2. 디컴파일
 1) java decomiler 사용
  (1) dex파일로 jar 추출
   - dex2jar툴을 이용하여 추출
   - 사용법 : d2j-dex2jar [dex 파일명]
   - 다운로드 : https://code.google.com/p/dex2jar/downloads/list

  (2) java decompiler로 java 소스 추출
   - GUI 툴
   - 다운로드 : http://java.decompiler.free.fr/?q=jdgui

 2) dedexer 사용
  - 사용법 : java -jar ddx.jar -d [역어셈블된 코드 저장 경로] [dex 파일명]
  - 다운로드 : http://sourceforge.net/projects/dedexer/?source=directory













android - monkey

android monkey

단말에 랜덤한 이벤트를 발생시켜 안정성 테스트를 할 수 있음.

adb shell monkey -p [패키지 이름] -v [테스트 횟수]


android - 위젯 가로, 세로 크기

위젯은 가로, 세로 방향에 다른 크기를 갖는다.
따라서 방향에 따른 별도의 레이아웃 처리가 필요하다.

가로

세로

windows - 에러코드


8567: Windows 버전이 도메인 또는 포리스트의 동작 버전과 호환되지 않습니다
8568: 요청된 값보다 버전이 낮은 도메인 컨트롤로가 아직 있기 때문에 동작 버전을 요청된 값으로 높일 수 없습니다
8569: 도메인이 혼합 도메인 모드일 때는 동작 버전 값을 증가시킬 수 없습니다. 동작 버전을 증가시키기 전에 도메인을 원래 모드로 변경해야 합니다
8570: 요청한 정렬 순서가 지원되지 않습니다
8571: 이름이 고유하지 않은 개체가 있습니다
8572: 컴퓨터 계정을 NT4 이전에 만들었습니다. 계정을 다시 만들어야 합니다
8573: 데이터베이스가 버전이 오래된 저장소입니다
8574: 여러 개의 충돌하는 컨트롤을 사용했기 때문에 작업을 계속할 수 없습니다
8575: 이 파티션에 대해 유효한 보안 설명자 참조를 찾을 수 없습니다
8576: 스키마 업데이트 실패: 링크 식별자가 예약되어 있습니다
8577: 스키마 업데이트 실패: 사용할 수 있는 링크 식별자가 없습니다
8578: 계정 그룹은 유니버설 그룹을 구성원으로 가질 수 없습니다
8579: 명명 컨텍스트 머리글이나 읽기 전용 개체에서는 이름 변경 또는 이동 작업을 수행할 수 없습니다
8580: 스키마 명명 컨텍스트에 있는 개체에서는 이동 작업을 수행할 수 없습니다
8581: 개체에 시스템 플래그가 설정되었으며 개체를 이동하거나 이름 변경할 수 없습니다
8582: 이 개체는 최상위 컨테이너를 바꿀 수 없습니다. 이 개체에서 이동이 금지되어 있지는 않지만 형제 컨테이너로 제한됩니다
8583: 완전히 확인할 수 없기 때문에 다른 포리스트에 대한 조회가 생성되었습니다
8584: 요청된 동작이 표준 서버에서 지원되지 않습니다
8585: 원격 서버에 있는 Active Directory의 파티션에 액세스할 수 없습니다. 파티션에 대해 최소한 하나의 서버가 실행 중인지 확인하십시오
8587: 이 요청의 스레드 한도를 초과했습니다
8588: 글로벌 카탈로그 서버가 가까운 사이트에 없습니다
8589: 로컬 DS 데이터베이스에 있는 대응하는 서버 개체에 serverReference 특성이 없기 때문에 DS에서 대상 서버를 상호 인증하는 서비스 사용자 이름(SPN)을 만들 수 없습니다
8590: 디렉터리 서비스가 단일 사용자 모드로 들어가지 못했습니다
8591: 구문 오류 때문에 디렉터리 서비스가 스크립트의 구문을 분석할 수 없습니다
8592: 오류 때문에 디렉터리 서비스가 스크립트를 처리할 수 없습니다
8593: 포함된 서버가 서로 다른 복제 epoch(일반적으로 이름 변경
중인 도메인에 연결됨)이기 때문에 디렉터리 서비스에서 요청된
작업을 수행할 수 없습니다
8594: 서버 확장 정보가 변경되었기 때문에 디렉터리 서비스 바인딩을
재협상해야 합니다
8595: 사용할 수 없는 상호 참조에서는 허용되지 않는 작업입니다
8596: 스키마 업데이트 실패: msDS-IntId에 사용할 수 있는 값이 없습니다
8597: 스키마 업데이트 실패: 중복된 msDS-INtId입니다. 작업을 다시 시도하십시오
8598: 스키마 삭제 실패: 특성이 rDNAttID에서 사용됩니다
8599: 디렉터리 서비스가 요청을 인증하지 못했습니다
8600: 스크립트가 올바르지 않기 때문에 디렉터리 서비스에서 처리할 수 없습니다
8601: 도메인 명명 마스터 FSMO에서 상호 참조 원격 생성 작업에 실패했습니다. 작업 오류는 확장된 데이터에 있습니다
9001: DNS 서버가 형식을 해석할 수 없습니다
9002: DNS 서버 오류입니다
9003: DNS 이름이 없습니다
9004: 이름 서버가 DNS 요청을 지원하지 않습니다
9005: DNS 작업을 거부했습니다
9006: 필요 없는 DNS 이름이 있습니다
9007: 필요 없는 DNS RR 세트가 있습니다
9008: 필요한 DNS RR 세트가 없습니다
9009: DNS 서버가 영역에 대한 권한이 없습니다
9010: 업데이트 또는 필요 조건의 DNS 이름이 영역에 없습니다
9016: DNS 서명을 확인하지 못했습니다
9017: 잘못된 DNS 키입니다
9018: DNS 서명의 유효 기간이 만료되었습니다
9501: 주어진 DNS 쿼리에 해당하는 레코드가 없습니다
9502: 잘못된 DNS 패킷입니다
9503: DNS 패킷이 없습니다
9504: DNS 오류입니다. rcode를 확인하십시오
9505: 보안되지 않은 DNS 패킷입니다
9551: 잘못된 DNS 형식입니다
9552: 잘못된 IP 주소입니다
9553: 잘못된 속성입니다
9554: 나중에 DNS 작업을 다시 시도하십시오
9555: 주어진 이름에 대한 레코드 및 형식이 고유하지 않습니다
9556: DNS 이름이 RFC 사양을 따르지 않았습니다
9557: DNS 이름은 정확히 지정된 DNS 이름입니다
9558: DNS 이름이 점으로 나누어져 있습니다(복수-이름)
9559: DNS 이름이 단일로 구성되었습니다
9560: DNS 이름에 올바르지 않은 문자가 있습니다
9561: DNS 이름에 숫자만 사용되었습니다
9562: 요청된 작업은 DNS 루트 서버에서 허용되지 않습니다
9601: DNS 영역이 없습니다
9602: DNS 영역 정보가 없습니다
9603: DNS 영역에 대해 잘못된 작업입니다
9604: 잘못된 DNS 영역 구성입니다
9605: DNS 영역에 Start of Authority (SOA) 레코드가 없습니다
9606: DNS 영역에 Name Server (NS) 레코드가 없습니다
9607: DNS 영역이 잠겼습니다
9608: DNS 영역을 만들지 못했습니다
9609: DNS 영역이 이미 있습니다
9610: DNS 자동 영역이 이미 있습니다
9611: 잘못된 DNS 영역 형식
9612: 보조 DNS 영역이 마스터 IP 주소가 필요합니다
9613: 보조가 아닌 DNS 영역입니다
9614: 보조 IP 주소가 필요합니다
9615: WINS 초기화를 실패했습니다
9616: WINS 서버가 필요합니다
9617: NBTSTAT 초기화 호출을 실패했습니다
9618: Start of Authority (SOA)를 잘못 삭제했습니다
9619: 이 이름에 대한 조건부 전달 구역이 이미 있습니다
9620: 이 영역은 하나 이상의 마스터 DNS 서버 IP 주소로 구성되어야 합니다
9621: 이 영역이 종료되었기 때문에 작업을 수행할 수 없습니다
9651: 주 DNS 영역에 데이터 파일이 필요합니다
9652: DNS 영역에 대해 잘못된 데이터 파일 이름입니다
9653: DNS 영역에 대한 데이터 파일 열기 실패입니다
9654: DNS 영역에 대한 데이터 파일 쓰기 실패입니다
9655: DNS 영역에 대한 데이터 파일을 읽는 동안 오류가 발생했습니다
9701: DNS 레코드가 없습니다
9702: DNS 레코드 형식 오류입니다
9703: DNS에서 노드 작성 오류가 발생했습니다
9704: 알 수 없는 DNS 레코드 종류입니다
9705: DNS 레코드 시간 초과입니다
9706: DNS 영역에 없는 이름입니다
9707: CNAME 루프를 감지했습니다
9708: CNAME DNS 레코드에 있는 노드입니다
9709: 해당 이름의 CNAME 레코드가 이미 있습니다
9710: DNS 영역 루트에만 있는 레코드입니다
9711: DNS 레코드가 이미 있습니다
9712: 보조 DNS 영역 데이터 오류입니다
9713: DNS 캐시 데이터를 만들지 못했습니다
9714: DNS 이름이 없습니다
9715: 포인터(PTR) 레코드를 만들지 못했습니다
9716: DNS 도메인을 삭제하지 않았습니다
9717: 디렉터리 서비스를 사용할 수 없습니다
9718: DNS 영역이 디렉터리 서비스에 이미 있습니다
9719: DNS 서버가 디렉터리 서비스에 혼합된 DNS 영역에 대한 부팅 파일을 만들거나 읽지 않습니다
9751: DNS AXFR(영역 전송)을 완료했습니다
9752: DNS 영역 전송을 실패했습니다
9753: 추가된 로컬 WINS 서버입니다
9801: 안전한 업데이트 호출에서는 업데이트 요청을 계속해야 합니다
9851: TCP/IP 네트워크 프로토콜이 설치되지 않았습니다
9852: 로컬 시스템에 대한 DNS 서버가 구성되지 않았습니다
9901: 지정된 디렉터리 파티션이 없습니다
9902: 지정된 디렉터리 파티션이 이미 있습니다
9903: DS가 지정된 디렉터리 파티션에 참여하고 있지 않습니다
9904: DS가 이미 지정된 디렉터리 파티션에 참여하고 있습니다
10004: WSACancelBlockingCall를 호출하여 차단 작업이 중단되었습니다
10009: 잘못된 파일 핸들입니다
10013: 액세스 권한에 의해 숨겨진 소켓에 액세스를 시도했습니다
10014: 호출에 대한 포인터 인수를 사용하려는 동안 시스템에서 잘못된 포인터 주소를 감지했습니다
10022: 잘못된 인수를 입력했습니다
10024: 열려진 소켓이 너무 많습니다
10035: 비동기 소켓 작업을 즉시 완료하지 못했습니다
10036: 중단 작업이 진행 중입니다
10037: 이미 작업이 진행 중인 비동기 소켓에 작업을 시도했습니다
10038: 소켓 이외의 개체에 작업을 시도했습니다
10039: 소켓의 해당 작업에서 필요한 주소가 생략되었습니다
10040: 데이터그램 소켓으로 보낸 메시지가 내부 메시지 버퍼 또는 다른 네트워크 제한보다 큽니다. 또는 데이터 그램을 수신한 버퍼가 데이터그램보다 작습니다
10041: 소켓 함수 호출에서 설정된 프로토콜이 해당 소켓 종류를 지원하지 않습니다
10042: 지원되지 않거나 잘못된 옵션이나 레벨이 getsockopt()이나 setsockopt()에서 지정되었습니다
10043: 요청된 프로토콜이 시스템 내에서 설정되지 않았거나 지원되지 않습니다
10044: 해당 주소에서는 지정된 소켓에 대한 지원을 하지 않습니다
10045: 관련된 개체 종류에 대한 해당 작업은 지원되지 않습니다
10046: 해당 프로토콜이 시스템 내에서 설정되지 않았거나 지원되지 않습니다
10047: 해당 프로토콜과 호환되지 않는 주소가 사용되었습니다
10048: 각 소켓 주소(프로토콜/네트워크 주소/포트)는 하나만 사용할 수 있습니다
10049: 요청한 주소는 해당 컨텍스트에서 유효하지 않습니다
10050: 네트워크를 사용할 수 없기 때문에 소켓 작업을 진행할 수 없습니다
10051: 연결할 수 없는 네트워크에서 소켓 작업을 시도했습니다
10052: 해당 작업이 진행되는 동안 오류가 발생하여 연결이 끊겼습니다
10053: 현재 연결은 사용자의 호스트 시스템의 소프트웨어의 의해 중단되었습니다
10054: 현재 연결은 원격 호스트에 의해 강제로 끊겼습니다
10055: 대기열이 또는 버퍼가 부족하여 소켓에서 해당 작업을 진행하지 못했습니다
10056: 이미 연결된 소켓에서 다른 연결을 요청했습니다
10057: 소켓이 연결되어 있지 않거나 Sendto 호출을 사용하여 데이터그램 소켓에 보내는 경우에 주소가 제공되지 않아서 데이터를 보내거나 받도록 요청할 수 없습니다
10058: 해당 소켓이 종료되었으므로 데이터 보내거나 받을 수 없습니다
10059: 일부 커널 개체에 대한 참조가 너무 많습니다
10060: 연결된 구성원으로부터 응답이 없어 연결하지 못했거나, 호스트로부터 응답이 없어 연결이 끊어졌습니다
10061: 대상 컴퓨터에서 연결을 거부했으므로 연결하지 못했습니다
10062: 이름을 해석할 수 없습니다
10063: 이름 또는 이름의 구성 요소가 너무 깁니다
10064: 호스트가 작동하지 않기 때문에 소켓 작업을 진행할 수 없습니다
10065: 연결할 수 없는 호스트로 소켓 작업을 시도했습니다
10066: 비어있지 않은 디렉터리는 제거할 수 없습니다
10067: Windows 소켓 구현에는 동시에 사용할 수 있는 응용 프로그램의 개수 제한이 있습니다
10068: 할당량을 초과했습니다
10069: 디스크 할당량을 초과했습니다
10070: 파일 핸들 참조를 더 이상 사용할 수 없습니다
10071: 해당 항목을 로컬에서 사용할 수 없습니다
10091: 네트워크 서비스를 제공하기 위해 원본으로 사용하는 시스템을 현재 사용할 수 없으므로 WSAStartup 기능을 실행할 수 없습니다
10092: 해당 Windows 소켓 버전은 지원되지 않습니다
10093: 응용 프로그램에서 WSAStartup을 호출하지 않았거나 WSAStartup에 실패했습니다
10101: 시스템 종료 시퀀스로 초기화된 원격 구성원을 나타내기 위해 WSARecv와 WSARecvFrom에 의해 반환되었습니다
10102: WSALookupServiceNext에서는 더 이상의 결과를 나타낼 수 없습니다
10103: 해당 호출이 처리되는 동안 WSALookupServiceEnd을 호출했습니다. 호출이 취소되었습니다
10104: 잘못된 프로시저 호출 테이블입니다
10105: 잘못된 서비스 공급자입니다
10106: 서비스 공급자를 로드하거나 초기화할 수 없습니다
10107: 시스템 호출을 실패했습니다
10108: 해당 서비스를 사용할 수 없습니다. 지정된 이름 영역에서 서비스를 찾을 수 없습니다
10109: 지정한 클래스를 찾을 수 없습니다
10110: WSALookupServiceNext에서는 더 이상의 결과를 나타낼 수 없습니다
10111: 해당 호출이 처리되는 동안 WSALookupServiceEnd을 호출했습니다. 호출이 취소되었습니다
10112: 데이터베이스 쿼리가 거부되었으므로 진행할 수 없습니다
11001: 알려진 호스트가 없습니다
11002: 호스트 이름을 확인하는 동안 로컬 서버가 신뢰할 만한 서버에서 응답을 받지 못해 발생한 일시적인 오류입니다
11003: 데이터베이스를 검색하는 동안 복구할 수 없는 오류가 발생했습니다
11004: 요청된 이름이 유효하고 데이터베이스에 있지만 올바른 관련 데이터를 가지고 있지는 않습니다
11005: 최소한 하나의 예약이 도착했습니다
11006: 최소한 하나의 경로가 도착했습니다
11007: 보내는 개체가 없습니다
11008: 받는 개체가 없습니다
11009: 예약이 확인되었습니다
11010: 리소스가 부족하여 오류가 발생했습니다
11011: 관리상의 이유로 거부되었습니다. 잘못된 자격 증명입니다
11012: 알 수 없거나 충돌하는 스타일입니다
11013: filterspec 또는 providerspecific 버퍼에 문제가 있습니다
11014: flowspec의 일부에서 오류가 발생했습니다
11015: 일반 QOS 오류입니다
11016: flowspec에 올바르지 않거나 알 수 없는 서비스 형식이 있습니다
11017: QOS 구조에 올바르지 않거나 일치하지 않는 flowspec이 있습니다
11018: 올바르지 않은 QOS 공급자 지정 버퍼입니다
11019: 올바르지 않은 QOS 필터 스타일이 사용되었습니다
11020: 올바르지 않은 QOS 필터 형식이 사용되었습니다
11021: FLOWDESCRIPTOR에 올바르지 않은 QOS FILTERSPEC 개수가 지정되었습니다
11022: QOS 공급자 지정 버퍼에 올바르지 않은 ObjectLength 필드를 갖는 개체가 지정되었습니다
11023: QOS 구조에 올바르지 않은 개수의 플로 설명자가 지정되었습니다
11024: QOS 공급자 특정 버퍼에 알 수 없는 개체가 있습니다
11025: QOS 공급자 특정 버퍼에 올바르지 않은 정책 개체가 있습니다
11026: 플로 설명자 목록에 올바르지 않은 QOS 플로 설명자가 있습니다
11027: QOS 공급자 고유 버퍼에 올바르지 않거나 일관적이지 않은 flowspec이 있습니다
11028: QOS 공급자 특정 버퍼에 올바르지 않는 FILTERSPEC이 있습니다
11029: QOS 공급자 특정 버퍼에 올바르지 않은 모양 제거 모드 개체가 있습니다
11030: QOS 공급자 특정 버퍼에 올바르지 않은 모양 개체가 있습니다
11031: QOS 공급자 특정 버퍼에 이미 지정된 정책 요소가 있습니다

android - px를 dp(dip) 적용법


안드로이드 단말은 다양한 해상도와 밀도를 조합해서 사용합니다.
모든 단말들에 대해 효과적으로 화면을 호환시키려면 중간 크기의 단말로 기준을 잡고 디자인을 하고 이에 맞는 단위 변환 작업을 통해 코드를 적용하는 작업이 필요합니다.

디자인 가이드는 통상 px을 단위로 사용합니다.
요즘 스마트폰의 경우 ldpi, mdpi, hdpi, xhdpi 등을 사용하는데 xhdpi가 나오기 전에는 mdpi를 기준으로 디자인 하였으나 요즘은 hdpi를 기준으로 디자인하는 것이 좋을듯 합니다.
hdpi를 기준으로 디자인 되었다면,
디자인된 이미지는 res/drawable-hdpi에 위치하면 단말의 density에 맞추어 알아서 맞추어 표시됩니다.
이외 지정된 크기는 아래와 같은 계산으로 dp를 구한 후 dp로 지정하여 사용하면 됩니다.

dp(dip) = px * density

density는 android.util.DisplayMetrics의 density 필드 값으로 hdpi를 기준으로 디자인 되었다면 1.5가 됨.
px = pixel
dip = density independent pixel


참고사항)
위와 같이 작업을 해도 화면의 가로 세로 비율 등으로 인해 화면 전체에 맞추어 표시되지 않을 수 있습니다.
이는 디자인의 기준이되는 단말보다 넓은 dp를 갖는 단말들이 존재하기 때문입니다.
(xhdpi는 360dp, 갤럭시 노트1이나 갤럭시 탭7은 400dp)

이경우는 남는 추가된 영역에 대해 어떤 방식으로 사용할지 결정하여 적용해야 합니다.
화면의 좌/우 여백으로 사용할 수도 있고 N 비율로 구성된 뷰의 크기를 늘릴 수도 있습니다.

google - maps api

MD5 key
keytool -list -v -keystore [keystore 파일명]

maps api sign URL https://developers.google.com/maps/documentation/android/v1/maps-api-signup