Main
Pro Android with Kotlin: Developing Modern Mobile Apps
Pro Android with Kotlin: Developing Modern Mobile Apps
Peter Späth
0 /
0
How much do you like this book?
What’s the quality of the file?
Download the book for quality assessment
What’s the quality of the downloaded files?
Develop Android apps with Kotlin to create more elegant programs than the Java equivalent. This book covers the various aspects of a modern Android app that professionals are expected to encounter. There are chapters dealing with all the important aspects of the Android platform, including GUI design, file- and data-handling, coping with phone calls, multimedia apps, interaction with location and mapping services, monetizing apps, and much more.
Pro Android with Kotlin is an invaluable source for developers wanting to build real-world state-of-the-art apps for modern Android devices.
What You Will Learn
- Integrate activities, such as intents, services, toasts and more, into your Android apps
- Build UIs in Android using layouts, widgets, lists, menus, and action bars
- Deal with data in your Android apps using data persistence and cloud access
- Design for different Android devices
- Create multimedia apps in Android
- Secure, deploy, and monetize your Android apps
Professional Android app developers.
Year:
2018
Edition:
1st ed.
Publisher:
Apress
Language:
english
Pages:
500
ISBN 10:
1484238206
ISBN 13:
9781484238202
File:
PDF, 5.42 MB
Your tags:
The file will be sent to your email address. It may take up to 1-5 minutes before you receive it.
The file will be sent to your Kindle account. It may takes up to 1-5 minutes before you received it.
Please note: you need to verify every book you want to send to your Kindle. Check your mailbox for the verification email from Amazon Kindle.
Please note: you need to verify every book you want to send to your Kindle. Check your mailbox for the verification email from Amazon Kindle.
Conversion to is in progress
Conversion to is failed
You may be interested in Powered by Rec2Me
Most frequently terms
val858
android694
app524
user283
null246
override fun214
int206
var201
apps195
api194
kotlin180
interface164
uri163
devices154
provider151
filter140
hardware126
permissions117
java110
broadcasts106
layout103
online97
manifest91
files90
apis89
xml86
database85
default85
google84
import81
res81
query81
camera80
receiver80
array78
tag77
apk75
bundle74
oncreate72
cursor69
callback64
module59
vertex56
boolean54
nfc53
listener50
Related Booklists
0 comments
You can write a book review and share your experiences. Other readers will always be interested in your opinion of the books you've read. Whether you've loved the book or not, if you give your honest and detailed thoughts then people will find new books that are right for them.
1
|
2
|
Pro Android with Kotlin Developing Modern Mobile Apps — Peter Späth Pro Android with Kotlin Developing Modern Mobile Apps Peter Späth Pro Android with Kotlin: Developing Modern Mobile Apps Peter Späth Leipzig, Germany ISBN-13 (pbk): 978-1-4842-3819-6 https://doi.org/10.1007/978-1-4842-3820-2 ISBN-13 (electronic): 978-1-4842-3820-2 Library of Congress Control Number: 2018955831 Copyright © 2018 by Peter Späth This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way, and transmission or information storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now known or hereafter developed. Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark. The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to proprietary rights. While the advice and information in this book are believed to be true and accurate at the date of publication, neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or omissions that may be made. The publisher makes no warranty, express or implied, with respect to the material contained herein. Managing Director, Apress Media LLC: Welmoed Spahr Acquisitions Editor: Steve Anglin Development Editor: Matthew Moodie Coordinating Editor: Mark Powers Cover designed by eStudioCalamar Distributed to the book trade worldwide by Springer Science+; Business Media New York, 233 Spring Street, 6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail orders-ny@springer-sbm.com, or visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a Delaware corporation. For information on translations, please e-mail editorial@apress.com; for reprint, paperback, or audio rights, please e-mail bookpermissions@springernature.com. Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales web page at www.apress.com/bulk-sales. Any source code or other supplementary material referenced by the author in this book is available to readers on GitHub via the book's product page, located at www.apress.com/9781484238196. For more detailed information, please visit www.apress.com/source-code. Printed on acid-free paper To Margret. Table of Contents About the Author���������������������������������������������������������������������������������������������������xvii About the Technical Reviewers������������������������������������������������������������������������������xix Introduction������������������������������������������������������������������������������������������������������������xxi Preface����������������������������������������������������������������������������������������������������������������xxvii ■Chapter ■ 1: System������������������������������������������������������������������������������������������������� 1 The Android Operating System����������������������������������������������������������������������������������������� 1 The Development System������������������������������������������������������������������������������������������������ 3 A ndroid Studio���������������������������������������������������������������������������������������������������������������������������������������� 3 Virtual Devices���������������������������������������������������������������������������������������������������������������������������������������� 4 The SDK�������������������������������������������������������������������������������������������������������������������������������������������������� 6 ■Chapter ■ 2: Application������������������������������������������������������������������������������������������� 7 Tasks�������������������������������������������������������������������������������������������������������������������������������� 9 The Application Manifest�������������������������������������������������������������������������������������������������� 9 ■Chapter ■ 3: Activities�������������������������������������������������������������������������������������������� 13 Declaring Activities��������������������������������������������������������������������������������������������������������� 14 Starting Activities����������������������������������������������������������������������������������������������������������� 15 Activities and Tasks�������������������������������������������������������������������������������������������������������� 16 v vi Table of Contents Activities Returning Data������������������������������������������������������������������������������������������������ 17 Intent Filters������������������������������������������������������������������������������������������������������������������� 18 Intent Action����������������������������������������������������������������������������������������������������������������������������������������� 19 Intent Category������������������������������������������������������������������������������������������������������������������������������������� 19 Intent Data�������������������������������������������������������������������������������������������������������������������������������������������� 20 Intent Flags������������������������������������������������������������������������������������������������������������������������������������������� 21 System Intent Filters���������������������������������������������������������������������������������������������������������������������������� 21 Activities Lifecycle���������������������������������������������������������������������������������������������������������� 22 Preserving State in Activities����������������������������������������������������������������������������������������� 24 ■Chapter ■ 4: Services��������������������������������������������������������������������������������������������� 27 Foreground Services������������������������������������������������������������������������������������������������������ 28 Background Services����������������������������������������������������������������������������������������������������� 28 Declaring Services��������������������������������������������������������������������������������������������������������� 29 Service Classes�������������������������������������������������������������������������������������������������������������� 32 Starting Services������������������������������������������������������������������������������������������������������������ 32 Binding to Services�������������������������������������������������������������������������������������������������������� 33 Data Sent by Services���������������������������������������������������������������������������������������������������� 37 Service Subclasses�������������������������������������������������������������������������������������������������������� 39 Services Lifecycle���������������������������������������������������������������������������������������������������������� 40 More Service Characteristics����������������������������������������������������������������������������������������� 42 ■Chapter ■ 5: Broadcasts����������������������������������������������������������������������������������������� 43 Explicit Broadcasts��������������������������������������������������������������������������������������������������������� 44 Explicit Remote Broadcasts������������������������������������������������������������������������������������������� 45 Explicit Broadcasts Sending to Other Apps������������������������������������������������������������������������������������������ 46 Implicit Broadcasts��������������������������������������������������������������������������������������������������������� 47 Intent Filter Matching����������������������������������������������������������������������������������������������������� 48 Active or On-Hold Listening������������������������������������������������������������������������������������������������������������������ 51 Sending Implicit Broadcasts����������������������������������������������������������������������������������������������������������������� 52 Receiving Implicit Broadcasts�������������������������������������������������������������������������������������������������������������� 53 Listening to System Broadcasts����������������������������������������������������������������������������������������������������������� 54 Table of Contents vii Adding Security to Broadcasts��������������������������������������������������������������������������������������� 55 Securing Explicit Broadcasts���������������������������������������������������������������������������������������������������������������� 55 Securing Implicit Broadcasts���������������������������������������������������������������������������������������������������������������� 57 Sending Broadcasts from the Command Line���������������������������������������������������������������� 58 Random Notes on Broadcasts���������������������������������������������������������������������������������������� 59 ■Chapter ■ 6: Content Providers������������������������������������������������������������������������������ 61 The Content Provider Framework����������������������������������������������������������������������������������� 61 Providing Content����������������������������������������������������������������������������������������������������������� 63 Initializing the Provider������������������������������������������������������������������������������������������������������������������������� 63 Querying Data��������������������������������������������������������������������������������������������������������������������������������������� 63 Modifying Content�������������������������������������������������������������������������������������������������������������������������������� 65 Finishing the ContentProvider Class����������������������������������������������������������������������������������������������������� 66 Registering the Content Provider����������������������������������������������������������������������������������� 67 Designing Content URIs������������������������������������������������������������������������������������������������������������������������ 70 Building a Content Interface Contract��������������������������������������������������������������������������������������������������� 71 A Cursor Class Based on AbstractCursor and Related Classes������������������������������������������������������������ 73 A Cursor Class Based on the Cursor Interface�������������������������������������������������������������������������������������� 75 Dispatching URIs Inside the Provider Code������������������������������������������������������������������������������������������� 76 Providing Content Files������������������������������������������������������������������������������������������������������������������������� 76 Informing Listeners of Data Changes��������������������������������������������������������������������������������������������������� 79 Extending a Content Provider����������������������������������������������������������������������������������������� 79 Client Access Consistency by URI Canonicalization������������������������������������������������������������������������������ 80 Consuming Content�������������������������������������������������������������������������������������������������������� 80 Using the Content Resolver������������������������������������������������������������������������������������������������������������������ 80 Accessing System Content Providers��������������������������������������������������������������������������������������������������� 82 Batch-Accessing Content Data������������������������������������������������������������������������������������������������������������� 93 Securing Content������������������������������������������������������������������������������������������������������������ 93 Providing Content for the Search Framework���������������������������������������������������������������� 95 Documents Provider������������������������������������������������������������������������������������������������������� 95 viii Table of Contents ■Chapter ■ 7: Permissions������������������������������������������������������������������������������������� 103 Permission Types��������������������������������������������������������������������������������������������������������� 103 Defining Permissions��������������������������������������������������������������������������������������������������� 104 Using Permissions�������������������������������������������������������������������������������������������������������� 105 Acquiring Permissions������������������������������������������������������������������������������������������������� 109 Acquiring Special Permissions������������������������������������������������������������������������������������� 110 Feature Requirements and Permissions���������������������������������������������������������������������� 112 Permissions Handling Using a Terminal����������������������������������������������������������������������� 113 ■Chapter ■ 8: APIs�������������������������������������������������������������������������������������������������� 115 Databases�������������������������������������������������������������������������������������������������������������������� 115 Configuring Your Environment for Room�������������������������������������������������������������������������������������������� 116 Room Architecture������������������������������������������������������������������������������������������������������������������������������ 116 The Database�������������������������������������������������������������������������������������������������������������������������������������� 116 Entities������������������������������������������������������������������������������������������������������������������������������������������������ 117 Relationships�������������������������������������������������������������������������������������������������������������������������������������� 118 Nested Objects����������������������������������������������������������������������������������������������������������������������������������� 120 Using Indexes������������������������������������������������������������������������������������������������������������������������������������� 121 Data Access: DAOs������������������������������������������������������������������������������������������������������������������������������ 121 Observable Queries���������������������������������������������������������������������������������������������������������������������������� 123 Database Clients��������������������������������������������������������������������������������������������������������������������������������� 125 Transactions��������������������������������������������������������������������������������������������������������������������������������������� 127 Migrating Databases�������������������������������������������������������������������������������������������������������������������������� 127 Scheduling������������������������������������������������������������������������������������������������������������������� 128 JobScheduler�������������������������������������������������������������������������������������������������������������������������������������� 130 Firebase JobDispatcher���������������������������������������������������������������������������������������������������������������������� 133 Alarm Manager����������������������������������������������������������������������������������������������������������������������������������� 137 Loaders������������������������������������������������������������������������������������������������������������������������ 140 Notifications����������������������������������������������������������������������������������������������������������������� 143 Creating and Showing Notifications��������������������������������������������������������������������������������������������������� 145 Adding Direct Reply���������������������������������������������������������������������������������������������������������������������������� 147 Notification Progress Bar�������������������������������������������������������������������������������������������������������������������� 150 Table of Contents ix Expandable Notifications�������������������������������������������������������������������������������������������������������������������� 150 Rectifying Activity Navigation������������������������������������������������������������������������������������������������������������� 150 Grouping Notifications������������������������������������������������������������������������������������������������������������������������ 151 Notification Channels������������������������������������������������������������������������������������������������������������������������� 153 Notification Badges���������������������������������������������������������������������������������������������������������������������������� 154 Contacts����������������������������������������������������������������������������������������������������������������������� 155 Contacts Framework Internals����������������������������������������������������������������������������������������������������������� 155 Reading Contacts������������������������������������������������������������������������������������������������������������������������������� 156 Writing Contacts��������������������������������������������������������������������������������������������������������������������������������� 158 Using Contacts System Activities������������������������������������������������������������������������������������������������������� 162 Synchronizing Contacts���������������������������������������������������������������������������������������������������������������������� 163 Using Quick Contact Badges�������������������������������������������������������������������������������������������������������������� 163 Search Framework������������������������������������������������������������������������������������������������������� 165 The Searchable Configuration������������������������������������������������������������������������������������������������������������ 166 The Searchable Activity���������������������������������������������������������������������������������������������������������������������� 166 The Search Dialog������������������������������������������������������������������������������������������������������������������������������ 167 The Search Widget������������������������������������������������������������������������������������������������������������������������������ 168 Search Suggestions���������������������������������������������������������������������������������������������������������������������������� 170 Location and Maps������������������������������������������������������������������������������������������������������� 175 Last Known Location�������������������������������������������������������������������������������������������������������������������������� 176 Tracking Position Updates������������������������������������������������������������������������������������������������������������������ 178 Geocoding������������������������������������������������������������������������������������������������������������������������������������������� 180 Using ADB to Fetch Location Information������������������������������������������������������������������������������������������� 183 Maps��������������������������������������������������������������������������������������������������������������������������������������������������� 184 Preferences������������������������������������������������������������������������������������������������������������������ 185 ■Chapter ■ 9: User Interface���������������������������������������������������������������������������������� 191 Background Tasks�������������������������������������������������������������������������������������������������������� 191 Java Concurrency������������������������������������������������������������������������������������������������������������������������������� 192 The AsyncTask Class�������������������������������������������������������������������������������������������������������������������������� 192 Handlers��������������������������������������������������������������������������������������������������������������������������������������������� 193 Loaders����������������������������������������������������������������������������������������������������������������������������������������������� 193 x Table of Contents Supporting Multiple Devices���������������������������������������������������������������������������������������� 193 Screen Sizes��������������������������������������������������������������������������������������������������������������������������������������� 194 Pixel Densities������������������������������������������������������������������������������������������������������������������������������������ 194 Declare Restricted Screen Support���������������������������������������������������������������������������������������������������� 195 Detect Device Capabilities������������������������������������������������������������������������������������������������������������������ 195 Programmatic UI Design���������������������������������������������������������������������������������������������� 196 Adapters and List Controls������������������������������������������������������������������������������������������� 198 Styles and Themes������������������������������������������������������������������������������������������������������� 201 Fonts in XML����������������������������������������������������������������������������������������������������������������� 203 2D Animation���������������������������������������������������������������������������������������������������������������� 205 Auto-animating Layouts��������������������������������������������������������������������������������������������������������������������� 205 Animated Bitmaps������������������������������������������������������������������������������������������������������������������������������ 205 Property Animation����������������������������������������������������������������������������������������������������������������������������� 206 View Property Animator���������������������������������������������������������������������������������������������������������������������� 207 Spring Physics������������������������������������������������������������������������������������������������������������������������������������ 207 Transitions������������������������������������������������������������������������������������������������������������������������������������������ 208 Start an Activity Using Transitions������������������������������������������������������������������������������������������������������ 209 Fast Graphics OpenGL ES��������������������������������������������������������������������������������������������� 211 Showing an OpenGL Surface in Your Activity�������������������������������������������������������������������������������������� 212 Creating a Custom OpenGL View Element������������������������������������������������������������������������������������������ 212 A Triangle with a Vertex Buffer����������������������������������������������������������������������������������������������������������� 214 A Quad with a Vertex Buffer and an Index Buffer������������������������������������������������������������������������������� 216 Creating and Using a Renderer����������������������������������������������������������������������������������������������������������� 220 Projection������������������������������������������������������������������������������������������������������������������������������������������� 221 Motion������������������������������������������������������������������������������������������������������������������������������������������������� 232 Light���������������������������������������������������������������������������������������������������������������������������������������������������� 232 Textures���������������������������������������������������������������������������������������������������������������������������������������������� 235 User Input������������������������������������������������������������������������������������������������������������������������������������������� 241 UI Design with Movable Items�������������������������������������������������������������������������������������� 242 Menus and Action Bars������������������������������������������������������������������������������������������������ 243 Options Menu������������������������������������������������������������������������������������������������������������������������������������� 243 Table of Contents xi Context Menu������������������������������������������������������������������������������������������������������������������������������������� 245 Contextual Action Mode���������������������������������������������������������������������������������������������������������������������� 246 Pop-up Menus������������������������������������������������������������������������������������������������������������������������������������ 246 Progress Bars��������������������������������������������������������������������������������������������������������������� 247 Working with Fragments���������������������������������������������������������������������������������������������� 248 Creating Fragments���������������������������������������������������������������������������������������������������������������������������� 248 Handling Fragments from Activities��������������������������������������������������������������������������������������������������� 249 Communicating with Fragments�������������������������������������������������������������������������������������������������������� 250 App Widgets����������������������������������������������������������������������������������������������������������������� 250 Drag and Drop�������������������������������������������������������������������������������������������������������������� 253 Defining Drag Data����������������������������������������������������������������������������������������������������������������������������� 254 Defining a Drag Shadow��������������������������������������������������������������������������������������������������������������������� 254 Starting a Drag����������������������������������������������������������������������������������������������������������������������������������� 255 Listening to Drag Events��������������������������������������������������������������������������������������������������������������������� 256 Multitouch�������������������������������������������������������������������������������������������������������������������� 258 Picture-in-Picture Mode����������������������������������������������������������������������������������������������� 259 Text to Speech�������������������������������������������������������������������������������������������������������������� 259 ■Chapter ■ 10: Development���������������������������������������������������������������������������������� 261 Writing Reusable Libraries in Kotlin����������������������������������������������������������������������������� 261 Starting a Library Module������������������������������������������������������������������������������������������������������������������� 261 Creating the Library���������������������������������������������������������������������������������������������������������������������������� 262 Testing the Library������������������������������������������������������������������������������������������������������������������������������ 263 Using the Library�������������������������������������������������������������������������������������������������������������������������������� 264 Publishing the Library������������������������������������������������������������������������������������������������������������������������� 264 Advanced Listeners Using Kotlin���������������������������������������������������������������������������������� 265 Multithreading�������������������������������������������������������������������������������������������������������������� 266 Compatibility Libraries������������������������������������������������������������������������������������������������� 268 Kotlin Best Practices���������������������������������������������������������������������������������������������������� 270 Functional Programming�������������������������������������������������������������������������������������������������������������������� 271 Top-Level Functions and Data������������������������������������������������������������������������������������������������������������ 272 Class Extensions��������������������������������������������������������������������������������������������������������������������������������� 273 xii Table of Contents Named Arguments������������������������������������������������������������������������������������������������������������������������������ 275 Scoping Functions������������������������������������������������������������������������������������������������������������������������������ 275 Nullability�������������������������������������������������������������������������������������������������������������������������������������������� 277 Data Classes��������������������������������������������������������������������������������������������������������������������������������������� 277 Destructuring�������������������������������������������������������������������������������������������������������������������������������������� 278 Multiline String Literals���������������������������������������������������������������������������������������������������������������������� 279 Inner Functions and Classes��������������������������������������������������������������������������������������������������������������� 279 String Interpolation����������������������������������������������������������������������������������������������������������������������������� 279 Qualified “this”����������������������������������������������������������������������������������������������������������������������������������� 280 Delegation������������������������������������������������������������������������������������������������������������������������������������������ 280 Renamed Imports������������������������������������������������������������������������������������������������������������������������������� 281 Kotlin on JavaScript����������������������������������������������������������������������������������������������������� 281 Creating a JavaScript Module������������������������������������������������������������������������������������������������������������� 281 Using the JavaScript Module�������������������������������������������������������������������������������������������������������������� 283 ■Chapter ■ 11: Building������������������������������������������������������������������������������������������ 285 Build-Related Files������������������������������������������������������������������������������������������������������� 285 Module Configuration��������������������������������������������������������������������������������������������������� 286 Module Common Configuration������������������������������������������������������������������������������������ 288 Module Build Variants�������������������������������������������������������������������������������������������������� 288 Build Types����������������������������������������������������������������������������������������������������������������������������������������� 289 Product Flavors����������������������������������������������������������������������������������������������������������������������������������� 290 Source Sets���������������������������������������������������������������������������������������������������������������������������������������� 291 Running a Build from the Console�������������������������������������������������������������������������������� 293 Signing������������������������������������������������������������������������������������������������������������������������� 294 ■Chapter ■ 12: Communication������������������������������������������������������������������������������ 297 ResultReceiver Classes������������������������������������������������������������������������������������������������ 297 Firebase Cloud Messaging������������������������������������������������������������������������������������������� 299 Communication with Backends������������������������������������������������������������������������������������ 301 Communication with HttpsURLConnection������������������������������������������������������������������� 302 Networking with Volley������������������������������������������������������������������������������������������������� 304 Table of Contents xiii Setting Up a Test Server����������������������������������������������������������������������������������������������� 306 Android and NFC���������������������������������������������������������������������������������������������������������� 308 Talking to NFC Tags������������������������������������������������������������������������������������������������������ 308 Peer-to-Peer NFC Data Exchange��������������������������������������������������������������������������������� 310 NFC Card Emulation����������������������������������������������������������������������������������������������������� 311 Android and Bluetooth�������������������������������������������������������������������������������������������������� 317 A Bluetooth RfComm Server����������������������������������������������������������������������������������������� 317 An Android RfComm Client������������������������������������������������������������������������������������������� 320 ■Chapter ■ 13: Hardware��������������������������������������������������������������������������������������� 337 Programming with Wearables�������������������������������������������������������������������������������������� 337 Wearables Development��������������������������������������������������������������������������������������������������������������������� 338 Wearables App User Interface������������������������������������������������������������������������������������������������������������ 340 Wearables Faces�������������������������������������������������������������������������������������������������������������������������������� 341 Adding Face Complications���������������������������������������������������������������������������������������������������������������� 341 Providing Complication Data�������������������������������������������������������������������������������������������������������������� 354 Notifications on Wearables����������������������������������������������������������������������������������������������������������������� 357 Controlling App Visibility on Wearables����������������������������������������������������������������������������������������������� 360 Authentication in Wear����������������������������������������������������������������������������������������������������������������������� 361 Voice Capabilities in Wear������������������������������������������������������������������������������������������������������������������ 361 Speakers on Wearables���������������������������������������������������������������������������������������������������������������������� 363 Location in Wear��������������������������������������������������������������������������������������������������������������������������������� 364 Data Communication in Wear������������������������������������������������������������������������������������������������������������� 365 Programming with Android TV�������������������������������������������������������������������������������������� 367 Android TV Use Cases������������������������������������������������������������������������������������������������������������������������� 367 Starting an Android TV Studio Project������������������������������������������������������������������������������������������������ 367 Android TV Hardware Features����������������������������������������������������������������������������������������������������������� 368 UI Development for Android TV����������������������������������������������������������������������������������������������������������� 368 Recommendation Channels for Content Search��������������������������������������������������������������������������������� 370 A Recommendation Row for Content Search������������������������������������������������������������������������������������� 373 Android TV Content Search����������������������������������������������������������������������������������������������������������������� 376 xiv Table of Contents Android TV Games������������������������������������������������������������������������������������������������������������������������������ 377 Android TV Channels��������������������������������������������������������������������������������������������������������������������������� 378 Programming with Android Auto���������������������������������������������������������������������������������� 378 Developing for Android Auto��������������������������������������������������������������������������������������������������������������� 379 Testing Android Auto for a Phone Screen������������������������������������������������������������������������������������������� 379 Testing Android Auto for a Car Screen������������������������������������������������������������������������������������������������ 379 Develop Audio Playback on Auto�������������������������������������������������������������������������������������������������������� 381 Develop Messaging on Auto��������������������������������������������������������������������������������������������������������������� 383 Playing and Recording Sound������������������������������������������������������������������������������������������������������������� 385 Short Sound Snippets������������������������������������������������������������������������������������������������������������������������� 386 Playing Media������������������������������������������������������������������������������������������������������������������������������������� 388 Recording Audio����������������������������������������������������������������������������������������������������������� 391 Using the Camera��������������������������������������������������������������������������������������������������������� 391 Taking a Picture���������������������������������������������������������������������������������������������������������������������������������� 392 Recording a Video������������������������������������������������������������������������������������������������������������������������������� 395 Writing Your Own Camera App������������������������������������������������������������������������������������� 397 Android and NFC���������������������������������������������������������������������������������������������������������� 423 Android and Bluetooth������������������������������������������������������������������������������������������������������������������������ 423 Android Sensors��������������������������������������������������������������������������������������������������������������������������������� 424 Retrieving Sensor Capabilities������������������������������������������������������������������������������������������������������������ 424 Listening to Sensor Events����������������������������������������������������������������������������������������������������������������� 424 Interacting with Phone Calls���������������������������������������������������������������������������������������� 427 Monitoring Phone State Changes������������������������������������������������������������������������������������������������������� 427 Initiate a Dialing Process�������������������������������������������������������������������������������������������������������������������� 431 Create a Phone Call Custom UI����������������������������������������������������������������������������������������������������������� 431 Fingerprint Authentication�������������������������������������������������������������������������������������������� 431 ■Chapter ■ 14: Testing�������������������������������������������������������������������������������������������� 433 Unit Tests���������������������������������������������������������������������������������������������������������������������� 434 Standard Unit Tests����������������������������������������������������������������������������������������������������������������������������� 434 Unit Tests with Stubbed Android Framework�������������������������������������������������������������������������������������� 435 Unit Tests with Simulated Android Framework����������������������������������������������������������������������������������� 436 Table of Contents xv Unit Tests with Mocking���������������������������������������������������������������������������������������������������������������������� 437 Integration Tests����������������������������������������������������������������������������������������������������������� 443 Testing Services��������������������������������������������������������������������������������������������������������������������������������� 443 Testing Intent Services����������������������������������������������������������������������������������������������������������������������� 444 Testing Content Providers������������������������������������������������������������������������������������������������������������������� 446 Testing Broadcast Receivers�������������������������������������������������������������������������������������������������������������� 447 User Interface Tests������������������������������������������������������������������������������������������������������ 448 ■Chapter ■ 15: Troubleshooting����������������������������������������������������������������������������� 449 Logging������������������������������������������������������������������������������������������������������������������������ 449 Debugging�������������������������������������������������������������������������������������������������������������������� 453 Performance Monitoring���������������������������������������������������������������������������������������������� 453 Memory Usage Monitoring������������������������������������������������������������������������������������������� 457 ■Chapter ■ 16: Distributing Apps��������������������������������������������������������������������������� 461 Your Own App Store������������������������������������������������������������������������������������������������������ 461 The Google Play Store�������������������������������������������������������������������������������������������������� 462 ■Chapter ■ 17: Instant Apps����������������������������������������������������������������������������������� 463 DevelopingInstant Apps������������������������������������������������������������������������������������������������ 463 Testing Instant Apps on an Emulator���������������������������������������������������������������������������� 465 Building Deployment Artifacts�������������������������������������������������������������������������������������� 466 Preparing Deep Links��������������������������������������������������������������������������������������������������� 466 Rolling Out Instant Apps����������������������������������������������������������������������������������������������� 467 ■Chapter ■ 18: CLI�������������������������������������������������������������������������������������������������� 469 The SDK Build Tools������������������������������������������������������������������������������������������������������ 472 The SDK Platform Tools������������������������������������������������������������������������������������������������ 475 Index��������������������������������������������������������������������������������������������������������������������� 479 About the Author Peter Späth, Ph. D. graduated in 2002 as a physicist and soon afterward became an IT consultant, mainly for Java-related projects. In 2016 he decided to concentrate on writing books on various subjects, with a primary focus on software development. With a wealth of experience in Java-related languages, the release of Kotlin for building Android apps made him enthusiastic about writing books for Kotlin development in the Android environment. xvii About the Technical Reviewers Marcos Placona is a developer evangelist at Twilio and a GDE. He serves communities in London and all over Europe. He is passionate about technology and security and spends a great deal of his time building mobile and web apps and occasionally connecting them to physical devices. Marcos is a great believer in open source projects. When he’s not writing open source code, he’s probably blogging about code on https://androidsecurity.info, https:// androidthings.rocks, or https://realkotlin.com. He’s also a great API enthusiast and believes they bring peace to the software engineering world. Massimo Nardone has a master of science degree in computing science from the University of Salerno, Italy, and has more than 24 years of experience in the areas of security, web/mobile development, cloud, and IT architecture. His IT passions are security and Android. Specifically, he has worked as a project manager, software engineer, research engineer, chief security architect, information security manager, PCI/SCADA auditor, and senior lead IT security/cloud/SCADA architect. He has also worked as a visiting lecturer and supervisor for exercises at the Networking Laboratory of the Helsinki University of Technology (Aalto University), and he holds four international patents (in the PKI, SIP, SAML, and proxy areas). xix xx About the Technical Reviewers He currently works as the chief information security officer (CISO) for Cargotec Oyj and is a member of the ISACA Finland Chapter board. Massimo has reviewed more than 45 IT books for different publishing companies and is the coauthor of Pro JPA 2 in Java EE 8 (Apress, 2018), Beginning EJB in Java EE 8 (Apress, 2018), and Pro Android Games (Apress, 2015). Introduction The programs explained in this book, despite their strong affinity to the Kotlin way of thinking, will not be totally mysterious to Java developers or developers of other modern computer languages. One of the design goals of Kotlin is expressiveness, so understanding Kotlin programs requires little effort, even when the programs get shorter. But at some point, you have to pay for maximum brevity with a loss of expressiveness and a loss of readability. When it comes to deciding what is better, I favor expressiveness over brevity, but be assured that a loquacious programming style is a no-go. In the end, professional developers want to write concise apps because less code means lower costs when it comes to maintenance. The Transition from Java to Kotlin Just to whet your appetite, you will now take a look at a really simple app—one that lacks a lot of features you would want to see in a more complex and professional app—and then rewrite it from Java to Kotlin. The app consists of a single activity and presents an edit field, a button, and a text field that reacts to button presses. If you want to create it using Android Studio, you initiate a new project, disable Kotlin support, and edit the layout to contain a TextView widget, a Button widget, and an EditText widget. Then assign the IDs edit, btn, and text to them, respectively. The Java code is as follows: package de.pspaeth.simplejava; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.*; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); xxi xxii Introduction final EditText et = findViewById(R.id.edit); final Button btn = findViewById(R.id.btn); final TextView text = findViewById(R.id.text); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String entered = et.getText().toString(); text.setText("You entered '" + entered + "' and pressed 'Go'"); } }); } } Here are a few notes about the previous Java code: The public in front of the class says that it is visible from everywhere. It cannot be omitted here since otherwise the framework could not use the class. The setContentView() changes something by virtue of the “set,” which is such a common construct that you might want to write it more concisely as contentView = s.th.instead, even with a variable of name "contentView" not actually existing or being private. A couple of competitor languages allow for this type of syntax. In Groovy for example, you can write contentView = s.th.and the language will internally translate it to setContentView(). The final in front of the three declarations is necessary in Java up to version 7 because the variables are going to be used in the anonymous inner class that comes a little later. Also, for the setOnClickListener() method, you might want to use .onClickListener = s.th. instead. It’s the same for the .setText() a little later. The argument to setOnClick-Listener() is an object of an anonymous inner class; it is already an abbreviation of first declaring and then instantiating and using it. But you could be even more expressive with syntax like btn -> do s.th. or similar, just not in the Java language (well, at least not before Java 8). For the et.getText() method, you could just as well write something like et.text, which would express the same thing but is shorter. A sister project that does the same thing but with Kotlin support is written in the Kotlin language as follows: package de.pspaeth.simplekotlin import android.support.v7.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.* Introduction xxiii class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) btn.setOnClickListener { view -> val entered = edit.text.toString() text.text = "You entered '" + entered + "' and pressed 'Go'" } } } Looking at the Kotlin code more thoroughly, a couple of observations emerge: You don’t need the semicolon delimiters. Kotlin checks at line breaks whether the statement is finished or whether the following line needs to be included. You don’t need public in front of the class; public is standard in Kotlin. Instead of extends, you just write :, improving the readability a little bit. You don’t need to specify void as a return type if a function doesn’t return anything. Kotlin can infer that. Unfortunately, you cannot write contentView = s.th. as suggested earlier. The Groovy language, for example, allows for that. The reason why this can’t be done in Kotlin is that the construct contentView = s.th. implies that there must be a class field named contentView, which is not the case. The compiler could check for appropriately named methods and then allow for that syntax, but the Kotlin developers decided to impose this restriction and to prohibit the construct if the field doesn’t exist. The same is true for setOnClickListener because a field called onClickListener doesn’t exist either. Instead of an anonymous inner class, you can use the functional construct view -> …. This is always possible if the addressed class, the listener in this case, just contains a single method, like void onClick( View v ) in the base interface used here. The Kotlin compiler knows that it must use that particular single method of the listener class. The EditText, Button, and TextView variables no longer need to be declared. This is, however, not related to Kotlin but a mechanism provided by Android Studio. The import kotlinx.android.synthetic. main.activity_main.* brings you those fields automatically, derived from the resources. To review, the Kotlin code with 559 characters does the same as the Java code with 861 characters. This is a savings of 35 percent, a percentage you can expect for more complex classes as well. Despite the syntax being different from Java, the Kotlin compiler translates its source code to the same virtual machine bytecode as Java, so Kotlin can use the plethora of Java libraries that are out there in the wild, and Java developers switching to or also using Kotlin won’t miss them. xxiv Introduction This Book’s Audience This book is for intermediate to experienced Android developers wanting to use the new Kotlin features to address current Android versions and devices. After reading this book, you will be able to use Android Studio and Kotlin to build advanced apps targeting the Android platform. Being a Kotlin expert is not absolutely necessary for using this book, but having read introductory-level Kotlin books or studied online resources is surely helpful. The online documentation of Kotlin provides valuable resources you can use as references while reading this book. Source You can find all the code source shown or referred to in this book at https://github.com/ Apress/pro-android-with-kotlin. Online Text Companion Some lists and tables, as well as some class and interface details, are available as part of the free source code download at https://github.com/Apress/pro-android-with-kotlin. References to such online resources are marked appropriately. How to Read This Book This book can be read sequentially if you want to learn what can be done on the Android platform, or you can read the chapters independently when the need arises while working on your Android projects. In addition, you can use parts of the book as a reference for both finding solutions to particular problems and determining how things can be done using Kotlin instead of Java. This book includes a description of special Kotlin language constructs that will help you make your code concise and reliable. Specifically, Chapter 1 gives a short, bird’s-eye view of the Android system. If you already have some experience with Android, you can skip it or just skim it. Chapters 2 to 6 talk about the Android architecture’s corner blocks: an application as a whole, activities, services, broadcasts, and content providers. If you are a pro-level developer, some of the information provided in these chapters might seem a bit basic and easy to find in the official Android developer documentation or elsewhere on the Web. The reason why I have included these topics is that the information in other sources is of varying quality—sometimes because of historical reasons, sometimes just because it is outdated. So, I tried to rectify some of these peculiarities and also provide you with a consolidated, fresh view on things. I hope I can save you some time when you get into the deeper-level nuts and bolts of Android work. You can also use these chapters as a reference in case you are in doubt about certain development issues while your Android project advances. Chapter 7 briefly talks about the permission system. This is something you must of course be acquainted with if you develop pro-level Android apps. Introduction xxv Chapters 8 and 9 deal with APIs you can use in your app and user interface issues. Because both of these are big issues, it is not possible to mention everything that refers to these topics. I, however, will give you a selection of useful and interesting solutions for various tasks in these areas. Chapters 10 and 11 take a deeper look at development and building strategies and describe how things can best be done inside Kotlin. While in the previous chapters the Kotlin code is presented in a more empirical way, in Chapter 10 I describe how to use Kotlin constructs to produce more elegant and better-readable application code. Chapter 12 describes some methods you can use to communicate between components inside your app or between your app and other apps or the outside world. Chapter 13 handles different devices from a hardware perspective, including smartphones, wearables like smartwatches, Android TV, and Android Auto. Here I also talk about ways to access the camera and sensors and how you can interface with phone calls. Chapters 14 to 17 deal with testing, troubleshooting, and publishing your app, and Chapter 18 explains how to use the tools provided with the SDK installation (part of Android Studio). Some Notes About the Code While in general I try to follow a “clean code” approach for all the code presented in this book, for simplicity I use two anti-patterns you shouldn’t follow in your production code. I do not use localized string resources. So, whenever you see something like this inside XML resources: android:text = "Some message" what instead you should do is create a string resource and let the attribute refer to it, as shown here: android:text = "@string/message" For logging statements, I always use LOG as a tag, as shown here: Log.e("LOG", "The message") In your code, you instead should create a tag like this: companion object { val TAG="The class name" ... } and then use this: Log.e(TAG, "The message") Preface Pro Android with Kotlin is an addition to the popular Apress series for Android development targeting the Java platform. With Kotlin as a highly promising new official language in the Android environment, it allows for more elegant programs compared to the Java standard. This book deals with advanced aspects of a modern Android app. With a thorough description of the important parts of Android system internals and professional-level APIs, advanced user interface topics, advanced development topics, in-depth communication surveys, professional-level hardware topics including looking at devices other than smartphones, a troubleshooting part with guidance on how to fix memory and performance problems, and an introduction to app monetizing, the book is an invaluable resource for developers wanting to build state-of-the-art professional apps for modern Android devices. This book is not meant to be an introduction to the Kotlin language. For this aim, please take a look at the Kotlin web site or any introductory-level book about Kotlin. What you will find here is an attempt to use as many features of Kotlin to write elegant and stable apps using less code compared to Java. In 2017, Android versions 8.0 and 8.1 were introduced. In a professional environment, writing apps that depend on new Android 8.x features is a bad idea since the worldwide distribution of devices running an 8.x version is well below 10 percent as of the writing of this book. But you can write code targeting versions 4.0 all the way up to 8.0 (thus covering almost 100 percent of Android devices) by introducing branches in your code. This is what you will be doing in this book. I still concentrate on modern 8.x development, but if I use modern features not available to older versions, I will tell you. Note that this book does not pay much attention to Android versions older than 4.1 (API level 16). If you look at the online API documentation, you will find a lot of constructs targeting API levels older than 16. Especially when it comes to support libraries, which were introduced to improve backward compatibility, development gets unnecessarily complicated if you look at API versions older than 16 because the distribution of such devices is less than 1 percent nowadays. This book will just assume you are not interested in such old versions, making it unnecessary to look at such support libraries in many cases and simplifying development considerably. xxvii Chapter 1 System The Android OS was born as the child of the Android Inc. company in 2003 and was later acquired by Google LLC in 2005. The first device running Android came on the market in 2008. Since then it has had numerous updates, with the latest version number at the beginning of 2018 reading 8.1. Ever since its first build, the market share of the Android OS has been constantly increasing, and by 2018 it is said to be greater than 80 percent. Even though the numbers vary with the sources you use, the success of the Android OS is surely undeniable. This victory partly has its roots in Google LLC being a clever player in the worldwide smartphone market, but it also comes from the Android OS carefully being tailored to match the needs of smartphones and other handheld or handheld-like devices. The majority of computer developers formerly or still working in the PC environment would do a bad job utterly disregarding handheld device development, and this book’s goal is to help you as a developer understand the Android OS and master the development of its programs. The book also concentrates on using Kotlin as a language to achieve development demands, but first we will be looking at the Android OS and auxiliary development-related systems to give you an idea about the inner functioning of Android. The Android Operating System Android is based on a specially tailored Linux kernel. This kernel provides all the low-level drivers needed to address the hardware, the program execution environment, and low-level communication channels. On top of the kernel you will find the Android Runtime (ART) and a couple of low-level libraries written in C. The latter serve as a glue between application-related libraries and the kernel. The Android Runtime is the execution engine where Android programs run. You as a developer hardly ever need to know about the details of how these low-level libraries and the Android Runtime do their work, but you will be using them for basic programming tasks such as addressing the audio subsystem or databases. © Peter Späth 2018 P. Späth, Pro Android with Kotlin, https://doi.org/10.1007/978-1-4842-3820-2_1 1 2 CHAPTER 1: System Above the low-level libraries and the Android Runtime sits the application framework, which defines the outer structure of any app you build for Android. It deals with activities, GUI widgets, notifications, resources, and so on. While understanding the low-level libraries certainly helps you to write good programs, knowing the application framework is essential to writing any Android app at all. On top of all that you will find the apps your users launch for tasks they have to accomplish. See Figure 1-1. Figure 1-1. The Android OS CHAPTER 1: System 3 You as a developer will create Android apps using Kotlin, Java, or C++ as a programming language, or a combination of them. And you will be using the application framework and the libraries to talk to the Android OS and the hardware. Using C++ as a programming language on a lower level, addressing target architecture peculiarities, leads to incorporating the Native Development Kit (NDK), which is an optional part of the Android SDK. While for special purposes it might be necessary to use the NDK, in most cases the extra effort to deal with yet another language and the special challenges it bears does not pay off. So in this book, we will be mainly talking about Kotlin, and sometimes Java where appropriate. The Development System The operating system running on handhelds is one part of the story; you as a developer also need a system for creating Android apps. The latter happens on a PC or laptop, and the software suite you use for it is Android Studio. Android Studio is the IDE you use for development, but while you install and operate it, the software development kit (see the section “The SDK”) gets installed as well, and we will be talking about both in the following sections. We will also cover virtual devices, which provide an invaluable aid for testing your app on various target devices. Android Studio The Android Studio IDE is the dedicated development environment for creating and running Android apps. Figure 1-2 shows its main window together with an emulator view. Android Studio provides the following: Managing program sources for Kotlin, Java, and C++ (NDK) Managing program resources The ability to test-run apps inside emulators or connected real devices More testing tools A debugging facility Performance and memory profilers Code inspection Tools for building local or publishable apps 4 CHAPTER 1: System Figure 1-2. Android Studio The help included in the studio and online resources provide enough information to master Android Studio. In this book, we will be talking about it once in a while and in dedicated chapters. Virtual Devices Developing software for computers always included the challenge to create one program that is able to handle all possible target systems. With handheld devices coming in so many different forms nowadays, this aspect has become more critical than ever before. You have smartphone devices with sizes between 3.9” and 5.4” and more, tablets from 7” to 14” and more, wearables, TVs at different sizes, and so on, all running with Android OS. Of course, you as a developer cannot possibly buy all devices that are needed to cover all possible sizes. This is where emulators come in handy. With emulators you don’t have to buy hardware and you still can develop Android apps. Android Studio makes it easy for you to use emulators for developing and testing apps, and using the tools from the software development kit you can even operate the emulators from outside Android Studio. Caution You can develop apps without owning a single real device. This is, however, not recommended. You should have at least one smartphone from the previous generation and maybe also a tablet if you can afford it. The reason is that operating real devices feels different compared to emulators. The physical handling is not 100 percent the same, and the performance differs as well. CHAPTER 1: System 5 To manage virtual devices from inside Android Studio, open the Android Virtual Device Manager via Tools ➤ Android ➤ AVD Manager. From here you can investigate, alter, create, delete, and start virtual devices. See Figure 1-3. Figure 1-3 AVD Manager When creating a new virtual device, you will be able to choose from a TV, wear, phone, or tablet device; you can select the API level to use (and download new API levels); and in the settings you can specify things like this: Graphics performance Camera mode (advanced settings) Network speed (advanced settings) Boot option (advanced settings; quick boot considerably improves bootup speed once the device has been booted for the first time) Number of simulated CPUs (advanced settings) Memory and storage settings (advanced settings) The virtual device base images and skins used for creating virtual images can be found here: SDK_INST/system-images SDK_INST/skins The actual virtual devices with installed apps and user data are in the following location: ~/.android/avd 6 CHAPTER 1: System Caution Virtual devices do not emulate all hardware supported by real devices. Namely, in the first quarter of 2018, the following are not supported: WiFi before API level 25 Bluetooth NFC SD card eject and insert Headphones attached to the device USB You must thus take precautions inside your app for these not to be present if you want to use the emulator. Handling running virtual devices can also be done by various command-line tools; see Chapter 18 for more information. The SDK The software development kit (SDK) is, in contrast to Android Studio, a loosely coupled selection of tools that are either essential for Android development and as such directly used by Android Studio or at least helpful for a couple of development tasks. They can all be started from within a shell and come with or without their own GUI. In case you don’t know where the SDK was installed during the installation of Android Studio, you can easily ask Android Studio: select File ➤ Project Structure ➤ SDK location from the menu. The command-line tools that are part of the SDK are described in Chapter 18. Chapter 2 Application An Android app consists of components such as activities, services, broadcast receivers, and content providers, as shown in Figure 2-1. Activities are for interacting with device users, services are for program parts that run without a dedicated user interface, broadcast receivers listen for standardized messages from other apps and components, and content providers allow other apps and components to access a certain amount and kind of data provided by a component. Figure 2-1. An app in the Android OS Components get started by the Android Runtime, or execution engine if you like, either by itself or on behalf of other components that create start triggers. When a component gets started depends on its type and the meta-information given to it. At the end of the lifecycle, all running components are subject to removal from the process execution list either because they have finished their work or because the Android OS has decided that © Peter Späth 2018 P. Späth, Pro Android with Kotlin, https://doi.org/10.1007/978-1-4842-3820-2_2 7 8 CHAPTER 2: Application a component can be removed because it is no longer needed or that it must be removed because of a device resource shortage. To make your app or component run as stable as possible and give your users a good feeling about its reliability, a deeper knowledge of the lifecycle of Android components is helpful. We will be looking at system characteristics of components and their lifecycles in this chapter. Simple apps and Android components are easy to build; just refer to one of the tutorials on the official Android web site or one of the thousand other tutorials elsewhere on the Web. A simple app is not necessarily a professional-level stable app, though, because Android state handling as far as the app is concerned is not the same as for a desktop application. The reason for this is that your Android device might decide to kill your app to save system resources, especially when you temporarily suspend the app in question because you use one or more other apps for some time. Of course, Android will most likely never kill apps you are currently working with, but you have to take precautions. Any app that was killed by Android can be restarted in a defined data and processing state, including most currently entered data by the user and possibly interfering in the least possible amount with the user’s current workflow. From a file perspective, an Android app is a single zip archive file with the suffix .apk. It contains your complete app including all meta-information, which is necessary to run the app on an Android device. The most important control artifact inside is the file AndroidManifest.xml describing the application and the components an application consists of. We do not in detail cover this archive file structure here, since in most cases Android Studio will be taking care of creating the archive correctly for you, so you usually don’t need to know about its intrinsic functioning. But you can easily look inside. Just open any *.apk file; for example, take a sample app you’ve already built using Android Studio, as shown here: AndroidStudioProject/[YOUR-APP]/release/app-release.apk Figure 2-2. An APK file unzipped Then unzip it. APK files are just normal zip files. You might have to temporarily change the suffix to .zip so your unzip program can recognize it. Figure 2-2 shows an example of an unzipped APK file. CHAPTER 2: Application 9 This .dex file contains the compiled classes in Dalvik Executable format, something that is similar to a JAR file in Java. We will be talking about app-related artifacts shortly, but first we will be looking at the more conceptual idea of what tasks are. Tasks A task is a group of activities interacting with each other in such a way that the end user considers them as the elements of an application. A user starts an app and sees the main activity, does some work there, opens and closes subactivities, maybe switches to another app, comes back, and eventually closes the app. Going a bit more in-depth, the main structure a task exhibits is its back stack, or simply stack, where activities of an app pile up. The standard behavior for simple apps in this stack is that the first activity when you launch an app builds the root of this stack, the next activity launched from inside the app lands on top of it, another subactivity lands on top of both, and so on. Whenever an activity gets closed because you navigate back (that is where the name back stack comes from), the activity gets removed from the stack. When the root activity gets removed, the stack gets closed as a whole, and your app is considered shut down. Inside the <application> element of the AndroidManifest.xml file, in more detail described in section “The Application Declaration” of the online text companion, we can see several settings altering the standard behavior of the task stack, and we will see more in Chapter 3. This way, a tailored task stack can become a powerful means to help your end users to understand and fluently use your app. Keep in mind that a complicated stack behavior might be hard to understand for users beginning to use your app, so it should be your aim to find a good balance between power and ease of use. The Application Manifest An important central app configuration file you can see in any Android app is the file AndroidManifest.xml. It describes the app and declares all the components that are part of the app. The outline of such a manifest file might look like this: <manifest xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http://schemas.android.com/tools" package="de.pspaeth.tinqly"> ... <application android:allowBackup="true" android:icon="@mipmap/my_icon"x android:label="@string/app_name" android:roundIcon="@mipmap/my_round_icon" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity ... /> </application> </manifest> 10 CHAPTER 2: Application The most important attribute of the root entry <manifest> is called package. It declares the ID of your app, and if you plan to publish your app, this must be a worldwide unique ID for it. A good idea is to use your domain (or your company’s domain) reversed and then an unique application identifier, as shown in the previous code. Table 2-1 describes all the possible attributes of <manifest>. Note that for the simplest apps, all you need is the package attribute and a single <application> child. Table 2-1. Manifest Main Attributes Name Description android: installLocation Defines the installation location. Use internalOnly for installing only in the internal storage, auto for letting the OS decide with affinity toward using the internal storage (the user can switch later in the system settings), or preferExternal for letting the OS decide with affinity toward using the external storage. The default is internalOnly. Note that a couple of restrictions apply to using external storage for that aim; see the online documentation for <manifest>. For modern devices with lots of free internal storage, you should never need to specify preferExternal here. package Defines the worldwide unique ID of your app and is a string like abc. def.ghi.[...] where the nondot characters may contain the letters A–Z and a–z, the numbers 0–9, and underscores. Don’t use a number after a dot! This is also the default process name and the default task affinity; see the online text companion to learn what those mean. Note that once your app is published, you cannot change this package name in the Google Play Store. There is no default; you must set this attribute. android: sharedUserId Defines the name of the Android OS user ID assigned to the app. You can prior to Android 8.0 or API level 26 do things such as assigning the same user ID to different apps, which lets them freely interchange data. The apps must then be signed with the same certificate. However, you normally don’t have to set this attribute, but if you set it, make sure you know what you are doing. android: sharedUserLabel If you also set sharedUserId, you can set a user-readable label for the shared user ID here. The value must be a reference to a string resource (for example, @string/myUserLabel). android: targetSandboxVersion Serves as a security level and is either 1 or 2. Starting with Android 8.0 or API level 26, you must set it to 2. With 2, the user ID can no longer be shared between different apps, and the default value for usesClearTextTraffic (see the online text companion) is set to false. android: versionCode Defines an internal version number of your app. This is not shown to users and used only for comparing versions. Use an integer number here. This defaults to undefined. android: versionName Defines a user-visible version string. This is either the string itself or a pointer to a string resource ("@string/..."). This is not used for anything else but informing the user. CHAPTER 2: Application All elements possible as children to the <manifest> element are listed in the section “Manifest Top Level Entries” of the online text companion. The most important one, <application>, describes the application and gets covered in detail in the section “The Application Declaration” of the online text companion. 11 Chapter 3 Activities Activities represent user interface entry points of your app. Any app that needs to interact functionally with the user in a direct way, by letting the user enter things or telling the user graphically about the functional state of an app, will expose at least one activity to the system. I say functionally because telling the user about events can also happen via notifications through toasts or the status bar, for which an activity is not needed. Apps can have zero, one, or more activities, and they get started in one of two ways: The main activity, as declared inside AndroidManifest.xml, gets started by launching the app. This is kind of similar to the main() function of traditional applications. All activities can be configured to be started by an explicit or implicit intent, as configured inside AndroidManifest.xml. Intents are both objects of a class and a new concept in Android. With explicit intents, by triggering an intent, a component specifies that it needs something to be done by a dedicated component of a dedicated app. For implicit intents, the component just tells what needs to be done without specifying which component is supposed to do it. The Android OS or the user decides which app or component is capable of fulfilling such an implicit request. From a user perspective, activities show up as things that can be started from inside an application launcher, be it the standard launcher or a specialized third-party launcher app. As soon as they are running, they show up in a task stack as well, and users will see them when using the Back button. © Peter Späth 2018 P. Späth, Pro Android with Kotlin, https://doi.org/10.1007/978-1-4842-3820-2_3 13 14 CHAPTER 3: Activities Declaring Activities To declare an activity, you can write the following inside AndroidManifest.xml, for example: <?xml version="1.0" encoding="utf-8"?> <manifest ... package="com.example.myapp"> <application ... > <activity android:name=".ExampleActivity" /> ... </application ... > ... </manifest > As shown in this particular example, you can start the name with a dot, which leads to prepending the app’s package name. In this case, the full name of the activity is com.example.myapp.ExampleActivity. Or you can write the full name, as shown here: <?xml version="1.0" encoding="utf-8"?> <manifest ... package="com.example.myapp" ...> <application ... > <activity android:name= "com.example.myapp.ExampleActivity" /> ... </application ... > ... </manifest> All attributes you can add to the <activity> element are listed in the section “Activity Related Manifest Entries” in the online text companion. The following are elements that can be child elements inside the activity element: <intent-filter> This is an intent filter. For details, see the online text companion at “ActivityRelated Manifest Entries”. You can specify zero, one, or many intent filters. <layout> Starting with Android 7.0, you can specify layout attributes in multiwindow modes as follows, where you of course can use your own numbers: <layout android:defaultHeight="500dp" android:defaultWidth="600dp" android:gravity="top|end" android:minHeight="450dp" android:minWidth="300dp" /> The attributes defaultWidth and defaultHeight specify the default dimensions, the attribute gravity specifies the initial placement of the activity in freeform modes, and the attributes minHeight and maxHeight signify minimum dimensions. CHAPTER 3: Activities 15 <meta-data> This is an arbitrary name-value pair in the form <meta-data android:name="..." android:resource="..." android:value="..." />. You can have several of them, and they go into an android.os.Bundle element available as PackageItemInfo.metaData. Caution Writing an app without any activity is possible. The app can still provide services, broadcast receivers, and data content as a content provider. One thing you as an app developer need to bear in mind is that users do not necessarily understand what such components without user interfaces actually do. In most cases, providing a simple main activity just to give information is recommended and improves the user experience. In a corporate environment, though, providing apps without activities is acceptable. Starting Activities Activities can be started in one of two ways. First, if the activity is marked as the launchable main activity of an app, the activity can be started from the app launcher. To declare an activity as a launchable main activity, inside the AndroidManifest.xml file you’d write the following: <activity android:name= "com.example.myapp.ExampleActivity"> <intent-filter> <action android:name= "android.intent.action.MAIN" /> <category android:name= "android.intent.category.LAUNCHER" /> </intent-filter> </activity> android.intent.action.MAIN tells Android that it is the main activity and will go to the bottom of a task, and the android.intent.category.LAUNCHER specifies that it must be listed inside the launcher. Second, an activity can be started by an intent from the same app or any other app. For this to be possible, inside the manifest you declare an intent filter, as shown here: <activity android:name= "com.example.myapp.ExampleActivity"> <intent-filter> <action android:name= "com.example.myapp.ExampleActivity.START_ME" /> <category android:name= "android.intent.category.DEFAULT"/> </intent-filter> </activity> 16 CHAPTER 3: Activities The corresponding code to address this intent filter and actually launch the activity now looks like this: val intent = Intent() intent.action = "com.example.myapp.ExampleActivity.START_ME" startActivity(intent) The flag exported="false" must be set for calls from other apps. The category specification android.intent.category.DEFAULT inside the filter takes care of the activity being launchable even with no category set in the launching code. In the previous example, we used an explicit intent to call an activity. We precisely told Android which activity to call, and we even expect there to be precisely one activity, which gets addressed this way through its intent filter. The other type of intent is called an implicit intent, and what it does, contrary to calling precisely one activity, is tell the system what we actually want to do without specifying which app or which component to use. Such implicit calls, for example, look like this: val intent = Intent(Intent.ACTION_SEND) intent.type = "text/plain" intent.putExtra(Intent.EXTRA_TEXT, "Give me a Quote") startActivity(intent) This snippet calls an activity that is able to handle Intent.ACTION_SEND actions, receive texts in the MIME type text/plain, and pass over the text “Give me a quote.” The Android OS will then present the user with a list of activities from this or other apps that are capable of receiving this kind of intent. Activities can have data associated with them. Just use one of the overloaded putExtra(...) methods of the intent class. Activities and Tasks What actually happens with a launched activity concerning the task stack gets determined by the attributes, listed here, as given in the <activity> element’s attributes: taskAffinity launchMode allowTaskReparenting clearTaskOnLaunch alwaysRetainTaskState finishOnTaskLaunch and by the intent calling flags, listed here: FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_SINGLE_TOP CHAPTER 3: Activities 17 You can specify Intent.flags = Intent.<FLAG>, where <FLAG> is one from the list. In case the activity attributes and caller flags contradict, the caller flags win. Activities Returning Data If you start an activity by using this: startActivityForResult(intent:Intent, requestCode:Int) it means you expect the called activity to give something back while it returns. The construct you use in the called activity reads as follows: val intent = Intent() intent.putExtra(...) intent.putExtra(...) setResult(Activity.RESULT_OK, intent) finish() where inside the .putExtra(...) method calls you can add whatever data is to be returned from the activity. You can, for example, add these lines to the onBackPressed() event handler method. For setResult()’s first argument, you can use any of the following: Activity.RESULT_OK if you want to tell the caller the called activity successfully finished its job. Activity.RESULT_CANCELED if you want to tell the caller the called activity did not successfully finish its job. You still can put extra information via .putExtra(...) to specify what went wrong. Activity.RESULT_FIRST_USER + N, with N being any number from 0, 1, 2, ..., for any custom result code you want to define. There is practically no limit for N (the maximum value reads 231 − 1). Note that you need to take care of also handling back-press events if you have a toolbar. One possibility is to add to the onCreate() method lines as follows: setSupportActionBar(toolbar) supportActionBar!!.setDisplayHomeAsUpEnabled(true) // The navigation button from the toolbar does not // do the same as the BACK button, more precisely // it does not call the onBackPressed() method. // We add a listener to do it ourselves toolbar.setNavigationOnClickListener { onBackPressed() } 18 CHAPTER 3: Activities When the called intent returns the way described earlier, the calling component needs to be informed of that event. This is done asynchronously since the startActivityForResult() method immediately returns and does not wait for the called activity to finish. The way this event gets caught nevertheless is by overriding the onActivityResult() method, as shown here: override fun onActivityResult(requestCode:Int, resultCode:Int, data:Intent) { // do something with 'requestCode' and 'resultCode' // returned data is inside 'data' } requestCode is whatever you set inside startActivityForResult() as requestCode, and resultCode is what you wrote as the first argument in setResult() in the called activity. Caution On some devices, requestCode has its most significant bit set to 1, no matter what was set before. To be on the safe side, you can use the Kotlin construct inside onActivityResult() as follows: val requestCodeFixed = requestCode and 0xFFFF Intent Filters Intents are objects to tell Android that something needs to be done, and they can be explicit by exactly specifying which component needs to be called or implicit if we don’t specify the called component but let Android decide which app and which component can answer the request. In case there is some ambiguity and Android cannot decide which component to call for implicit intents, Android will ask the user. For implicit intents to work, a possible intent receiver needs to declare which intents it is able to receive. For example, an activity might be able to show the contents of a text file, and a caller saying “I need an activity that can show me text files” possibly connects to exactly this activity. Now the way the intent receiver declares its ability to answer intent requests is by specifying one or more intent filters in its app’s AndroidManifest.xml file. The syntax of such a declaration is as follows: <intent-filter android:icon="drawable resource" android:label="string resource" android:priority="integer" > ... </intent-filter> Here, icon points to a drawable resource ID for an icon, and label points to a string resource ID for a label. If unspecified, the icon or label from the parent element will be used. The priority attribute is a number between -999 and 999 and for intents specifies its ability to handle such intent request, and for receivers specifies the execution order for several receivers. Higher priorities come before lower priorities. CHAPTER 3: Activities 19 Caution The priority attribute should be used with caution. A component cannot possibly know what priorities other components from other apps can have. So, you introduce some kind of dependency between apps, which is not intended by design. This <intent-filter> element can be a child of the following: <activity> and <activity-alias> <service> <receiver> So, intents can be used to launch activities and services and to fire broadcast messages. The element must contain children elements as follows: <action> (obligatory) <category> (optional) <data> (optional) Intent Action The <action> child of the filter (or children, because you can have more than one) specifies the action to perform. The syntax is as follows: <action android:name="string" /> This will be something expressing an action such as View, Pick, Edit, Dial, and so on. The complete list of generic actions is specified by constants with names like ACTION_* inside the class android.content.Intent; you can find a list in the section “Intent Constituent Parts” in the online text companion. Besides those generic actions, you can define your own actions. Note Using any of the standard actions does not necessarily mean there is any app on your device that is able to respond to a corresponding intent. Intent Category The <category> child of the filter specifies a category for the filter. The syntax is as follows: <category android:name="string" /> This attribute may be used to specify the type of component that an intent should address. You can specify several categories, but the category is not used for all intents, and you can omit it as well. The filter will match the intent only if all required categories are present. 20 CHAPTER 3: Activities When an intent is used on the invoker side, you can add categories by writing the following, for example: val intent:Intent = Intent(...) intent.addCategory("android.intent.category.ALTERNATIVE") Standard categories correspond to constants with names like CATEGORY_* inside the android.content.Intent class. You can find them listed in the section “Intent Constituent Parts” in the online text companion. Caution For implicit intents, you must use the DEFAULT category inside the filter. This is because the methods startActivity() and startActivityForResult() use this category by default. Intent Data The <data> child of the filter is a data type specification for the filter. The syntax is as follows: <data android:scheme="string" android:host="string" android:port="string" android:path="string" android:pathPattern="string" android:pathPrefix="string" android:mimeType="string" /> You can specify either of the following or both of the following: A data type specified by only the mimeType element, for example, text/ plain or text/html. So, you can write the following: <data android:mimeType="text/html" /> A data type specified by scheme, host, port, and some path specification: <scheme>://<host>:<port>[<path>|<pathPrefix>|<path Pattern>]. Here <path> means the full path, <pathPrefix> is the start of a path, and <pathPattern> is like a path but with wildcards: X* is zero or more occurrences of the character X, and .* is zero or more occurrences of any character. Because of escaping rules, write \\* for an asterisk and \\\\ for a backslash. On the caller side, you can use setType(), setData(), and setDataAndType() to set any data type combination. CHAPTER 3: Activities 21 Caution For implicit intent filters, if the caller specifies a URI data part as in intent.data = <some URI>, it might not be sufficient to specify just the scheme/host/port/path inside the filter declaration. Under these circumstances, you also have to specify the MIME type, as in mimeType="*/*". Otherwise, the filter possibly won’t match. This generally happens in a content provider environment since the content provider’s getType() method gets called for the specified URI and the result gets set as the intent’s MIME type. Intent Extra Data Any intent can have extra data added to it that you can use to send data with it other than specified by the <data> subelement. While you can use one of the various putExtra(...) methods to add any kind of extra data, there are also a couple of standard extra data strings sent by putExtra(String,Bundle). You can find the keys in the section “Intent Constituent Parts” in the online text companion. Intent Flags You can set special intent handling flags by invoking the following: intent.flags = Intent.<FLAG1> or Intent.<FLAG2> or ... Most of these flags specify how the intent gets handled by the Android OS. Specifically, flags of the form FLAG_ACTIVITY_* are aimed at activities called by Context.startActivity(..), and flags like FLAG_RECEIVER_* are for use with Context.sendBroadCast(...). The tables in the section “Intent Constituent Parts” in the online text companion show the details. System Intent Filters The system apps (that is, the apps already installed when you buy a smartphone) have intent filters you can use to call them from your app. Unfortunately, it is not that easy to guess how to call the activities from system apps, and relevant documentation is hard to find. A way out is to extract this information from their APK files. This is done for you for API level 26, and the result is listed in the online text companion in the section “The System Intent Filters.” As an example, suppose you want to send an e-mail. Looking at the system intent table in the online text companion, you can find a lot of actions for PrebuiltGmail. Which one do we use? Well, first a general-purpose interface should not have too many input parameters. Second, we can also look at the action name to find something that seems appropriate. A promising candidate is the SEND_TO action; all that it apparently needs is a mailto: data specification. And as it happens, this is the action we actually need. Using an elaborated mailto:... URL allows us to specify more recipients, CC and BCC recipients, a subject, and even the mail body. However, you can also just use "mailto:master@universe.com" and add recipients, body, and so on, by using extra fields. So to send an e-mail, while possibly letting the user choose among several e-mail apps installed on a device, write the following: val emailIntent:Intent = Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto","abc@gmail.com", null)) 22 CHAPTER 3: Activities emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Subject") emailIntent.putExtra(Intent.EXTRA_TEXT, "Body") startActivity(Intent.createChooser( emailIntent, "Send email...")) // or startActivity(emailIntent) if you want to use // the standard chooser (or none, if there is only // one possible receiver). Caution It is at the receiving app’s discretion how to exactly handle intent URIs and extra data. A poorly designed e-mailer might not allow you to specify e-mail header data at all. To be on the safe side, you may want to add all header data in both the mailto: URI and as extra data. Activities Lifecycle Activities have a lifecycle, and contrary to traditional desktop applications, they are intentionally subject to being killed whenever the Android OS decides to do so. So, you as a developer need to take special precautions to make an app stable. More precisely, an activity finds itself in one of the following states: Shut down: The activity is not visible and not processing anything. Still, the app containing the activity might be alive because it has some other components running. Created: Either the activity is the main activity and was started by the user or some other component or it is an activity regardless of whether it is main activity and it was started by some other component, from inside the same app or another app if security considerations permit it. Also, activity creation happens when you, for example, flip the screen and the app needs to be built up with different screen characteristics. During the creation process, the callback method onCreate() gets called. You must implement this method since there the GUI needs to be built up. You can also use this callback method to start or connect to services or provide content provider data. And you can use the APIs to prepare playing music, operating the camera, or doing anything else the app is made for. This is also a good place to initially set up a database or other data storage your app needs. Started: Once done with the creation (and also in case of a restart after a stop), the activity goes into the started state. Here the activity is about to become visible to the user. During the start process, the callback method onStart() gets called. This is a good place to start broadcast receivers, start services, and rebuild internal state and processes you quit while the activity went to the stopped state. Resumed: Shortly before actually becoming visible to the user, the activity goes through the resuming process. During that process the callback onResume() gets called. Running: The activity is fully visible, and the user can interact with it. This state immediately follows the resuming process. CHAPTER 3: Activities Paused: The activity loses focus but is still at least partly visible. Losing the focus, for example, happens when the user taps the Back or Recents button. The activity may continue to send updates to the UI or continue to produce sound, but in the majority of cases the activity will proceed to the stopped state. During the pausing, the onPause() callback gets called. The paused state is followed by the stopped state or the resumed state. Stopped: The activity is invisible to the user. It later might be restarted, destroyed, and expunged from the active process list. During stopping, the onStop() callback gets called. After stopping, either destruction or starting happens. Here you can, for example, stop the service you started in onStart(). Destroyed: The activity is removed. The callback onDe