Android Studio Development Essentials: Android 7 Edition Copyright c 2016 Neil Smyth. All rights reserved. Korean Translation Copyright c 2017 by J-Pu

Save this PDF as:
 WORD  PNG  TXT  JPG

Size: px
Start display at page:

Download "Android Studio Development Essentials: Android 7 Edition Copyright c 2016 Neil Smyth. All rights reserved. Korean Translation Copyright c 2017 by J-Pu"

Transcription

1

2 Android Studio Development Essentials: Android 7 Edition Copyright c 2016 Neil Smyth. All rights reserved. Korean Translation Copyright c 2017 by J-Pub. co. The Korean edition is published by arrangement with Neil Smyth through Agency-One, Seoul. 이책의한국어판저작권은에이전시원을통해저작권자와의독점계약으로제이펍출판사에있습니다. 신저작권법에의해한국내에서보호를받는저작물이므로무단전재와무단복제를금합니다. 1쇄발행 2017년 8월 11일지은이닐스미스옮긴이심재철펴낸이장성두펴낸곳제이펍출판신고 2009년 11월 10일제 호주소경기도파주시회동길 159 3층 3-B호전화 / 팩스 홈페이지 / 원고투고 독자문의 / 교재문의 편집부이민숙, 황혜나, 이슬, 이주원 / 소통 기획팀민지환, 현지환 / 회계팀김유미교정 교열장성두 / 본문디자인이민숙 / 표지디자인미디어픽스용지신승지류유통 / 인쇄해외정판사 / 제본광우제책사 ISBN (93000) 값 37,000원 이책은저작권법에따라보호를받는저작물이므로무단전재와무단복제를금지하며, 이책내용의전부또는일부를이용하려면반드시저작권자와제이펍의서면동의를받아야합니다. 잘못된책은구입하신서점에서바꾸어드립니다. 제이펍은독자여러분의아이디어와원고투고를기다리고있습니다. 책으로펴내고자하는아이디어나원고가있으신분께서는책의간단한개요와차례, 구성과저 ( 역 ) 자약력등을메일로보내주세요.

3

4 드리는말씀 이책은 핵심만골라배우는안드로이드스튜디오 & 프로그래밍 의최신개정판입니다. 이책에기재된내용을기반으로한운용결과에대해저 / 역자, 소프트웨어개발자및제공자, 제이펍출판사는일체의책임을지지 않으므로양해바랍니다. 이책에기재한회사명및제품명은각회사의상표및등록명입니다. 이책에서는 TM, C, R 등의기호를생략하고있습니다. 이책에서사용하고있는실제제품버전은독자의학습시점에따라책의버전과다를수있습니다. 이책의원서는안드로이드스튜디오 2.3 과안드로이드 7( 누가 ) 버전으로작성되었습니다만, 번역서는안드로이드스튜디오 3.0 Canary 8 과안드로이드 8.0 버전에맞춰업데이트하여출간합니다. 제이펍의다른책들과는달리이책은빠른출간을위해베타리딩을진행하지않고출간합니다. 이책에나오는안드로이드스튜디오예제프로젝트파일과역자가집필한특별부록 Kotlin( 코틀린 ) 핵심파악하기 (PDF) 는다음의사 이트에서다운로드할수있습니다. - 책의내용과관련된문의사항은옮긴이나출판사로연락주시기바랍니다. - 옮긴이 : - 출판사 :

5 차례 xxvi CHAPTER 1 CHAPTER 2 CHAPTER 3 개요 _ 안드로이드스튜디오의장점 소스코드다운로드하기 단축키와코드표기 안드로이드스튜디오최신버전사용하기 독자 A/S 오탈자 5 안드로이드스튜디오개발환경구성하기 _ 개발시스템요구사항 자바 JDK 설치하기 리눅스에서설치하기 안드로이드스튜디오패키지다운로드하기 안드로이드스튜디오설치하기 안드로이드스튜디오설정위저드 가장최신버전의안드로이드 SDK 패키지설치하기 명령행에서안드로이드 SDK 도구사용하기 안드로이드스튜디오와 SDK 버전업그레이드하기 안드로이드 SDK와 NDK 및자바 JDK 경로변경하기 요약 27 안드로이드스튜디오로첫번째애플리케이션만들기 _ 새로운안드로이드프로젝트생성하기 프로젝트와 SDK 설정정의하기 액티비티생성하기 애플리케이션변경하기 레이아웃과리소스파일살펴보기 요약 45 차례 v

6 CHAPTER 4 CHAPTER 5 CHAPTER 6 CHAPTER 7 안드로이드스튜디오 UI 둘러보기 _ 웰컴스크린 메인창 도구창 안드로이드스튜디오의단축키 스위처와최근파일기능을이용한내비게이션 안드로이드스튜디오테마변경하기 요약 57 안드로이드스튜디오에서 AVD 생성하기 _ AVD 개요 새로운 AVD 생성하기 에뮬레이터시작하기 AVD에서애플리케이션실행하기 Run/Debug 구성 실행중인애플리케이션중단시키기 명령행에서 AVD 조회하기 AVD 구성파일들 AVD의위치이동과이름변경 Intel HAXM 사용으로에뮬레이터성능향상시키기 요약 74 안드로이드스튜디오 AVD 에뮬레이터사용과구성하기 _ 에뮬레이터환경 에뮬레이터툴바 줌모드사용하기 에뮬레이터창의크기조정 확장제어옵션 드래그 -드롭 모의지문구성하기 멀티코어지원 요약 85 실제안드로이드장치에서애플리케이션테스트하기 _ ADB 개요 안드로이드장치에서 ADB 활성화하기 adb 연결테스트하기 안드로이드스튜디오에서장치확인하기 요약 97 vi 차례

7 CHAPTER 8 CHAPTER 9 CHAPTER 10 CHAPTER 11 안드로이드스튜디오코드편집기 _ 안드로이드스튜디오코드편집기 편집기창나누기 코드자동완성 문장자동완성 매개변수정보 코드생성 코드접어감추기 빠른문서검색 소스코드형식변환 샘플코드찾아보기 요약 110 안드로이드아키텍처개요 _ 안드로이드소프트웨어스택 리눅스커널 안드로이드런타임 ART 안드로이드라이브러리 애플리케이션프레임워크 애플리케이션 요약 116 액티비티와인텐트개요 _ 안드로이드액티비티 안드로이드인텐트 브로드캐스트인텐트 브로드캐스트수신자 안드로이드서비스 콘텐트제공자 애플리케이션매니페스트 애플리케이션리소스 애플리케이션컨텍스트 요약 121 안드로이드애플리케이션과액티비티생명주기 _ 안드로이드애플리케이션과리소스관리 안드로이드프로세스상태 액티비티생명주기 액티비티스택 액티비티상태 구성변경 요약 127 차례 vii

8 CHAPTER 12 CHAPTER 13 CHAPTER 14 CHAPTER 15 CHAPTER 16 액티비티상태변화처리하기 _ Activity 클래스 동적상태 vs. 영속적상태 안드로이드액티비티생명주기메서드 액티비티생애 액티비티가다시시작되지않게하기 요약 137 액티비티상태변화예제 _ 상태변화예제프로젝트생성하기 사용자인터페이스디자인하기 액티비티생명주기메서드오버라이딩 로그캣패널의메시지필터링하기 애플리케이션실행하기 액티비티로실험하기 요약 149 액티비티상태를저장하고복원하기 _ 동적상태저장 사용자인터페이스상태의자동저장과복원 Bundle 클래스 상태데이터저장하기 상태데이터복원하기 애플리케이션테스트하기 요약 156 안드로이드뷰, 뷰그룹, 레이아웃 _ 서로다른안드로이드장치를위한디자인 뷰와뷰그룹 안드로이드레이아웃매니저 뷰계층구조 사용자인터페이스생성 요약 163 안드로이드스튜디오레이아웃편집기살펴보기 _ Basic vs. Empty 액티비티템플릿 안드로이드스튜디오레이아웃편집기 디자인모드 팔레트 레이아웃의확대 / 축소보기 디자인뷰와청사진뷰 텍스트모드 171 viii 차례

9 16.8 속성설정하기 즐겨사용하는속성구성하기 커스텀장치정의생성하기 현재장치변경하기 요약 176 CHAPTER 17 CHAPTER 18 CHAPTER 19 안드로이드 ConstraintLayout 개요 _ ConstraintLayout 의핵심요소 기준선정렬 지시선사용하기 위젯크기구성하기 비율 ConstraintLayout 의장점 ConstraintLayout 의가용성 요약 184 안드로이드스튜디오에서 ConstraintLayout 사용하기 _ 디자인뷰와레이아웃뷰 자동연결 제약추론 수동연결 제약삭제하기 제약바이어스조정하기 ConstraintLayout 마진이해하기 상대제약과바이어스의중요성 위젯의크기구성하기 지시선추가하기 위젯의그룹정렬 다른타입의레이아웃을 ConstraintLayout 으로변환하기 요약 198 안드로이드스튜디오에서 ConstraintLayout 체인과비율사용하기 _ 체인생성하기 체인스타일변경하기 Spread inside 체인스타일 Packed 체인스타일 바이어스를사용한 Packed 체인스타일 Weighted 체인 비율사용하기 요약 208 차례 ix

10 CHAPTER 20 CHAPTER 21 CHAPTER 22 CHAPTER 23 CHAPTER 24 ConstraintLayout 예제프로젝트 _ ConstraintLayout 예제프로젝트생성하기 새로운액티비티생성하기 자동연결설정과이미지파일추가하기 위젯을사용자인터페이스에추가하기 제약추가하기 레이아웃테스트하기 레이아웃검사기사용하기 계층구조뷰어사용하기 요약 223 직접 XML 레이아웃작성하기 _ 직접 XML 레이아웃생성하기 XML 직접작성 vs. 레이아웃편집기의디자인모드사용 요약 229 ConstraintSet 으로 ConstraintLayout 관리하기 _ 자바코드 vs. XML 레이아웃파일 뷰생성하기 뷰속성 ConstraintSet 요약 237 안드로이드 ConstraintSet 예제프로젝트 _ 안드로이드스튜디오로예제프로젝트생성하기 액티비티에뷰추가하기 뷰속성설정하기 뷰 ID 생성하고사용하기 제약설정구성하기 EditText 뷰를추가하기 dp를 px로변환하기 요약 246 안드로이드이벤트처리개요 _ 안드로이드이벤트이해하기 android:onclick 리소스사용하기 이벤트리스너와콜백메서드 이벤트처리예제 사용자인터페이스디자인하기 이벤트리스너와콜백메서드 이벤트소비하기 요약 255 x 차례

11 CHAPTER 25 CHAPTER 26 CHAPTER 27 CHAPTER 28 안드로이드스튜디오의 Instant Run 사용하기 _ Instant Run 개요 Instant Run의 Swap 레벨이해하기 Instant Run의활성화와비활성화 Instant Run 사용하기 Instant Run 예제프로젝트 Instant Run의 Hot swap 수행시키기 Instant Run의 Warm swap 수행시키기 Instant Run의 Cold swap 수행시키기 Run 버튼 요약 262 터치와다중터치이벤트처리하기 _ 터치이벤트처리하기 MotionEvent 객체 터치액션이해하기 다중터치처리하기 다중터치애플리케이션생성하기 액티비티사용자인터페이스디자인하기 터치이벤트리스너구현하기 애플리케이션실행시키기 요약 271 안드로이드제스처감지클래스로일반제스처처리하기 _ 일반제스처감지와처리하기 제스처처리프로젝트생성하기 리스너클래스구현하기 GestureDetector 인스턴스생성하기 ontouchevent( ) 메서드구현하기 애플리케이션테스트하기 요약 279 커스텀제스처와핀치인식구현하기 _ 안드로이드제스처빌더애플리케이션 GestureOverlayView 클래스 제스처감지하기 제스처확인하기 제스처빌더애플리케이션의빌드와실행 제스처파일생성하기 SD 카드에서제스처파일추출하기 예제프로젝트생성하기 제스처파일을프로젝트에추가하기 사용자인터페이스디자인하기 285 차례 xi

12 28.11 제스처파일로드하기 이벤트리스너등록하기 ongestureperformed 메서드구현하기 애플리케이션테스트하기 GestureOverlayView 구성하기 제스처가로채기 핀치제스처처리하기 핀치제스처예제프로젝트 요약 294 CHAPTER 29 CHAPTER 30 CHAPTER 31 안드로이드프래그먼트개요 _ 프래그먼트란? 프래그먼트생성하기 레이아웃 XML 파일을사용하여프래그먼트를액티비티에추가하기 코드에서프래그먼트를추가하고관리하기 프래그먼트이벤트처리하기 프래그먼트간의통신구현하기 요약 304 안드로이드스튜디오에서프래그먼트사용하기 예제프로젝트 _ 예제프래그먼트애플리케이션개요 예제프로젝트생성하기 첫번째프래그먼트레이아웃생성하기 첫번째프래그먼트클래스생성하기 두번째프래그먼트레이아웃생성하기 프래그먼트를액티비티에추가하기 ToolbarFragment가액티비티와통신하게만들기 액티비티에서 TextFragment로통신하기 애플리케이션테스트하기 요약 322 오버플로메뉴생성과관리 _ 오버플로메뉴 오버플로메뉴생성하기 오버플로메뉴보여주기 메뉴항목선택에응답하기 체크가능한항목그룹생성하기 안드로이드스튜디오메뉴편집기 예제프로젝트생성하기 메뉴항목변경하기 onoptionsitemselected( ) 메서드변경하기 애플리케이션테스트하기 요약 334 xii 차례

13 CHAPTER 32 CHAPTER 33 CHAPTER 34 CHAPTER 35 안드로이드전환프레임워크 _ 안드로이드전환과장면 전환에인터폴레이터사용하기 장면전환사용하기 코드의커스텀전환과 TransitionSet XML의커스텀전환과 TransitionSet 인터폴레이터사용하기 커스텀인터폴레이터생성하기 begindelayedtransition 메서드사용하기 요약 346 begindelayedtransition 을사용한안드로이드전환 _ 안드로이드스튜디오 TransitionDemo 프로젝트생성하기 프로젝트파일준비하기 begindelayedtransition 애니메이션구현하기 우리입맛에맞는전환만들기 요약 354 안드로이드장면전환구현하기 _ 장면전환프로젝트개요 안드로이드스튜디오 SceneTransitions 프로젝트생성하기 루트컨테이너를확인하고준비하기 첫번째장면디자인하기 두번째장면디자인하기 첫번째장면보여주기 두번째장면로드하기 전환구현하기 전환파일추가하기 전환세트의로딩과사용 부가적인전환구성하기 요약 364 플로팅액션버튼과스낵바사용하기 _ 머티리얼디자인 디자인라이브러리 플로팅액션버튼 (FAB) 스낵바 예제프로젝트생성하기 프로젝트살펴보기 플로팅액션버튼변경하기 ListView를콘텐트레이아웃에추가하기 ListView에항목추가하기 액션을스낵바에추가하기 요약 378 차례 xiii

14 CHAPTER 36 CHAPTER 37 CHAPTER 38 CHAPTER 39 탭인터페이스생성하기 _ ViewPager 개요 TabLayout 컴포넌트개요 TabLayoutDemo 프로젝트생성하기 첫번째프래그먼트생성하기 프래그먼트복제하기 TabLayout 과 ViewPager 추가하기 Pager 어댑터생성하기 초기화작업하기 애플리케이션테스트하기 TabLayout 커스터마이징 아이콘탭항목보여주기 요약 392 RecyclerView 와 CardView 사용하기 _ RecyclerView 개요 CardView 개요 라이브러리를프로젝트에추가하기 요약 398 RecyclerView 와 CardView 예제프로젝트 _ CardDemo 프로젝트생성하기 플로팅액션버튼삭제하기 RecyclerView와 CardView 라이브러리추가하기 CardView 레이아웃디자인하기 RecyclerView 추가하기 RecyclerView 어댑터생성하기 이미지파일추가하기 RecyclerView 컴포넌트초기화하기 애플리케이션테스트하기 카드선택에응답하기 요약 410 앱바와컬랩싱툴바레이아웃사용하기 _ AppBar 개요 예제프로젝트 RecyclerView와 Toolbar 연동시키기 컬랩싱툴바레이아웃개요 제목과스크림색상변경하기 요약 420 xiv 차례

15 CHAPTER 40 CHAPTER 41 CHAPTER 42 CHAPTER 43 내비게이션드로어구현하기 _ 내비게이션드로어개요 드로어를열거나닫기 드로어항목선택에응답하기 내비게이션드로어액티비티템플릿사용하기 내비게이션드로어템플릿으로프로젝트생성하기 템플릿레이아웃리소스파일 헤더색상리소스파일 템플릿메뉴리소스파일 템플릿코드 앱실행하기 요약 429 안드로이드스튜디오마스터 / 디테일플로 _ 마스터 / 디테일플로 마스터 / 디테일플로액티비티생성하기 마스터 / 디테일플로템플릿살펴보기 마스터 / 디테일플로템플릿변경하기 콘텐트모델변경하기 디테일패널변경하기 WebsiteDetailFragment 클래스변경하기 WebsiteListActivity 클래스수정하기 매니페스트퍼미션추가하기 애플리케이션실행하기 요약 443 안드로이드인텐트개요 _ 인텐트개요 명시적인텐트 액티비티에서데이터반환하기 암시적인텐트 인텐트필터사용하기 인텐트사용가능여부확인하기 요약 450 명시적인텐트예제프로젝트 _ 예제프로젝트생성하기 ActivityA의사용자인터페이스디자인하기 두번째액티비티클래스생성하기 ActivityB 의사용자인터페이스레이아웃디자인하기 애플리케이션의매니페스트파일살펴보기 인텐트생성하기 인텐트데이터추출하기 458 차례 xv

16 43.8 서브액티비티로 ActivityB 론칭하기 서브액티비티에서데이터반환하기 애플리케이션테스트하기 요약 462 CHAPTER 44 CHAPTER 45 CHAPTER 46 암시적인텐트예제프로젝트 _ 암시적인텐트예제프로젝트생성하기 사용자인터페이스디자인하기 암시적인텐트생성하기 암시적인텐트로론칭되는액티비티생성하기 사용자인터페이스에웹뷰추가하기 인텐트 URL 얻기 MyWebView 프로젝트의매니페스트파일변경하기 MyWebView 패키지를장치에설치하기 애플리케이션테스트하기 요약 473 브로드캐스트인텐트와브로드캐스트수신자 _ 브로드캐스트인텐트개요 브로드캐스트수신자개요 브로드캐스트수신자로부터결과데이터받기 스티키브로드캐스트인텐트 브로드캐스트인텐트예제프로젝트 예제애플리케이션생성하기 브로드캐스트인텐트를생성하고전송하기 브로드캐스트수신자생성하기 매니페스트파일에브로드캐스트수신자구성하기 브로드캐스트애플리케이션테스트하기 시스템브로드캐스트인텐트리스닝하기 요약 487 스레드와스레드핸들러 _ 스레드개요 애플리케이션의메인스레드 스레드핸들러 기본적인스레드예제프로젝트 새로운스레드생성하기 스레드핸들러구현하기 핸들러에게메시지전달하기 요약 497 xvi 차례

17 CHAPTER 47 CHAPTER 48 CHAPTER 49 CHAPTER 50 스타트서비스와바운드서비스개요 _ 스타트서비스 인텐트서비스 바운드서비스 서비스생명주기 소멸된서비스재시작옵션제어하기 매니페스트파일에서비스선언하기 시스템구동시서비스시작시키기 요약 505 스타트서비스구현예제프로젝트 _ 예제프로젝트생성하기 Service 클래스생성하기 서비스를매니페스트파일에추가하기 서비스시작시키기 인텐트서비스테스트하기 Service 클래스사용하기 새로운서비스생성하기 사용자인터페이스변경하기 애플리케이션실행하기 서비스를처리하는새로운스레드생성하기 요약 517 로컬바운드서비스예제프로젝트 _ 바운드서비스이해하기 바운드서비스상호작용옵션 로컬바운드서비스예제프로젝트 바운드서비스를프로젝트에추가하기 Binder 구현하기 클라이언트를서비스에바인딩하기 예제프로젝트마무리하기 애플리케이션테스트하기 요약 528 원격바운드서비스예제프로젝트 _ 클라이언트에서원격서비스로통신하기 예제애플리케이션생성하기 사용자인터페이스디자인하기 원격바운드서비스구현하기 원격서비스를매니페스트파일에구성하기 원격서비스를론칭하고바인딩하기 원격서비스에메시지전송하기 요약 536 차례 xvii

18 CHAPTER 51 CHAPTER 52 CHAPTER 53 CHAPTER 54 안드로이드 7 의알림개요 _ 알림개요 NotifyDemo 프로젝트생성하기 사용자인터페이스디자인하기 두번째액티비티생성하기 알림을생성하고전달하기 알림에서액티비티를시작시키기 알림에액션추가하기 알림에소리추가하기 알림메시지묶기 요약 549 안드로이드 7 알림의직접응답구현 _ DirectReply 프로젝트생성하기 사용자인터페이스디자인하기 RemoteInput 객체생성하기 PendingIntent 객체생성하기 응답액션생성하기 직접응답입력데이터수신하기 알림변경하기 요약 558 안드로이드스튜디오에서 Firebase 사용하기 _ Firebase란? Firebase에서명하기 FirebaseNotify 프로젝트생성하기 사용자인터페이스구성하기 프로젝트를 Firebase에연결하기 새로운 Firebase 프로젝트생성하기 google-services.json 파일 Firebase 라이브러리추가하기 요약 566 Firebase 원격알림사용하기 _ Firebase 알림전송하기 알림메시지수신하기 알림에맞춤데이터포함시키기 포그라운드앱의알림처리하기 요약 574 xviii 차례

19 CHAPTER 55 CHAPTER 56 CHAPTER 57 CHAPTER 58 안드로이드 7 의다중창지원개요 _ 분할화면과자유형식및 PIP 모드 다중창모드로전환하기 자유형식모드의지원여부확인하기 다중창지원을앱에서활성화하기 다중창관련속성지정하기 액티비티에서다중창모드인지검사하기 다중창관련통지받기 다중창모드에서액티비티를시작시키기 자유형식모드로실행되는액티비티의크기와위치구성하기 요약 584 다중창예제프로젝트 _ 다중창프로젝트생성하기 FirstActivity 의사용자인터페이스디자인하기 두번째액티비티추가하기 두번째액티비티시작시키기 다중창모드활성화하기 다중창지원테스트하기 두번째액티비티를다른창에서시작시키기 자유형식창의위치와크기변경하기 요약 592 안드로이드 SQLite 데이터베이스개요 _ 데이터베이스테이블이해하기 데이터베이스스키마개요 열과데이터타입 데이터베이스행 기본키개요 SQLite란? SQL AVD에서 SQLite 사용해보기 안드로이드 SQLite 자바클래스 요약 602 TableLayout 과 TableRow 개요 _ TableLayout 과 TableRow 데이터베이스프로젝트생성하기 사용자인터페이스에 TableLayout 추가하기 TableRow 구성하기 버튼을레이아웃에추가하기 레이아웃마진조정하기 요약 610 차례 xix

20 CHAPTER 59 CHAPTER 60 CHAPTER 61 CHAPTER 62 안드로이드 SQLite 데이터베이스예제프로젝트 _ 데이터베이스예제개요 데이터모델생성하기 데이터핸들러구현하기 액티비티이벤트메서드구현하기 애플리케이션테스트하기 요약 621 콘텐트제공자이해하기 _ 콘텐트제공자란? 콘텐트제공자 콘텐트 URI 콘텐트리졸버 <provider> 매니페스트요소 요약 626 콘텐트제공자구현하기 _ Database 프로젝트활용하기 콘텐트제공자패키지추가하기 콘텐트제공자클래스생성하기 Authority와콘텐트 URI 구성하기 콘텐트제공자에 UriMatcher 구현하기 콘텐트제공자의 oncreate( ) 메서드구현하기 콘텐트제공자의 insert( ) 메서드구현하기 콘텐트제공자의 query( ) 메서드구현하기 콘텐트제공자의 update( ) 메서드구현하기 콘텐트제공자의 delete( ) 메서드구현하기 매니페스트파일에콘텐트제공자선언하기 데이터베이스핸들러변경하기 요약 642 구글클라우드스토리지액세스하기 _ 스토리지액세스프레임워크 스토리지액세스프레임워크사용하기 피커의파일내역선별하기 인텐트결과처리하기 파일의내용읽기 파일에내용쓰기 파일삭제하기 파일의지속적인액세스얻기 요약 650 xx 차례

21 CHAPTER 63 CHAPTER 64 CHAPTER 65 CHAPTER 66 안드로이드스토리지액세스프레임워크예제프로젝트 _ 스토리지액세스프레임워크예제프로젝트개요 스토리지액세스프레임워크예제프로젝트생성 사용자인터페이스디자인하기 요청코드선언하기 새로운스토리지파일생성하기 onactivityresult( ) 메서드 스토리지파일에데이터저장하기 스토리지파일을열고읽기 스토리지액세스애플리케이션테스트하기 요약 665 비디오재생구현하기 _ 안드로이드 VideoView 클래스개요 안드로이드 MediaController 클래스개요 비디오재생테스트관련사항 비디오재생예제프로젝트생성하기 VideoPlayer 애플리케이션의레이아웃디자인하기 VideoView 구성하기 인터넷퍼미션추가하기 MediaController를 VideoView에추가하기 onpreparedlistener 설정하기 요약 674 카메라인텐트를사용한비디오녹화와이미지캡처 _ 카메라지원여부확인하기 비디오캡처인텐트호출하기 이미지캡처인텐트호출하기 안드로이드스튜디오비디오녹화프로젝트생성하기 사용자인터페이스레이아웃디자인하기 카메라확인하기 비디오캡처인텐트론칭하기 인텐트의반환결과처리하기 애플리케이션테스트하기 요약 682 런타임퍼미션요청하기 _ 보통과위험퍼미션이해하기 퍼미션예제프로젝트생성하기 퍼미션확인하기 런타임시에퍼미션요청하기 퍼미션요청이유제공하기 퍼미션앱테스트하기 요약 692 차례 xxi

22 CHAPTER 67 CHAPTER 68 CHAPTER 69 CHAPTER 70 안드로이드오디오녹음과재생하기 _ 오디오재생하기 MediaRecorder 클래스를사용해서오디오녹음하기 예제프로젝트개요 AudioApp 프로젝트생성하기 사용자인터페이스디자인하기 마이크확인하기 액티비티초기화하기 recordaudio( ) 메서드구현하기 stopaudio( ) 메서드구현하기 playaudio( ) 메서드구현하기 매니페스트파일에퍼미션구성하기 애플리케이션테스트하기 요약 706 구글맵 API 사용하기 _ 구글맵안드로이드 API의구성요소 구글맵프로젝트생성하기 개발자서명얻기 애플리케이션테스트하기 지오코딩과역-지오코딩이해하기 지도를애플리케이션에추가하기 현재위치퍼미션요청하기 사용자의현재위치보여주기 지도타입변경하기 맵컨트롤을사용자에게보여주기 지도제스처처리하기 지도표식생성하기 맵카메라제어하기 요약 726 안드로이드인쇄프레임워크사용하기 _ 안드로이드인쇄아키텍처 인쇄서비스플러그인 구글클라우드인쇄 구글드라이브로인쇄하기 PDF로저장하기 안드로이드장치에서인쇄하기 안드로이드애플리케이션에포함되는인쇄지원옵션 요약 737 HTML 과웹콘텐트인쇄예제프로젝트 _ HTML 인쇄예제애플리케이션생성하기 동적 HTML 콘텐트인쇄하기 739 xxii 차례

23 70.3 기존웹페이지인쇄예제애플리케이션생성하기 플로팅액션버튼삭제하기 사용자인터페이스레이아웃디자인하기 웹페이지를 WebView에로드하기 인쇄메뉴옵션추가하기 요약 749 CHAPTER 71 CHAPTER 72 CHAPTER 73 안드로이드커스텀문서인쇄 _ 안드로이드커스텀문서인쇄개요 커스텀문서인쇄프로젝트준비하기 커스텀인쇄어댑터생성하기 onlayout( ) 콜백메서드구현하기 onwrite( ) 콜백메서드구현하기 페이지가인쇄범위에있는지확인하기 페이지캔버스에콘텐트그리기 인쇄작업시작시키기 애플리케이션테스트하기 요약 767 안드로이드지문인증구현하기 _ 지문인증개요 지문인증프로젝트생성하기 장치의지문인증구성하기 지문퍼미션을매니페스트파일에추가하기 지문아이콘다운로드하기 사용자인터페이스디자인하기 KeyguardManager와 FingerprintManager 사용하기 장치의보안설정확인하기 안드로이드 Keystore와 KeyGenerator 사용하기 키생성하기 Cipher 초기화하기 CryptoObject 인스턴스생성하기 지문인증처리클래스구현하기 프로젝트테스트하기 요약 786 서로다른안드로이드장치와화면처리하기 _ 서로다른장치화면처리하기 화면크기에맞는레이아웃생성하기 안드로이드스튜디오에서다양한크기의레이아웃생성하기 서로다른이미지제공하기 하드웨어지원여부확인하기 특정장치에맞는애플리케이션바이너리제공하기 요약 792 차례 xxiii

24 CHAPTER 74 CHAPTER 75 CHAPTER 76 안드로이드애플리케이션릴리스하기 _ 릴리스준비절차 빌드변이변경하기 ProGuard 활성화하기 키스토어파일생성하기 개인키생성하기 애플리케이션 APK 파일생성하기 구글플레이개발자콘솔계정등록하기 새로운 APK 버전을구글플레이개발자콘솔에업로드하기 APK 파일분석하기 요약 803 구글플레이인앱결제를애플리케이션에통합하기 _ 구글플레이결제라이브러리설치하기 인앱결제예제프로젝트생성하기 결제퍼미션을매니페스트파일에추가하기 IInAppBillingService.aidl 파일을프로젝트에추가하기 유틸리티클래스를프로젝트에추가하기 사용자인터페이스디자인하기 Click Me! 버튼구현하기 구글플레이개발자콘솔과구글계정 애플리케이션의공개인증키받기 애플리케이션에서구글플레이결제설정하기 구글플레이인앱결제구입을초기설정하기 onactivityresult 메서드구현하기 구입종료리스너구현하기 구입제품소비하기 IabHelper 인스턴스해제하기 Security.java 파일변경하기 인앱결제애플리케이션테스트하기 릴리스용 APK 빌드하기 새로운인앱제품생성하기 알파배포채널로애플리케이션제출하기 인앱결제테스트계정추가하기 그룹테스트구성하기 인앱구입의문제해결하기 요약 828 안드로이드스튜디오의그래들개요 _ 그래들개요 그래들과안드로이드스튜디오 최상위수준의그래들빌드파일 모듈수준의그래들빌드파일들 빌드파일에서명설정구성하기 명령행에서그래들작업실행하기 요약 840 xxiv 차례

25 CHAPTER 77 안드로이드스튜디오그래들빌드예제프로젝트 _ 빌드변이예제프로젝트생성하기 빌드플레이버를모듈빌드파일에추가하기 플레이버를프로젝트구조에추가하기 리소스파일을플레이버에추가하기 빌드플레이버테스트하기 빌드변이와클래스파일 빌드플레이버에패키지추가하기 각플레이버의액티비티클래스변경하기 요약 부록 A, B 는독자들의이해를위해옮긴이가작성한특별부록입니다. 아래의사이트에서예제프로젝트파일과함께무료로다운로드받으실수있습니다. URL APPENDIX A 코틀린핵심파악하기 : 개요와실습환경구축 A.1 코틀린언어개요 A.2 자바 JDK 설치하기 A.3 코틀린컴파일러설치하기 A.4 코틀린으로네이티브애플리케이션작성과실행하기 A.5 요약 APPENDIX B 코틀린핵심파악하기 : 구성요소와문법 B.1 코틀린프로그램구조 B.2 코틀린변수 B.3 코틀린의타입 B.4 연산자와연산자오버로딩 B.5 Null 타입처리메커니즘 B.6 코드실행제어 B.7 함수 B.8 클래스와인터페이스 B.9 람다식 B.10 예외처리 B.11 package와 import 차례 xxv

26 정성과최선을다했습니다. 한마디로요약해서독자여러분께드리고싶은제진심의표현입니다. 용어하나하나, 내용모두에걸쳐심사숙고하였으며, 실습용프로젝트코드의작성및수정과테스트를병행하여이책을완성하였습니다. 이책에서는안드로이드스튜디오를사용해서안드로이드애플리케이션을개발하는데필요한핵심적인내용을알려줍니다. 즉, 안드로이드스튜디오를사용하는데꼭필요한내용은물론이고, 안드로이드애플리케이션개발에반드시알아야할내용도골고루가르쳐줍니다. 그리고이모든것을안드로이드스튜디오의실습프로젝트로구성하여독자여러분이직접만들어체험하면서쉽게배울수있도록구성되었습니다. 또한, 안드로이드프로그래밍기법과안드로이드스튜디오의최신기능을반영하고있습니다. 따라서안드로이드스튜디오를사용해서안드로이드애플리케이션개발을배우고시작하려는분들께적극권하고싶은책입니다. 또한, 안드로이드스튜디오를빠른시간내에파악하고싶은기존개발자분들께도권하고싶습니다. 이책을번역하면서다음과같은부분에중점을두었습니다. 1. 모든내용을안드로이드스튜디오 3 최신버전에맞춰수정하고보충하였습니다. 2. 용어선정에신중을기하고독자여러분의이해를돕는데필요한설명을많이추가하였습니다. 3. 책의각종프로젝트를독자여러분이만들면서실습하는데도움이될수있도록결함을수정하고미비한점을보완하였습니다. xxvi 옮긴이머리말

27 이책은더욱강력해진안드로이드스튜디오 3를기준으로만든최신안드로이드도서입니다. 독자여러분께도움이될수있는책을만들어야한다는집념이있었기에가능했던것같습니다. 이책을출간하는데아낌없는배려와수고를해주신제이펍출판사의장성두사장님과이민숙과장님께진심으로감사드립니다. 2017년 7월옮긴이 드림 옮긴이머리말 xxvii

28

29 C H A P T E R 1 개요 이책은최신버전의안드로이드스튜디오 (Android Studio) 와안드로이드 SDK(Software Development Kit) 를사용해서안드로이드애플리케이션 (application, 줄여서 app) 을개발하는데필요한기법을가르쳐준다. 안드로이드스튜디오는안드로이드애플리케이션을개발할때사용하는통합개발환경 (IDE, Integrated Development Environment) 이다. 우선은안드로이드애플리케이션을개발하고테스트하는환경을구축하는데필요한내용을설명한다. 그리고안드로이드스튜디오의주요기능과사용법을살펴본다. 예를들어, 각종도구창, 코드편집기, 레이아웃편집기와같은것들이다. 또한, 인스턴트런 (Instant Run) 기능과향상된 AVD(Android Virtual Device) 에뮬레이터도살펴본다. 그다음에안드로이드의아키텍처를간략히살펴본후안드로이드스튜디오를사용해서애플리케이션과사용자인터페이스를설계하고만드는방법들을자세히알아볼것이다. 이때데이터베이스, 콘텐트제공자 (content provider), 인텐트 (intent) 와같은여러고급주제들도다룬다. 또한, 터치스크린처리, 제스처인식, 카메라사용, 비디오와오디오의재생과녹화방법도설명한다. 그리고인쇄, 애니메이션화면전환, 클라우드기반파일스토리지도다룬다. 이러한보편적인안드로이드애플리케이션개발기법들외에도이책에서는구글플레이 (Google Play) 와연관된내용들도설명한다. 구글맵 (Google Map) API를사용한지도구현이라든지, 구글플레이개발자콘솔에우리가만든애플리케이션을게시하고인앱결제 (in-app billing) 를하는방법등이다. 1

30 또한, 애플리케이션프로젝트파일들을구성및관리하고빌드 (build) 하기위해안드로이드스튜디오에서플러그인하여사용하는자동화프로젝트시스템 ( 도구 ) 인그래들 (Gradle) 에대해서도살펴본다. 그리고안드로이드버전 5( 롤리팝 ) 에소개된머티리얼 (material) 디자인의개념과안드로이드버전 6( 마시멜로 ) 에서완벽하게구현된머티리얼사용자인터페이스도설명한다. 즉, 플로팅액션버튼 (floating action button), 스낵바 (Snackbar), 탭인터페이스 (tabbed interface), 카드뷰 (card view), 내비게이션드로어 (navigation drawers), 컬랩싱툴바 (collapsing toolbar) 등이다. 또한, 변경된퍼미션메커니즘과지문인식구현방법도알아본다. 더불어안드로이드스튜디오최신버전에서새롭게변경된레이아웃편집기의기능과사용법을알려주며, 안드로이드버전 7( 누가 ) 에새로추가된 ConstraintLayout 클래스, 직접응답알림 (direct reply notifications), Firebase 서비스, 다중창지원 (multi-window support) 기능의개념과구현방법도배운다. 이책에서는여러분이자바 (Java) 프로그래밍을해본경험이있다고간주하므로자바언어에관한언급은따로하지않을것이다. 그리고윈도우 (Windows) 나맥 (Mac) 또는리눅스 (Linux) 가실행되는컴퓨터가있고안드로이드스튜디오와안드로이드 SDK를다운로드및설치할수있으면시작준비가된것이다. 이책의모든본문과그림및프로젝트코드는안드로이드스튜디오최신버전 (3.0 이상 ) 을사용하여작성되었다. 따라서독자여러분이안드로이드스튜디오를사용한최신안드로이드프로그래밍을배우는데어려움이없을것이다. 1.1 안드로이드스튜디오의장점 안드로이드스튜디오에서는종전의이클립스 IDE보다훨씬강력하고특화된기능을제공한다. 그리고앞으로구글에서는구글클라우드플랫폼 (Google Cloud Platform) 과연계시켜더욱확장된기능을제공할것이다. 중요한것만요약하면다음과같다. 유연성이좋은그래들 (Gradle) 기반의자동화프로젝트빌드시스템을사용한다 ( 이클립스에서는 Ant 사용 ). 하나의프로젝트코드로여러안드로이드장치용애플리케이션을구현할수있다. 이기능은안드로이드웨어 (Android Wear) 에서특히유용하다. 2 CHAPTER 1 개요

31 구글의각종서비스와다양한장치유형을지원하는각종템플릿들이있어서프로젝트에필요한기본적인코드와파일들을자동으로생성해준다. 그래픽레이아웃편집기의기능이강력하고사용하기쉬워서사용자인터페이스디자인이편리하다. 코드의성능이나버전호환성및기타문제점을잡아내는 Lint의기능이강화되었다. 구글클라우드플랫폼을자체적으로지원하여구글클라우드메시징 / 앱엔진과쉽게통합할수있다. 우리의코드를사전에분석하여완성도를보완해주고리팩토링 (refactoring) 을해주는각종분석도구를지원한다. 1.2 소스코드다운로드하기 이책에나오는각종예제의안드로이드스튜디오프로젝트파일들은다음에서다운로드할수있다. URL 예제프로젝트코드를안드로이드스튜디오로로드하는절차는다음과같다. 1. Welcome to Android Studio 대화상자에서 Open an existing Android Studio project를선택하거나안드로이드스튜디오메인메뉴의 File Open... 을선택한다. 2. 프로젝트선택대화상자가나오면열려는프로젝트관련파일들이있는서브디렉터리 ( 프로젝트이름과동일함 ) 를선택하고 OK를클릭한다. 3. Sync Android SDKs 대화상자가나오면 OK를클릭한다 ( 열려는프로젝트에지정되어있는안드로이드 SDK 설치디렉터리와현재사용중인컴퓨터의안드로이드 SDK 설치디렉터리가달라서이대화상자가나오는것이다. OK를클릭하면현재사용중인컴퓨터의안드로이드 SDK 설치디렉터리가프로젝트의디폴트로사용된다 ). 4. 만일프로젝트가로드되면서 Android Gradle Plugin Update Required 대화상자가나타날때는반드시 Update 버튼을클릭해야한다 ( 프로젝트에포함되는그래들플러그인의버전이업데이트되어야하기때문이다 ). 5. 프로젝트가로드된후아무창도열려있지않으면 Alt와숫자 1[ 맥 OS X에서는 Cmd와숫자 1] 키를같이눌러프로젝트도구창을연후필요한파일을편집기창으로로드한다. 1.2 소스코드다운로드하기 3

32 이책의실습프로젝트에서는여러가지의최소 SDK 버전을사용한다. 안드로이드 5.1( 롤리팝, API 22), 안드로이드 6.0( 마시멜로, API 23), 안드로이드 7.x( 누가, API 24/25) 등이다. 그리고애플리케이션으로실행할때는안드로이드 8(API 26) AVD 에뮬레이터와실제장치 ( 스마트폰 ) 를같이사용하였다. 만일다운로드한프로젝트소스를에뮬레이터가아닌각자의스마트폰이나태블릿으로실행하고자할때는그장치의안드로이드버전과같거나또는낮은버전으로최소 SDK 버전을변경해야한다. 이때는프로젝트도구창의 Gradle Scripts build.gradle (Module: app) 파일을더블클릭하여편집기에로드한후, minsdkversion 번호를해당안드로이드버전의 API 레벨번호로수정하고실행하면된다 ( 그림 1-1). 그림 단축키와코드표기 이책에서는두개이상의키보드키를누를때 + 기호로나타내었다. 예를들어, Alt 키와 Enter 키를같이누를때는 Alt + Enter로표기하였다. 또한, 단축키는윈도우키 [ 맥 OS X 키 ] 의형태로표시되어있다. 예를들면 Alt + Enter[Option + Enter]. 소스코드의삭제는글자가운데를가로지르는취소선으로표시하였으며, 추가되는코드는진한글씨로나타내었다. 1.4 안드로이드스튜디오최신버전사용하기 이책의모든내용은안드로이드스튜디오 3.0 Canary 8 릴리즈를기준으로작성되었다. 따라서안드로이드스튜디오 3.0 이전버전과는다른부분이있을수있으므로반드시안드로이드스튜디오 3.0 이상으로실습해야한다. 만일이책이출간된후에도안드로이드스튜디오 3.0 공식버전이발표되지않았다면, 다음을방문하여프리뷰버전을다운로드받자. 4 CHAPTER 1 개요

33 URL 그리고별도의설치없이압축을푼후 \bin 서브디렉터리에있는 studio.exe(32비트 ) 또는 studio64.exe(64비트 ) 를실행하면안드로이드스튜디오를사용할수있다. 단, 안드로이드 SDK 와자바 JDK를설치해야하므로 2장에서설명한대로현재의공식버전도설치하기바란다 ( 안드로이드스튜디오는서로다른버전을설치하고사용해도문제가생기지않는다 ). 1.5 독자 A/S 여러분이만족하는책이되었으면한다. 혹시오류를발견하거나문의사항이있으면 hanafos.com 혹은 으로메일을보내주기바란다. 1.6 오탈자 이책의내용에오류가없도록최선의노력을했지만, 혹시오탈자가있을지도모르겠다. 그런 경우는제이펍 ( 의이책소개페이지에있는정오표코너에서안내하도록하겠다. 1.6 오탈자 5

34 C H A P T E R 20 ConstraintLayout 예제프로젝트 안드로이드스튜디오레이아웃편집기를사용하면쉽고생산성높은방법으로안드로이드애플리케이션의사용자인터페이스를디자인할수있다. 이번장에서는안드로이드스튜디오레이아웃편집기를사용해서 ConstraintLayout 기반의사용자인터페이스를생성하는방법을알아본다. 또한, 레이아웃검사기와계층구조뷰어도구의사용법도설명한다 ConstraintLayout 예제프로젝트생성하기 우선, 새로운안드로이드스튜디오프로젝트를생성하자. 안드로이드스튜디오메인메뉴의 File New New Project... 를선택하거나웰컴스크린에서 Start a new Android Studio project를선택한다. 그러면새프로젝트를생성하는첫번째대화상자가나타날것이다. Application name 필드에는 LayoutSample을입력하고, Company Domain에는 ebookfrenzy. com을입력한후 Next 버튼을누르자. 안드로이드장치선택화면에서는폰과태블릿 (Phone and Tablet) 을선택하고, 최소 SDK는 API 22: Android 5.1 (Lollipop) 을그대로둔다. Next 버튼을누르면액티비티타입을선택하는대화상자가나올것이다. 앞의다른장에서는 Empty Activity와같은템플릿을선택해서프로젝트액티비티를자동생성했었다. 그러나여기서는새로운액티비티와그것의레이아웃리소스파일을직접생성하는방법을배울것이므로 Add No Activity를선택하고 Finish 버튼을눌러서프로젝트를생성한다. 209

35 20.2 새로운액티비티생성하기 새프로젝트의생성이끝나면안드로이드스튜디오메인창이텅빈공간으로나타날것이다. 다음으로할일은새액티비티를생성하는것이다. 안드로이드애플리케이션을개발할때아무액티비티도없는상태에서새로운액티비티를생성할필요가있는경우가더러있다. 따라서여기서작성하는예제가도움이될것이다. Alt + 1 [ Cmd + 1 ] 단축키를눌러서프로젝트도구창을열자. 프로젝트도구창의각폴더를다음과같이확장시켜서 app java com.ebookfrenzy.layoutsample 패키지를찾자. 그리고패키지이름에서마우스오른쪽버튼을클릭한후 New Activity Empty Activity 를선택한다 ( 그림 20-1). 그림 20-1 새액티비티생성대화상자가나오면 Activity Name에 LayoutSampleActivity 를입력하자. 또한, 자동으로설정된 Layout Name인 activity_layout_sample은그대로두고 Generate Layout File 도체크된상태로둔다. 레이아웃리소스파일은자동생성할필요가있기때문이다. 또한 Backwards Compatibility (AppCompat) 도체크된상태로둔다. 우리앱이구버전의안드로이드에서실행되더라도호환이되도록하기위함이다. 잠깐, 아직 Finish 버튼은누르지말자! 210 CHAPTER 20 ConstraintLayout 예제프로젝트

36 애플리케이션이장치에서실행되기위해서는론처액티비티 (launcher activity) 라는액티비티를갖고있어야한다. 론처액티비티가없으면애플리케이션이최초론칭될때어떤액티비티를시작시켜야하는지안드로이드운영체제가알수없다. 따라서애플리케이션이시작되지못한다. 여기서는하나의액티비티만갖고있으므로그것을우리애플리케이션의론처액티비티로지정해야한다. 대화상자에서 Launcher Activity 옵션을체크한후 Finish 버튼을누르자. 이제는안드로이드스튜디오가두개의파일을우리프로젝트에추가했을것이다. 액티비티의자바소스코드파일 (LayoutSampleActivity.java) 은 app java com.ebookfrenzy.layoutsample 폴더에있으며, 편집기창에이미로드되었을것이다. 또한, 사용자인터페이스의 XML 레이아웃파일 (activity_layout_sample.xml) 은 app res layout 폴더에생성되었으며, 이것역시편집기창에이미로드되었을것이다. 끝으로, 새로생성된액티비티가 AndroidManifest.xml 파일에추가되어론처액티비티로지정되어있을것이다. 매니페스트파일도프로젝트창에서볼수있다. app manifests 폴더밑에있으며다음의 XML을포함한다. 여기서 <intent-filter> 와 </intent-filter> 태그사이에있는 category 요소에론처액티비티로지정된다. <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=" package="com.ebookfrenzy.layoutsample"> <application android:allowbackup="true" android:supportsrtl="true" <activity android:name=".layoutsampleactivity"> <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> </application> </manifest> 20.2 새로운액티비티생성하기 211

37 20.3 자동연결설정과이미지파일추가하기 편집기의 activity_layout_sample.xml 레이아웃파일탭을클릭하고편집기창의제일밑에있는 Design 탭을클릭하여디자인모드로변경한다. 그리고컴포넌트트리에서레이아웃 (ConstraintLayout) 을클릭한후만일레이아웃편집기왼쪽위의 Autoconnect 버튼모양이이면클릭하여그림 20-2 처럼로변경한다. 자동연결을비활성화한후나중에우리가직접제약연결을추가하는방법을배우기위해서다. 그림 20-2 여기서는 ImageView 객체를사용해서이미지를보여줄것이다. 따라서프로젝트에이미지파일을추가해야한다. 파일이름은 galaxys6.png 이며, 이책의프로젝트파일을다운로드받으면 Material_Icons 디렉터리밑에있다. 이미지파일을각자컴퓨터운영체제의파일시스템에서찾은후클립보드로복사한다. 그리고프로젝트도구창의 app res drawable에서오른쪽마우스버튼을클릭한후 Paste를선택하고대화상자에서 OK 버튼을누른다. 그림 20-3처럼제대로복사가되었는지확인한다. 그림 위젯을사용자인터페이스에추가하기 팔레트의 Images 부류에있는 ImageView 를마우스로끌어서레이아웃의중앙에놓으면 ( 수직과수평의점선이만나는곳이중앙이다 ) Resources 대화상자가나타난다. 제일왼쪽위에 212 CHAPTER 20 ConstraintLayout 예제프로젝트

38 있는 Drawable 을클릭하고바로오른쪽의 Project 밑에있는 galaxys6 을클릭한다 ( 그림 20-4). 그림 20-4 OK 버튼을누르면이이미지가 ImageView 에지정된다. 그리고부모레이아웃과약간의좌우 여백이생기도록 ImageView 의크기를조정한후마우스로끌어서레이아웃의중앙으로이동 시킨다 (ImageView 의네개꼭지점에나타난작은사각형을마우스로끌면크기를조정할수있다 ). 그림 위젯을사용자인터페이스에추가하기 213

39 팔레트의 Text 부류에있는 TextView를끌어서 ImageView 위쪽에놓는다. 그리고속성창에서 text 속성을 Samsung Galaxy S6 으로변경하고모든속성보기버튼 ( ) 을클릭하여모든속성이나타나게한다. textalignment의오른쪽필드를클릭하여드롭다운에서 center를선택하고 textsize 속성의값을 24sp(dp 아님 ) 로입력한후 TextView가수평으로중앙에오도록조정한다 ( 그림 20-6). 그림 20-6 그다음에세개의버튼을추가하고각버튼의 text 속성값을 Buy Now, Pricing, Details 로 변경한다. 완성된레이아웃은그림 20-7 과같다. 214 CHAPTER 20 ConstraintLayout 예제프로젝트 그림 20-7

40 현재는각위젯의위치와크기를제어하는데필요한제약이충분하게추가되어있지않다. 따라서이상태로앱을실행한다면모든위젯들이화면의왼쪽위모서리에겹쳐서나타날것이다. 현재상태에서레이아웃편집기툴바의화면방향전환버튼 ( 그림 20-8의화살표로표시됨 ) 을클릭하여가로방향으로화면을회전시키자. 그림 20-8 이그림을보면알수있듯이, 이미지의일부가잘린상태로중앙에도위치하지않으며, 세개 의버튼은화면영역을벗어나서아예보이지도않는다. 화면크기변화에맞춰레이아웃과 위젯을적합하게나타낼제약이지정되지않았기때문이다 제약추가하기 장치의방향변경이나서로다른화면크기에적응가능한레이아웃을생성하는핵심요소가제약이다. 레이아웃을다시세로방향으로돌려놓고 ImageView 위에있는 TextView 를선택한다. 그리고왼쪽과오른쪽및위의제약핸들 ( 작은원 ) 을마우스로끌어서부모인 ConstraintLayout에각각연결한다 ( 그림 20-9). 그림 제약추가하기 215

41 같은요령으로 ImageView 를선택하고왼쪽과오른쪽의상대제약을부모레이아웃에연결한 다. 그리고위쪽은 TextView 의아래쪽으로, 아래쪽은중앙버튼의위쪽과연결한다. 그다음에 ImageView가선택된상태에서자주사용하는속성만나타나게한다 ( 만일모든속성이나타나있으면모든속성보기버튼 ( ) 을다시클릭.) 그리고속성창위에서위쪽마진을 24로, 아래쪽마진을 8로변경한다. 또한, 높이와너비크기를 0dp 또는 match_constraint 로변경한다 ( 그림 20-10). 이렇게설정하면화면크기에따라레이아웃이변경될때 ImageView의크기가자동으로조정된다. 그림 그림 은현재 ImageView 에추가된제약연결을보여준다. 그림 CHAPTER 20 ConstraintLayout 예제프로젝트

42 이제는세개의버튼위젯에제약을추가하는것만남았다. 여기서는세개의버튼을하나의체인 (chain) 으로연결한다. 우선, 그림 20-2 의 Autoconnect 버튼을클릭하여로바꾼다. 제약의자동연결을활성화시키기위함이다. 그다음에 Buy Now 버튼을클릭한후 Shift 키를누른채로나머지두버튼도클릭하여세버튼모두선택되도록한다. 그리고 Shift 키를떼고 Buy Now 버튼에서오른쪽마우스버튼을클릭하고메뉴의 Center Horizontally를선택한다. 앞장에서얘기했듯이, 이렇게하면선택된위젯들간의양방향제약을쉽게추가하여체인을구성할수있다. 이제는세버튼이체인으로구성되었다. 기본적으로체인스타일은 spread 스타일이된다. 여기서는이스타일이적합하다. 끝으로, Buy Now 버튼의아래쪽과레이아웃의아래쪽을제약으로연결한다. 또한, 나머지두버튼도같은방법으로레이아웃의아래쪽에연결한다. ( 각버튼을선택하고아래쪽연결점 ( 작은원 ) 을클릭한후연결선을끌어서레이아웃의아래쪽에가져가면연결점이초록색으로나타난다. 이때마우스버튼을놓으면자동으로제약이추가된다.) 이모든작업이끝나면그림 와같이세버튼의제약이연결된다. 그림 레이아웃테스트하기 모든제약연결이추가되었으므로레이아웃편집기툴바의화면방향전환버튼을다시클릭하여가로방향으로화면을회전시키자. 이제는변경된화면크기에맞추어레이아웃이제대로나타날것이다. 이로써디자인시점에서레이아웃편집기로확인한결과는이상없이잘된것이다. 다음은앱이실제실행될때도잘되는지확인해보자. 실제장치나에뮬레이터에서우리앱을실행한후가로방향으로장치를회전시켜보자. 예를들어, 그림 20-13에서는에뮬레이터에서화면방향을전환한결과를보여준다 레이아웃테스트하기 217

43 그림 위그림을보면알수있듯이, 앱을실행할때도레이아웃이제대로나타나는것을알수있 다. 이보다더복잡한레이아웃을디자인할때도마찬가지방법으로하면된다. 즉, 팔레트로 부터위젯을끌어서레이아웃에놓은후속성을설정하고제약을추가하면된다 레이아웃검사기사용하기 사용자인터페이스레이아웃을구성하는컴포넌트들의정보는레이아웃검사기 (Inspector) 를사용해서볼수있다. 단, 실제장치나에뮬레이터에서앱이실행중일때만가능하다. 앞의그림 20-13과같이가로방향으로앱의화면이나타난상태에서메인메뉴의 Tools Android Layout Inspector를선택한다. 그리고 Choose Process 대화상자에서현재실행중인애플리케이션프로세스인 com.ebookfrenzy.layoutsample을선택하고 OK 버튼을클릭한다. 그림 처럼세개의패널이나타난다 ( 여기서는프로젝트도구창을닫은상태다 ). 그림 CHAPTER 20 ConstraintLayout 예제프로젝트

44 왼쪽패널에서는사용자인터페이스레이아웃을구성하는컴포넌트들의계층구조를보여준다. 그리고중앙패널에서는장치화면에나타난레이아웃을보여준다. 여기서특정위젯을클릭하면그것과연관된컴포넌트를왼쪽패널의계층구조에서찾아서표시해준다. 또한오른쪽패널에서는현재선택된컴포넌트의모든속성과설정값을보여준다 계층구조뷰어사용하기 액티비티의뷰계층구조를자세히살펴보는데유용한도구가계층구조뷰어 (Hierarchy Viewer) 다. 이도구의주목적은현재실행중인애플리케이션에있는액티비티의뷰트리전체를자세하게보여주는것이다. 더불어레이아웃을화면에그리는성능도살펴볼수있다. 계층구조뷰어는안드로이드에뮬레이터에서실행되거나또는안드로이드개발 (development) 버전을실행하는장치에서만사용될수있다. 그러면이번장에서생성된 LayoutSample 애플리케이션에대해계층구조뷰어를실행해보자. 우선, AVD 에뮬레이터에서 LayoutSample 애플리케이션을시작시킨다. 그리고에뮬레이터에서화면이보일때까지기다리자. 그다음에안드로이드스튜디오메인메뉴에서 Tools Android Android Device Monitor를선택한다 ( 혹시 Disable ADB Integration 대화상자가나타나면 OK 버튼을누른다 ). 잠시후안드로이드장치모니터 (DDMS) 창이별도로열릴것이다. 안드로이드장치모니터메인메뉴의 Window Open Perspective... 를선택한후그다음대화상자에서 Hierarchy View를선택하고 OK 버튼을누른다. 그러면장치모니터창에계층구조뷰어가나타난다. 계층구조뷰어는여러개의패널로구성된다. 그림 20-15처럼보이는왼쪽패널의왼쪽위에있는 Windows 탭을클릭하면장치나에뮬레이터 ( 여기서는 Nexus5X) 에서현재동작가능한모든창 (window) 을보여준다 ( 계층구조뷰어에서는액티비티나프로세스대신 창 이라는용어를사용한다 ). 굵은글씨로된창이현재포그라운드로동작중인창이며, 여기서는 LayoutSampleActivity다. 그림 계층구조뷰어사용하기 219

45 우리애플리케이션프로세스인 com.ebookfrenzy.layoutsample.layoutsampleactivity 가선택된 상태에서툴바의버튼 ( 20-16). ) 을클릭하면뷰의계층구조가트리뷰로로드되어나타난다 ( 그림 그림 트리뷰패널밑에있는스케일바 (% 로표시됨 ) 를사용하거나마우스휠을돌리면트리뷰를줌인 / 줌아웃할수있다. 그러나대부분의경우트리가너무커서전체를한번에보기는힘들것이다. 그러므로마우스를클릭한채로끌어서트리를이동하여보거나, 또는오른쪽위에있는트리오버뷰 (Tree Overview) 패널안에서렌즈를이동시켜보면된다 ( 그림 20-17). 그림 CHAPTER 20 ConstraintLayout 예제프로젝트

46 트리뷰에는액티비티레이아웃에포함된뷰와더불어다른뷰들이같이나타날수있다는것을염두에두자. 예를들어, 화면맨위에나타나는액션바 (action bar), 또는액티비티가나타나는영역을제공하는레이아웃뷰등이다. 트리뷰에서특정노드를선택하면그것과일치하는사용자인터페이스요소가레이아웃뷰 ( 오른쪽하단의패널에서 Layout View 탭을클릭 ) 에빨간색으로강조되어표시된다. 그림 20-18에서는 ConstraintLayout 뷰가선택된경우를보여준다. 그림 마찬가지로, 레이아웃뷰에서특정뷰를선택하면그것과일치하는트리뷰의노드로이동되어강조표시된다. 뷰의추가정보는트리뷰에서그것의노드를선택하여얻을수있다. 해당노드를더블클릭하면팝업대화상자에서추가정보를보여준다. 예를들어, 그림 20-19에서는 LayoutSample 애플리케이션의 DETAILS 버튼노드를더블클릭했을때나타난대화상자를보여준다. (AVD 에뮬레이터를생성했던시스템이미지가구버전일때는팝업대화상자가나타나지않을수있다. 이때는 AVD 에뮬레이터를삭제하고최신버전으로생성한후앱을실행한다. 또한, 안드로이드장치모니터도다시실행시킨다.) 그림 계층구조뷰어사용하기 221

47 트리뷰에서는선택된레이아웃뷰를다시그리는작업을수행하거나, 또는트리뷰를 PNG 이미지파일로저장하는툴바버튼도제공한다 ( 트리뷰창의오른쪽위에있는각툴바버튼에마우스커서를대보면해당버튼의기능을설명하는텍스트가나온다 ). 또한, 선택된노드의뷰가그려지는성능정보를보기위해계층구조뷰어를사용할수도있다. 이때는루트뷰 ( 여기서는 ConstraintLayout) 로동작하는노드를선택한후그림 20-20에화살표로표시된툴바버튼을클릭하면된다. 그림 그러면각유형별 ( 측정치, 레이아웃, 그리기 ) 성능을나타내는점들이해당노드에나타난다 ( 그림 20-21). 여기서빨간색점은액티비티의다른뷰에비해그뷰의성능이느리다는것을나타낸다. 많은수의자식뷰들을갖고있는컨테이너뷰의성능은빨간색점으로나타날수있다. 왜냐하면각자식뷰들이모두그려질때까지기다려야하기때문이다. 그렇다고해서그컨테이너뷰가성능상의문제가있음을나타내는것은아니다. 그림 CHAPTER 20 ConstraintLayout 예제프로젝트

48 20.9 요약 안드로이드스튜디오의레이아웃편집기는안드로이드 7( 누가 ) 에추가된 ConstraintLayout 클래스와밀접하게통합되어있다. 이번장에서는레이아웃편집기를사용해서 ConstraintLayout 기반의사용자인터페이스를생성하는방법을알아보았다. 이때가장중요한것이제약연결을생성하는것이다. 또한, 레이아웃검사기와안드로이드장치모니터의계층구조뷰어를사용하는방법도살펴보았다. 이런도구들은사용자인터페이스레이아웃을구성하는컴포넌트를분석하는데유용하게사용될수있다 요약 223

49 C H A P T E R 56 다중창예제프로젝트 앞장에서설명한다중창지원개요에이어서이번장에서는다중창지원을구현하는안드 로이드앱을만들것이다. 이번장에서생성하는프로젝트에서는여러개의액티비티를분할 화면모드와자유형식모드로구성하고관리하는방법을보여준다 다중창프로젝트생성하기 우선, 새프로젝트를생성하자. 안드로이드스튜디오메인메뉴의 File New New Project... 를선택하거나웰컴스크린에서 Start a new Android Studio project를선택한다. Application name 필드에 MultiWindow를입력하고, Company Domain 필드에는 ebookfrenzy. com을입력한다. 안드로이드장치선택화면에서는폰과태블릿 (Phone and Tablet) 만선택하고, 최소 SDK 버전은 API 24: Android 7.0 (Nougat) 으로선택한다. 액티비티선택화면에서는 Empty Activity 를선택한다. 그리고마지막대화상자에서 Activity Name에 FirstActivity 를입력하고자동으로설정된나머지필드값은그대로둔다. Finish 버튼을눌러프로젝트를생성한다 FirstActivity 의사용자인터페이스디자인하기 여기서는사용자인터페이스를하나의 Button 과 TextView로구성한다. 레이아웃편집기에열려있는레이아웃파일인 activity_first.xml의탭을클릭하여선택한후디자인모드로변경한다. 그리고 Hello World! 를보여주는 TextView를삭제하자. 585

50 자동연결 (Autoconnect) 이활성화된상태에서 (18장참조 ) 팔레트의 Text 부류에있는 TextView를마우스로끌어서레이아웃의중앙에놓고 ID를 mytextview 로변경한다. 또한 Widgets 부류에있는 Button을끌어서 TextView 밑에놓자. 그리고레이아웃편집기의제약추론버튼 ( ) 을클릭한다 (18장참조 ). 이렇게하면 Button의제약연결이자동으로추가된다. Button이선택된상태에서속성창의 text 속성을 Launch 로변경하고이값을문자열리소스로추출한다. 또한, onclick 속성을찾아속성값으로 launchintent를입력한다. 이것은버튼을클릭했을때실행될메서드다. 완성된레이아웃은그림 56-1 과같다. 그림 두번째액티비티추가하기 두번째액티비티는사용자가첫번째액티비티의버튼을클릭 ( 터치 ) 하면시작되게할것이다. 프로젝트도구창의 app java 밑에있는 com.ebookfrenzy.multiwindow 패키지에서오른쪽마우스버튼을누른후 New Activity Empty Activity 를선택한다. 그리고액티비티구성대화상자에서 Activity Name을 SecondActivity로변경하고 Layout Name은 activity_second로변경한다. 이액티비티는애플리케이션이시작될때바로실행되는것이아니므로 Launcher Activity 를체크하지말아야한다. 나머지는기본값그대로두고 Finish 버튼을누른다. 586 CHAPTER 56 다중창예제프로젝트

51 레이아웃편집기에열려있는레이아웃파일인 activity_second.xml의탭을클릭하여선택한후디자인모드로변경한다. 그리고팔레트의 TextView를마우스로끌어서레이아웃의중앙에놓고속성창의 text 속성을 Second Activity 로변경하고 layout_width 속성을 wrap_ content로변경한다. 완성된레이아웃은그림 56-2 와같다. 그림 두번째액티비티시작시키기 그다음에는 FirstActivity 클래스에 launchintent( ) 메서드를구현하는코드를추가하자. 편집기 의 FirstActivity.java 를선택한후다음코드를추가한다. package com.ebookfrenzy.multiwindow; import android.content.intent; import android.support.v7.app.appcompatactivity; import android.os.bundle; import android.view.view; public class FirstActivity extends AppCompatActivity protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_first); } 56.4 두번째액티비티시작시키기 587

52 } public void launchintent(view view) { Intent i = new Intent(this, SecondActivity.class); startactivity(i); } 안드로이드 7(Nougat) 이실행중인실제장치나에뮬레이터에서앱을실행한후 Launch 버튼 을클릭하여두번째액티비티가시작되는지확인해보자 다중창모드활성화하기 또한, 앱의다중창지원을활성화하도록다음과같이 AndroidManifest.xml 파일을변경한다 ( 매니페스트파일은프로젝트도구창의 app manifests 밑에있다 ). <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=" package="com.ebookfrenzy.multiwindow"> <application android:allowbackup="true" android:supportsrtl="true" <activity android:name=".firstactivity" android:resizeableactivity="true"> <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> <activity android:name=".secondactivity"></activity> </application> </manifest> 이책을저술하는시점에는다중창지원이기본적으로활성화되어있다. 그러나향후에는기 본설정이변경될수있으므로위와같이매니페스트에다중창지원활성화를추가하는것이 좋다. 588 CHAPTER 56 다중창예제프로젝트

53 56.6 다중창지원테스트하기 우선, 안드로이드 7.0 이상버전이실행되는에뮬레이터를시작시키자 (5장참조 ). 여기서는 Nexus 5X 에뮬레이터를사용한다 (55장의 55.2 절에서설명한대로자유형식모드를활성화시켜야한다 ). 앱을다시실행시켜서전체화면모드로나타난상태에서오버뷰버튼을길게눌러분할화면모드로전환하면그림 56-3 과같이 MultiWindow 앱과오버뷰화면이서로다른창으로나타난다. Launch 버튼을클릭하면첫번째액티비티와같은창에두번째액티비티가나타난다. 그리고두개의직사각형이포개진모양의오버뷰버튼을다시길게누르면전체화면모드로전환된다. Back 버튼을눌러서다시첫번째액티비티가나타나게한다. 이번에는자유형식모드로 MultiWindow 앱을실행해보자. 단, 이때는자유형식모드를지원하는장치나에뮬레이터에서앱을실행해야한다. 우선, 전체화면모드에서오버뷰버튼을짧게눌러서오버뷰화면이나타나게한다. 그리고 MultiWindow 앱의제목에나타난자유형식모드버튼 ( 그림 56-4에원으로표시됨 ) 을클릭한다. 그림 56-3 그림 56-4 그러면 MultiWindow 앱이자유형식모드의창으로나타난다 ( 그림 56-5). 그다음에 Launch 버튼을클릭하면첫번째액티비티가두번째액티비티로교체되어같은창에나타난다. 따라서두번째액티비티를다른창에나타나게하려면그와관련된플래그를설정한인텐트로시작시켜야한다. 그림 다중창지원테스트하기 589

54 56.7 두번째액티비티를다른창에서시작시키기 첫번째액티비티가두번째액티비티로교체되지않고다른창으로나타나게하려면두번째액티비티를다른태스크스택에서시작시켜야한다. FirstActivity.java 의 launchintent( ) 메서드를다음과같이변경한다. public void launchintent(view view) { Intent i = new Intent(this, SecondActivity.class); i.addflags(intent.flag_activity_launch_adjacent Intent.FLAG_ACTIVITY_MULTIPLE_TASK Intent.FLAG_ACTIVITY_NEW_TASK); } startactivity(i); 변경이끝났으면앱을다시실행시키자. 그리고오버뷰버튼을길게눌러분할화면모드로전 환한후 Launch 버튼을눌러두번째액티비티를시작시킨다. 이제는두번째액티비티가첫 번째액티비티와인접한다른창에나타날것이다 ( 그림 56-6). 그림 CHAPTER 56 다중창예제프로젝트

55 그림 56-6의상태에서오버뷰버튼을길게누르면 MultiWindow 앱이전체화면모드로전환된다. 그리고오버뷰버튼을짧게누르면오버뷰화면이나타난다. 거기에서 MultiWindow 앱의두번째액티비티를닫은후첫번째액티비티의자유형식모드버튼 ( 그림 56-4) 을클릭하여자유형식모드로전환한다. 그다음에 Launch 버튼을클릭하여두번째액티비티를실행시키면첫번째액티비티와다른창에두번째액티비티가나타난다 ( 그림 56-7). 그림 자유형식창의위치와크기변경하기 두번째액티비티가자유형식모드의별개창으로시작될때는기본적으로화면중앙에나타난다. 그러나다음과같이하면창의위치와크기를변경할수있다. 여기서는화면의제일왼쪽위에창이나타나면서가로와세로가각각 100픽셀크기를갖도록지정한다. 다음과같이 lauchintent( ) 메서드를변경하자. package com.ebookfrenzy.multiwindow; import android.app.activityoptions; import android.content.intent; import android.graphics.rect; import android.support.v7.app.appcompatactivity; 56.8 자유형식창의위치와크기변경하기 591

56 import android.os.bundle; import android.view.view; import static com.ebookfrenzy.multiwindow.r.id.mytextview; public class FirstActivity extends AppCompatActivity protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_first); } public void launchintent(view view) { Intent i = new Intent(this, SecondActivity.class); i.addflags(intent.flag_activity_launch_adjacent Intent.FLAG_ACTIVITY_MULTIPLE_TASK Intent.FLAG_ACTIVITY_NEW_TASK); Rect rect = new Rect(0, 0, 100, 100); ActivityOptions options = ActivityOptions.makeBasic(); ActivityOptions bounds = options.setlaunchbounds(rect); startactivity(i, bounds.tobundle()); } 마지막으로, 앱을다시실행하고자유형식모드로전환한후두번째액티비티를시작시키자. 그 리고두번째액티비티창이앞에서지정한위치및크기로나타나는지확인해보자 요약 이번장에서는예제프로젝트를생성하여안드로이드앱의다중창지원을사용하는방법을알아보았다. 구체적으로는다중창지원의활성화, 새로운태스크스택으로액티비티시작시키기, 자유형식모드에서창의크기와위치를구성하기등이다. 592 CHAPTER 56 다중창예제프로젝트