logo资料库

The Busy Coder's Guide to Android Development Final Version.pdf

第1页 / 共4293页
第2页 / 共4293页
第3页 / 共4293页
第4页 / 共4293页
第5页 / 共4293页
第6页 / 共4293页
第7页 / 共4293页
第8页 / 共4293页
资料共4293页,剩余部分请下载后查看
Table of Contents
Preface
Welcome to the Book!
First-Generation Book
The Book’s Structure
The Trails
Code Organization and Gradle
Testing
Rx
Advanced UI
Integrated UIs
Security
Data Storage and Retrieval
Advanced Network Topics
Media
Hardware and System Services
Integration and Introspection
Other Tools
Tuning Android Applications
Miscellaneous Topics
Widget Catalog
Device Catalog
Appendices
About the Updates
About the APK Edition
Source Code and Its License
Creative Commons and the Four-to-Free (42F) Guarantee
Acknowledgments
Key Android Concepts
Android Applications
Programming Language
Components
Activities
Services
Content Providers
Broadcast Receivers
Widgets, Containers, and Resources
Apps and Packages
Android Devices
Types
The Emulator
OS Versions and API Levels
Dalvik and ART
Processes and Threads
Don’t Be Scared
Choosing Your Development Toolchain
Android Studio
Eclipse
IntelliJ IDEA
Command-Line Builds via Gradle
Yet Other Alternatives
IDEs… And This Book
What We Are Not Covering
App Inventor
App Generators
Tutorial #1 - Installing the Tools
But First, Some Notes About Android’s Emulator
Step #1: Checking Your Hardware
Step #2: Setting Up Java and 32-Bit Linux Support
Step #3: Install Android Studio
Step #4: Install the SDKs and Add-Ons
Using SDK Manager and Updating Your Environment
In Our Next Episode…
Android and Projects
Projects and Android Studio
Creating a New Project
Copying a Project
Importing a Project
Tutorial #2 - Creating a Stub Project
About Our Tutorial Project
About the Rest of the Tutorials
About Our Tools
Step #1: Importing the Project
Step #2: Get Ready for the x86 Emulator
Windows
Mac
Linux
Step #3: Set Up the AVD
Step #4: Set Up the Device
Windows
Windows Update
Standard Android Driver
Manufacturer-Supplied Driver
macOS and Linux
Step #5: Running the Project
In Our Next Episode…
Getting Around Android Studio
Navigating The Project Explorer
Android Project View
Classic Project View
Context Menus in the Explorer
Opening Files from the Explorer
Running Projects
The Basics
“Instant Run”
Viewing Output
Build View
Logcat
Accessing Android Tools
SDK and AVD Managers
Android Studio and Release Channels
Visit the Trails!
Contents of Android Projects
What You Get, In General
The Modules
The Source Sets
The Manifest
The Java
The Resources
The Build Instructions
More About the Directory Structure
The Root Directory
The App Directory
The Source Sets
What You Get Out Of It
Introducing Gradle and the Manifest
Gradle: The Big Questions
What is Gradle?
What is Groovy?
What Does Android Have To Do with Gradle?
Obtaining Gradle
Direct Installation
Linux Packages
The gradlew Wrapper
Versions of Gradle and the Android Gradle Plugin
Gradle Environment Variables
Examining the Gradle Files
The Project-Level File
buildscript
allprojects
The Module-Level Gradle File
dependencies
android
Introducing the Manifest
Things In Common Between the Manifest and Gradle
Package Name and Application ID
minSdkVersion and targetSdkVersion
Version Code and Version Name
Other Gradle Items of Note
Where’s the GUI?
The Rest of the Manifest
An Application For Your Application
Supporting Multiple Screens
Other Stuff
Learning More About Gradle
Visit the Trails!
Tutorial #3 - Manifest Changes
Some Notes About Relative Paths
Step #1: Supporting Screens
Step #2: Blocking Backups
Step #3: Ignoring Lint
In Our Next Episode…
Some Words About Resources
String Theory
Plain Strings
Um, Wait, My Manifest Does Not Look Like That
Styled Text
CDATA. CDATA Run. Run, DATA, Run.
The Directory Name
Editing String Resources
Multi-Locale Support
Got the Picture?
Some Notes About WebP
Dimensions
Editing Dimension Resources
The Resource That Shall Not Be Named… Yet
Icons
App Icons… And Everything Else
Creating an App Icon with the Asset Studio
Foreground Layer
Background Layer
Legacy
Generating the Icon
Using In Your Manifest
Creating Other Icons with the Asset Studio
Tutorial #4 - Adjusting Our Resources
Step #1: Changing the Name
Step #2: Changing the Icon
Step #3: Running the Result
In Our Next Episode…
The Theory of Widgets
What Are Widgets?
Size, Margins, and Padding
What Are Containers?
The Absolute Positioning Anti-Pattern
The Theme of This Section: Themes
In the Beginning, There Was “Theme”, And It Was Meh
Holo, There!
Considering the Material
Doing More with Themes
The Android User Interface
The Activity
Dissecting the Activity
Using XML-Based Layouts
What Is an XML-Based Layout?
XML Layouts and Your IDE
Why Use XML-Based Layouts?
Using Layouts from Java
Basic Widgets
Common Concepts
Widgets and Attributes
Referencing Widgets By ID
The Curious Case of the Cast
Size
Introducing the Graphical Layout Editor
Palette
Preview
Blueprint
Preview Toolbar
Upper Left Toolbar
Upper Right Toolbar
Component Tree
Attributes
Text Tab
And Now, Some Notes About the Book’s Sample Projects
Assigning Labels
Android Studio Graphical Layout Editor
Editing the Text
Editing the ID
Notable TextView Attributes
A Commanding Button
Android Studio Graphical Layout Editor
Tracking Button Clicks
Fleeting Images
Android Studio Graphical Layout Editor
Scaling Images
Fields of Green. Or Other Colors.
Android Studio Graphical Layout Editor
Notable EditText Attributes
More Common Concepts
Padding
Margins
Colors
Other Useful Attributes
Useful Methods
Visit the Trails!
Debugging Your App
Get Thee To a Stack Trace
Logcat in Android Studio
The Case of the Confounding Class Cast
Point Break
The Classic Container Classes
Introducing the Sampler App
RTL and Your Layouts
LinearLayout and the Box Model
Concepts and Attributes
Orientation
Fill Model
Weight
Gravity
Android Studio Graphical Layout Editor
Example: Bottom-then-Top
The XML
Android Studio Graphical Layout Editor
Example: Stacked-Percent
The XML
Android Studio Graphical Layout Editor
Example: URL Dialog
The XML
Android Studio Graphical Layout Editor
Example: A Bigger Form
The XML
Android Studio Graphical Layout Editor
The Problem
All Things Are Relative
Concepts and Attributes
Positions Relative to Container
Relative Notation in Attributes
Positions Relative to Other Widgets
Android Studio Graphical Layout Editor
Example: Bottom-then-Top
The XML
Android Studio Graphical Layout Editor
Example: URL Dialog
Example: Overlap
Tabula Rasa
Concepts and Attributes
Putting Cells in Rows
Non-Row Children of TableLayout
Stretch, Shrink, and Collapse
Android Studio Graphical Layout Editor
Example: A Bigger Form
Example: URL Dialog
Hey, What About ConstraintLayout?
Turning Back to RTL
Other Common Widgets and Containers
Just a Box to Check
Android Studio Graphical Layout Editor
Don’t Like Checkboxes? How About Toggles or Switches?
Android Studio Graphical Layout Editor
Turn the Radio Up
Android Studio Graphical Layout Editor
Scrollwork
Android Studio Graphical Layout Editor
Making Progress with ProgressBars
Framing the Scene
Visit the Trails!
Tutorial #5 - Creating a Layout
Step #1: Creating a New Layout Resource
Step #2: Defining the UI
In Our Next Episode…
GUI Building, Continued
Making Your Selection
Including Includes
Preview of Coming Attractions
AdapterViews and Adapters
Adapting to the Circumstances
Using ArrayAdapter
Lists of Naughty and Nice
Clicks versus Selections
Choice Modes
Clicks versus Selections, Revisited
Spin Control
Grid Your Lions (Or Something Like That…)
Fields: Now With 35% Less Typing!
Customizing the Adapter
The Single Layout Pattern
Step #0: Get Things Set Up Simply
Step #1: Design Your Row
Step #2: Extend ArrayAdapter
Step #3: Override the Constructor and getView()
Optimizing with the ViewHolder Pattern
Dealing with Multiple Row Layouts
Visit the Trails!
The WebView Widget
Role of WebView
Daddy, Where Do WebViews Come From?
Adding the Widget
Loading Content Via a URL
Links and Redirects
Supporting JavaScript
Alternatives for Loading Content
Listening for Events
Addressing the Link/Redirect Behavior
Opting Out of Google Monitoring
“Anonymous” Metrics
Safe Browsing
Visit the Trails!
Defining and Using Styles
Styles: DIY DRY
Elements of Style
Where to Apply a Style
The Available Attributes
Inheriting a Style
The Possible Values
Themes: Would a Style By Any Other Name…
What Happens If You Have No Theme
Android Studio’s Theme Editor
Dependencies
What’s a Dependency?
Dependency Scopes
Depending on a Local JAR
What’s an Artifact?
Artifacts and Repositories
Major Library Families from Google
Requesting Dependencies
Find What You Need
Configure the Repositories
Identify the Dependencies and Versions
Add the Dependencies
The Android Support Library
What’s In There?
About the Names
About the -v Suffixes
Getting It
Choosing a Version
Attaching It To Your Project
Tutorial #6 - Adding a Library
Step #1: Getting Rid of Existing Cruft
Step #2: Requesting New Dependencies
In Our Next Episode…
Introducing ConstraintLayout
Why Another Container?
Drag-and-Drop GUI Builders
Performance
Comparing with the Classics
Getting ConstraintLayout
Using Widgets and Containers from Libraries
Using a ConstraintLayout
Basic Anchoring, Single Axis
The XML
The Android Studio Graphical Layout Editor
Basic Anchoring, Dual Axis
Playing the Percentages
Converting Existing Layouts
Visit the Trails!
RecyclerView
AdapterView and its Discontents
Enter RecyclerView
A Trivial List
The Dependency
A RecyclerViewActivity
The LayoutManager
The Adapter
The ViewHolder
The Results
What’s Missing?
Divider Options
CardView
Manual
DividerItemDecoration
DIY Decorators
Handling Click Events
Responding to Clicks
Visual Impact of Clicks
Option #1: Translucent Selector on Top
Option #2: Background Selector
Option #3: Controlled Ripple Emanation Point
Visit the Trails!
The Action Bar
Bar Hopping
Android 1.x/2.x
Android 3.0-4.1, Tablets
Android 4.0-4.4, Phones
Android 4.2-4.4, Tablets
Android 5.0+
Yet Another History Lesson
Your Action Bar Options
Pure Native
Backports
A Quick Note About Toasts
Setting the Target
Defining the Resource
A Quick Note About Android Studio
Applying the Resource
Responding to Events
The Rest of the Sample Activity
MENU Key, We Hardly Knew Ye
Action Bars, Live in Living Color!
Material Tint Effects
Color Resources
Tinting a Theme
Applying the Theme
The Results
Restoring the Icon (Sort Of)
Action Bar Style Generator
Designing the Scheme
Implementing the Scheme
Visit the Trails!
Vector Drawables
Getting the Artwork
Android Studio Vector Asset Wizard
Other Tools
Using the Artwork
VectorDrawableCompat
Gradle Configuration
Use in Java
Tutorial #7 - Setting Up the Action Bar
Step #1: Adding Some Icons
Step #2: Defining Some Options
Step #3: Loading and Responding to Our Options
Step #4: Supporting Older Devices
Step #5: Trying It Out
In Our Next Episode…
Android’s Process Model
When Processes Are Created
BACK, HOME, and Your Process
Termination
Foreground Means “I Love You”
You and Your Heap
Activities and Their Lifecycles
Creating Your Second (and Third and…) Activity
Defining the Class and Resources
Populating the Class and Resources
Augmenting the Manifest
Warning! Contains Explicit Intents!
Using Implicit Intents
Where Do We Get These Uri Values?
Extra! Extra!
Pondering Parcelable
Asynchronicity and Results
Schroedinger’s Activity
Life, Death, and Your Activity
onCreate() and onDestroy()
onStart(), onRestart(), and onStop()
onPause() and onResume()
Stick to the Pairs
When Activities Die
Walking Through the Lifecycle
Recycling Activities
Application: Transcending the Activity
The Case of the Invisible Activity
Tutorial #8 - Setting Up An Activity
Step #1: Creating the Stub Activity Class and Manifest Entry
Step #2: Launching Our Activity
In Our Next Episode…
The Tactics of Fragments
The Six Questions
What?
Where??
Who?!?
When?!!?
WHY?!?!?
Screen Sizes
Pages
OMGOMGOMG, HOW?!?!??
Where You Get Your Fragments From
Your First Fragment
The Library
The Fragment Layout
The Fragment Class
The Activity Layout
The Activity Class
The Fragment Lifecycle Methods
onAttach() Versus onAttach()
Your First Dynamic Fragment
The ListFragment Class
The Activity Class
Fragments and the Action Bar
Tutorial #9 - Starting Our Fragments
Step #1: Create a SimpleContentFragment
Step #2: Examining SimpleContentFragment
In Our Next Episode…
Swiping with ViewPager
Pieces of a Pager
Paging Fragments
The Activity Layout
The Activity
The PagerAdapter
The Fragment
The Result
Paging Other Stuff
Indicators
PagerTitleStrip and PagerTabStrip
Other Indicator Options
Revisiting the Containers Sampler
The Layout
The Data
The Fragment
The Activity
The PagerAdapter
Visit the Trails!
Tutorial #10 - Rigging Up a ViewPager
Step #1: Add a ViewPager to the Layout
Step #2: Creating a ContentsAdapter
Step #3: Setting Up the ViewPager
In Our Next Episode…
Resource Sets and Configurations
What’s a Configuration? And How Do They Change?
Configurations and Resource Sets
Screen Size and Orientation
The Original: Android-Defined Buckets
The Modern: Developer-Defined Buckets
Mashups: Width and Height Buckets
About That API Level
Coping with Complexity
Choosing The Right Resource
Scenario #1: Something Simple
Scenario #2: Disparate Resource Set Categories
Scenario #3: Multiple Qualifiers
Scenario #4: Multiple Qualifiers, Revisited
Scenario #5: Screen Density
Scenario #6: Screen Sizes
API-Versioned Resources
Use Case: Themes by API Level
Default Change Behavior
Destroy and Recreate the Activity
Rebuild the Fragments
Recreate the Views
Retain Some Widget State
State Saving Scenarios
Your Options for Configuration Changes
Do Nothing
Retain Your Fragments
Model Fragment
Add to the Bundle
Fragments and a Bundle
onRetainNonConfigurationInstance()
DIY
Blocking Rotations
And Now, a Word From the Android Project View
Configuration Challenges
Multi-Locale Support
Screen Zoom/Dynamic Density
Material Design Basics
Your App, in Technicolor!
Basic Tinting Options
Official Google-Approved Colors
Dealing with Threads
The Main Application Thread
Getting to the Background
Asyncing Feeling
The Theory
AsyncTask, Generics, and Varargs
The Stages of AsyncTask
A Sample Task
The Fragment and its AsyncTask
The Activity and the Results
Threads and Configuration Changes
Where Not to Use AsyncTask
About the AsyncTask Thread Pool
Alternatives to AsyncTask
And Now, The Caveats
Event Buses
What Is an Event Bus?
OK, But Why Are We Bothering With This?
Introducing greenrobot’s EventBus
Requesting the Artifact
Defining Events
Posting Events
Receiving Events
The Activity
Visit the Trails!
Requesting Permissions
Frequently-Asked Questions About Permissions
What Is a Permission?
When Will I Need a Permission?
What Are Some Common Permissions, and What Do They Defend?
How Do I Request a Permission?
When Is the User Informed About These Permissions?
Installing Through SDK Tools
Installing from the Play Store, Android 5.1 and Older
Installing from the Play Store, Android 6.0+
Installing by Other Means, Android 5.1 and Older
Installing by Other Means, Android 6.0+
Characteristics of Permissions
Name
Protection Level
Normal
Dangerous
Permission Group
Maximum SDK Version
Minimum SDK Version
New Permissions in Old Applications
Android 6.0+ Runtime Permission System
What Permissions Are Affected By This?
What Goes in the Manifest?
How Do I Know If I Have Permission?
How Do I Know If the User Takes Permissions Away From Me?
How Do I Ask the User For Permission?
When Do I Ask the User For Permission?
When Do I Not Ask the User For Permission?
What Do I Do If the User Says “No”?
What Do I Do If the User Says “No, And Please Stop Asking”?
What Happens When I Ship This to an Older Device?
What Happens When My App Has a Lower Target SDK Version?
What Happens if the User Clears My App’s Data?
How Can I Automate Permission Grants?
Should I Be Using PermissionChecker?
A Simple Runtime Permission Abstraction
Examining the Protocol
Requesting the Permission
Handling the Result
Dealing with (Configuration) Change
Assets, Files, and Data Parsing
Packaging Files with Your App
Raw Resources
XML Resources
Assets
Files and Android
Internal vs. External
Standard vs. Cache
Yours vs. Somebody Else’s
Working with Internal Storage
Working with External Storage
Where to Write
Relevant Permissions
When to Write
Letting the User See Your Files
Limits on External Storage Open Files
Removable Storage
What You Can Do
What You Can’t Do
The Workarounds
Multiple User Accounts
Linux Filesystems: You Sync, You Win
StrictMode: Avoiding Janky Code
Files, and Your Development Machine
Mounting as a Drive
Browsing Files Via Android Studio
Push and Pull for External Storage
Run-As for Internal Storage
XML Parsing Options
JSON Parsing Options
Using Files with Implicit Intents
Visit the Trails!
Tutorial #11 - Adding Simple Content
Step #1: Adding Some Content
Step #2: Using SimpleContentFragment
Step #3: Launching Our Activities, For Real This Time
Step #4: Getting a Bit More Material
Step #5: Seeing the Results
In Our Next Episode…
Tutorial #12 - Displaying the Book
Step #1: Adding a Book
Step #2: Creating a ModelFragment
Step #3: Defining Our Model
Step #4: Examining Our Model
Step #5: Defining Our Event
Step #6: Loading Our Model
Step #7: Registering for Events
Step #8: Adapting the Content
Step #9: Showing the Content When Loaded
Step #10: Attaching our ModelFragment
Step #11: Showing the Content After a Configuration Change
Step #12: Setting Up StrictMode
In Our Next Episode…
Using Preferences
Getting What You Want
Stating Your Preference
Collecting Preferences with PreferenceFragment
Showing the Current Values
Defining Your Preferences
Creating Your PreferenceFragment
The Results
Android Studio’s Preferences Editor
Types of Preferences
CheckBoxPreference and SwitchPreference
EditTextPreference
RingtonePreference
ListPreference and MultiSelectListPreference
Tutorial #13 - Using Some Preferences
Step #1: Defining the Preference XML Files
Step #2: Creating Our Preference Activity
Step #3: Adding To Our Action Bar
Step #4: Launching the Preference Activity
Step #5: Loading the Preferences
Step #6: Saving the Last-Read Position
Step #7: Restoring the Last-Read Position
Step #8: Keeping the Screen On
In Our Next Episode…
SQLite Databases
Introducing SQLite
Thinking About Schemas
Start with a Helper
Employing Your Helper
Where to Hold a Helper
Getting Data Out
Your Query Options
What Is a Cursor?
Using the Cursor Manually
Introducing CursorAdapter
Getting Data Out, Asynchronously
The Rest of the CRUD
The Primary Option: execSQL()
Alternative Options
Asynchronous CRUD and UI Updates
Setting Transaction Bounds
Hey, What About Hibernate?
But, What About Room?
Visit the Trails!
Tutorial #14 - Saving Notes
Step #1: Adding a DatabaseHelper
Step #2: Examining DatabaseHelper
Step #3: Creating a NoteFragment
Step #4: Examining NoteFragment
Step #5: Creating the NoteActivity
Step #6: Examining NoteActivity
Step #7: Add Notes to the Action Bar
Step #8: Defining a NoteLoadedEvent
Step #9: Loading a Note from the Database
Step #10: Loading the Note Into the Fragment
Step #11: Updating the Database
Step #12: Saving the Note
Step #13: Adding a Delete Action Bar Item
Step #14: Closing the NoteFragment When Deleted
In Our Next Episode…
Internet Access
DIY HTTP
A Sample Usage of HttpUrlConnection
Asking Permission
Creating Your Data Model
A Thread for Loading
A Fragment for Questions
An Activity for Orchestration
What Android Brings to the Table
Testing with StrictMode
What About HttpClient?
HTTP via DownloadManager
Using Third-Party Libraries
SSL
Using HTTP Client Libraries
OkHttp
Retrofit
Dependencies
Creating the Interface
Making the Request
Picasso
Downloading and Installing Picasso
Updating the Model
Requesting the Images
The Rest of the Story
Volley
Getting Volley
Requests and Queues
Making a Manager
Requesting JSON
Requesting Images
Comparison with Retrofit + Picasso
Other Candidate Libraries
Visit the Trails
Intents, Intent Filters
What’s Your Intent?
Pieces of Intents
Intent Routing
Stating Your Intent(ions)
Responding to Implicit Intents
Requesting Implicit Intents
Zero Matches
One Match
Many Matches, Default Behavior
The Chooser Override
Direct Share Targets
ShareActionProvider
Practice Safe Content Resolution
Broadcasts and Broadcast Receivers
Sending a Simple Broadcast
Receiving a Broadcast: In an Activity
Receiving a Broadcast: Via the Manifest
The Stopped State
Getting Out of the Stopped State
Getting Into the Stopped State
Example System Broadcasts
At Boot Time
On Battery State Changes
Sticky Broadcasts and the Battery
Battery and the Emulator
Battery Data on Android 5.0+
The Order of Things
Keeping It Local
Visit the Trails!
Tutorial #15 - Sharing Your Notes
Step #1: Adding a ShareActionProvider
Step #2: Sharing the Note
Step #3: Testing the Result
In Our Next Episode…
Services and the Command Pattern
Why Services?
Setting Up a Service
The Service Class
Lifecycle Methods
Manifest Entry
Communicating To Services
Sending Commands with startService()
Binding to Services
Scenario: The Music Player
The Design
The Service Implementation
Using the Service
The Power of the PendingIntent
What Is a PendingIntent?
How Do We Create One?
How Do We Execute the PendingIntent?
Why Not Just Pass the Intent?
Where Will We Use PendingIntents?
Communicating From Services
Broadcast Intents
Pending Results
Event Buses
Messenger
Notifications
Scenario: The Downloader
The Design
Using the Service
The Service Implementation
Receiving the Broadcast
Limitation: Time
Limitation: Staying Awake
JobIntentService
IntentService or JobIntentService?
Services and Configuration Changes
When Do Services End?
Scenario #1: You Stop It
Scenario #2: Android Terminates Your Process
Scenario #3: The User Nukes You From Orbit
Scenario #4: Automatically, After a Minute
Background Service Limitations
What Is a Background Service, Exactly?
What Happens?
What Are the Alternatives?
Tutorial #16 - Updating the Book
Step #1: Adding a Stub DownloadCheckService
Step #2: Tying the Service Into the Action Bar
Step #3: Defining Our Event
Step #4: Defining Our JSON
Step #5: Defining Our Retrofit Interface
Step #6: Retrieving Our JSON Via Retrofit
Step #7: Downloading the Update
Step #8: Unpacking the Update
Step #9: Using the Update
In Our Next Episode…
Tutorial #17 - Supporting Large Screens
Step #1: Creating Our Layouts
Step #2: Loading Our Sidebar Widgets
Step #3: Opening the Sidebar
Step #4: Loading Content Into the Sidebar
Step #5: Removing Content From the Sidebar
Backwards Compatibility Strategies and Tactics
Think Forwards, Not Backwards
Aim Where You Are Going
A Target-Rich Environment
Lint: It’s Not Just For Belly Buttons
A Little Help From Your Friends
Avoid the New on the Old
Java
@TargetAPI
Resources
Components
Testing
Keeping Track of Changes
System Services
What is a System Service?
What System Services Are There?
Google Play Services
What Is Google Play Services?
…From the Standpoint of Developers?
…From the Standpoint of Users of Google Play Devices?
…From the Standpoint of the Android Ecosystem?
What Is In the Play Services SDK?
Android Pay / Google Wallet
Wear OS
Google+
Google Account Login / Sign In with Google
Google Analytics
Google App Indexing
Google App Invites
Google Cast
Google Cloud Messaging
Google Drive
Google Fit
Google Location Services
Google Maps
Google Mobile Ads / AdMob
Google Mobile Vision
Google Nearby
SafetyNet
Adding Play Services to Your Project
The Metadata
Dealing with Runtime Permissions
Detecting If We Have Permission
Requesting Permissions
Handling the Result
Dealing with Configuration Changes
Checking for Play Services
Initializing the GoogleApiClient
Connecting and Disconnecting
Getting Help
Questions. Sometimes, With Answers.
Heading to the Source
Working with Library Modules
Prerequisites
Creating a Library Module
Using a Library Module
Library Modules and the Manifest
Library Modules and Transitive Dependencies
Limitations of Library Modules
Gradle and Tasks
Key Build-Related Tasks
Results
Gradle Build Variants
Prerequisites
Objectives of the Project Structure
Terminology
Source Sets
Build Types
Product Flavors
Build Variants
Flavor Dimensions
Configuring the Stock Build Types
Source Sets
build.gradle Settings
Order of Precedence
Adding Build Types
Adding Product Flavors and Getting Build Variants
Doing the Splits
Scoping Your Splits
Requesting NDK Splits
Requesting Density Splits
Gradle and Android Studio
The Build Variants View
The Android Project View
Flavors, Build Types, and the Project Structure Dialog
Manifest Merger Rules
Prerequisites
Manifest Scenarios
Library Manifest and App Manifest
App Manifest and Build Types
App Manifest and Product Flavors
Combo Platters
Pieces of Manifest Generation
Merger Rules
Markers and Selectors
Placeholders
Examining the Merger Results
Viewing Merged Manifests in Android Studio
Merging Elements and Attributes
Basic Merger Rules
Example #1: Manifest Attributes
Example #2: Additional Permissions
Example #3: Additional Components
Example #4: Intent Filter
Some Unusual Scenarios
uses-sdk
uses-feature and uses-library
Markers and Selectors
Employing Placeholders
Signing Your App
Prerequisites
Role of Code Signing
What Happens In Debug Mode
Finding Your Debug Keystore
Synchronizing Your Debug Signing Key
Production Signing Keys
Creating a Production Signing Key
Android Studio
Manually
Signing with the Production Key
Android Studio
Gradle
Two Types of Key Security
Distribution
Prerequisites
Get Ready To Go To Market
Versioning
Application ID
Icon and Label
Logging
Testing
EULA
Writing a Gradle Plugin
Prerequisites
Customizing a Gradle Build
Some Use Cases for a Custom Plugin
Code Generation
Resource Generation
Code Analysis
Writing a Plugin
Create a Java Module
Apply the Groovy Plugin
Update the Dependencies
Add a Groovy Source Directory and Package
Implement a Plugin
Using Both Groovy and Java
Adding Plugin Metadata
Distributing the Plugin
Using the Plugin
Dealing with Bugs and Changes
Trying the Sample App
Creating a Real Plugin
Integrating with the Android Plugin
Validating the Environment
Writing a Task Class
Splicing Your Task Into the Build
Configuring the Plugin
Code Generation
Prerequisites
What Drives the Custom Code?
Other Java Code
Other Project Files
Other Data Sources
Java as Poetry
Writing a Code Generation Plugin
Designing the Output
Crafting the Plugin
Writing the Task
Generating Java Code
Using the Generated Code
Advanced Gradle for Android Tips
Prerequisites
Gradle, DRY
It’s build.gradle All The Way Down
gradle.properties
Custom Properties Files
Environment Variables
Automating APK Version Information
Auto-Incrementing the versionCode
Adding to BuildConfig
Testing with JUnit4
Prerequisites
Instrumentation Tests and Unit Tests
Where Your Test Code Lives
Where Your Test Code Runs
Writing JUnit4 Test Cases
The Class
The Test Methods
Setup and Teardown
Testing Activities
Testing Context-Dependent Code
Configuring Gradle
The Test Dependency
The Test Runner
The Test Application ID
Running Your Instrumentation Tests
Android Studio Ad-Hoc Test Runs
Android Studio Run Configuration
Examining the Test Results
Gradle for Android
Testing Android Library Projects
Testing and Runtime Permissions
The Android Test Orchestrator
Testing with Espresso
Prerequisites
Adding a Shot of Espresso
Writing Tests in Espresso
Finding Widgets via Hamcrest Matchers
Performing Actions
Validating via Assertions… And Possibly More Matchers
Stock Assertions
Custom Assertions
The Espresso Test Recorder
Starting and Recording
What You Get
Is This Worthwhile?
Stronger Espresso
Testing AdapterView
Testing RecyclerView
Intent Testing
Testing Activity Re-Creation and Configuration Changes
Opting Out of Analytics
Waiting for the World to Change
What’s an IdlingResource?
Using an IdlingResource
Implementing a Custom IdlingResource
Testing with UI Automator
Prerequisites
What Is UI Automator?
Why Choose UI Automator Over Alternatives?
Gradle and Android Studio Settings
Creating a Test Case
Performing Device-Level Actions
Starting Your Activity
Getting Proxies for Widgets and Containers
UiSelector
UiObject, UiCollection, and UiScrollable
Interacting with Widgets
Asserting Conditions
Running Your Tests
Finding Your Widgets
Using the UI Automator Viewer
Measuring Test Coverage
Prerequisites
Who Tests the Testers?
Some Types of Test Coverage
Statement Coverage
Branch Coverage
Loop Coverage
Coverage and Your Instrumentation Tests
Unit Testing
Prerequisites
I Thought We Were Already Unit Testing?
Scenario: Clean Architecture
Setting Up Unit Testing
Adding the Test JUnit Dependency
Creating the Test Sourceset
Writing POJO Unit Tests
Adding the Test Package
Writing a Test Case
Running Unit Tests
From Android Studio
From the Command Line
Mocking Android
Why Are We Being Mean to Android?
Mockito
Why Mockito?
Setting Up Mockito
Using Mockito in Unit Tests
Robolectric
Setting up Robolectric
Choosing an API Level
Writing Robolectric Tests
Running Robolectric Tests
OK, So, Why Bother?
MonkeyRunner and the Test Monkey
Prerequisites
MonkeyRunner
Writing a MonkeyRunner Script
Executing MonkeyRunner
Monkeying Around
Java 8 Lambda Expressions
Prerequisites
The Basic Idea
Using Lambda Expressions
Enabling Lambda Expressions
Replacing Listeners with Lambdas
Alternative: Method References
Rx Basics
Prerequisites
Life is But a Stream
Action and Reaction
A Rx For What Ails You
Rx and Lambdas
A Simple Stream
Adding the Dependency
Replacing the Loop
Be Your Own Stream
Removing the AsyncTask
subscribeOn()
observeOn()
doOnComplete()
subscribe()
Lambdas and Lifetimes
Streaming from a Resource
Error Handling
Transmogrification
Rx-Enabled Libraries
Further Reading
What About LiveData?
Notifications
Prerequisites
What’s a Notification?
Notifications and Channels
Showing a Simple Notification
The Activity-Or-Notification Scenario
Big (and Rich) Notifications
The Styles
The Builders
The Sample
The Results
Foreground Services
Isn’t “Foreground Service” an Oxymoron?
Putting Your Service in the Foreground
The Malformed Notification
Disabled Notifications
Android 4.x
Android 5.0+
Android 8.0+
Advanced Notifications
Prerequisites
Being a Good Citizen
More About Channels
What You Do with Channels
Creating Channel Groups
Creating Channels
What the User Sees
Once and Done
Backwards Compatibility
Wear? There!
Simple Notification
“Big” Style and Action Button
Foreground Service
Stacking Notifications
…And the Passage of Time
Avoiding Wear
Other Wear-Specific Notification Options
Pages
Wear-Only Actions
Voice Input
The Activity and Notification
The Receiver
The Results
Remote Input, On-Device
Notification Groups
Lockscreen Notifications
Private Notifications
Public Notifications
Secret Notifications
A Visibility Sample
Priority, Importance, and Heads-Up Notifications
Specifying the Priority
Results on Android 5.x Devices
Results on Older Devices
Full-Screen Notifications
Requesting Full-Screen Output
Results on Android 5.0-7.1 Devices
Results on Android 3.0-4.4 Devices
Results on Older Devices
Hey, What About Android 8.0+?
Progress Notifications
The UI
The Downloader Service
Everything but the Icky Parts
The Interceptor
The ProgressResponseBody
Updating the Notification
What If We Had an Activity in the Foreground?
Custom Views
The Notification Layout
Using the Layout
Styling Custom Views
Life After Delete
The Mysterious Case of the Missing Number
Notifications and MessagingStyle
Changes in API Level 23
Sounds and Android 7.0
Auto-Timeout
Launcher Icon Badge
Multi-Window Support
Prerequisites
A History of Windows
What The User Sees
What Your Code Sees
Opting Out
Opting In
Configuring the Layout
Avoiding Stutter
Managing the Background
How Low Can You Go?
Handling the Screen Size Transition
Parallel Processing
Split-Screen, HOME, and Your Activity
Split-Screen and Orientations
Forcing Your App Into Multi-Window/Multi-Instance
Using Sidecar
Choosing the Activity
Implementing the TileService
Forcing Activities to Resize
Breaking the Sidecar
Supporting Legacy Proprietary Multi-Window
Freeform Multi-Window Mode
Playing with Freeform
The Taskbar App
The adb Setting
The Freecar App
Freeform and Your App
Picture-in-Picture
Multi-Display Support
Advanced ConstraintLayout
Prerequisites
Guidelines
Barriers to Entry
Disclosing Your Bias
Centering Yourself
Keeping Things Proportional
Constraining Sizes
…of Children of the ConstraintLayout
…of the ConstraintLayout Itself
Chains, Without the Whips
How Do We Set up a Chain?
Styles of Chains
Spread
Spread-Inside
Packed
Chains and Biases
Chains and Weights
Going in a Circle
Groups of Views… But Not ViewGroups
GridLayout
Prerequisites
Issues with the Classic Containers
Nested Containers
Drag-and-Drop
The New Contender: GridLayout
GridLayout and the Android Support Package
Our Test App
Replacing the Classics
Horizontal LinearLayout
Vertical LinearLayout
TableLayout
Implicit Rows and Columns
Row and Column Spans
Dialogs and DialogFragments
Prerequisites
DatePickerDialog and TimePickerDialog
Changes and Bugs
AlertDialog
DialogFragments
DialogFragment: The Other Flavor
Dialogs: Modal, Not Blocking
Advanced ListViews
Prerequisites
Multiple Row Types, and Self Inflation
Our Data Model and Planned UI
The Basic BaseAdapter
Requesting Multiple Row Types
Creating and Recycling the Rows
Choice Modes and the Activated Style
Custom Mutable Row Contents
From Head To Toe
Enter RecyclerView
Action Modes
Prerequisites
A Matter of Context
Manual Action Modes
Choosing Your Trigger
Starting the Action Mode
Implementing the Action Mode
onCreateActionMode()
onPrepareActionMode()
onActionItemClicked()
onDestroyActionMode()
Multiple-Choice-Modal Action Modes
Long-Click To Initiate an Action Mode
Setting Up the Listeners
Handling the Long Click
Addressing Configuration Changes
Resetting the Choice Mode
The Results
Other Advanced Action Bar Techniques
Prerequisites
Action Layouts
Action Views and Action Providers
Searching with SearchView
SearchView… in the Menu Resource
SearchView… in the Action Bar Configuration
SearchView… And Filtering a ListView
onQueryTextChange()
onQueryTextSubmit()
onClose()
SearchView… From the User’s Perspective
Floating Action Bars
Toolbar
Prerequisites
Basic Toolbar Mechanics
Use Case: Split Action Bar
Enabling Stock Android 4.x Behavior
Adding the Toolbar
Using the Layout
Populating and Using the Toolbar
Results and Changes
Use Case #2: Replacement Action Bar
AppCompat: The Official Action Bar Backport
Prerequisites
Ummmm… Why?
Why an Action Bar Backport?
Why AppCompat?
Supported
Materialistic
Consistent
Forced
The Basics of Using AppCompat
The Library Project
Your Build Settings
Your Theme
Your Menu Resources
Your Activity and Fragments
Your Callback Methods
Your Results
Other AppCompat Effects
Tinting
Switch Backport
Overlay
SearchView
ShareActionProvider
Toolbar and AppCompat
To Material, or Not to Material
The Android Design Support Library
Prerequisites
GUIs and the Support Package
Adding the Library… and What Comes With It
Introducing CWAC-CrossPort
Snackbars: Sweeter than Toasts
Alerts
Action Bars. No, Not Those Action Bars.
CWAC-CrossPort
Absolutely FABulous
FAB Mechanics
Coordinating with Snackbars
CWAC-CrossPort
Third-Party FABs… and FAMs
Material Tabs with TabLayout
CWAC-CrossPort
Floating Labels
Using TextInputLayout
CWAC-CrossPort
Third-Party Floating Labels
Advanced RecyclerView
Prerequisites
What About Cursors?
Grids
A Simple Grid
Choosing the Number of Columns
Varying the Items
A List with Headers
A Grid-Style Table
Mutable Row Contents
Switching to the Activated Style
But, What About Single-Choice?
Keyboard Navigation
Action Modes
Changing the Contents
Updating Existing Contents
Adding and Removing Items
The Order of Things
The Gradle Change
The RecyclerViewFragment
The SortedFragment
The SortedList
The IconicAdapter
The SortedList.Callback
The AsyncTask
The Results
Other Bits of Goodness
Animating the Deltas
Model
The Menu
The Diff-ing
The SimpleCallback
ListAdapter. No, Not That ListAdapter.
The Callback
The Adapter
The Rx Stuff
Expandable Rows
RecyclerView as Pager
Using RecyclerViewPager
Adding the Dependency
Using the Widget
Populating the Pages
Dealing with Recycling
Dealing with Configuration Changes
Using SnapHelper
Adding Tabs
Declaring a LayoutManager in the Layout
Transcript Mode
Advanced Uses of WebView
Prerequisites
Friends with Benefits
JavaScript Calling Java: addJavascriptInterface()
Java Calling JavaScript: loadUrl() and evaluateJavascript()
Java Calling JavaScript: WebMessage
JavaScript Calling Java: WebMessagePort
Navigating the Waters
Settings, Preferences, and Options (Oh, My!)
Security and Your WebView
Rogue JavaScript Risks
The addJavascriptInterface() Bugs
The Same-Origin Policy Bug
Android 8.0 WebView Changes
Multi-Process Mode
Honors Cleartext Traffic Setting
Chrome Custom Tabs
The Input Method Framework
Prerequisites
Keyboards, Hard and Soft
Tailored To Your Needs
Tell Android Where It Can Go
Fitting In
Jane, Stop This Crazy Thing!
Fonts and Text
Prerequisites
Love The One You’re With
Yeah, But Do We Really Have To Do This in Java?
Here a Glyph, There a Glyph
Auto-Sizing TextView
Justified Text
Rich Text
Prerequisites
The Span Concept
Implementations
TextView and Spanned
Available Spans
Loading Rich Text
String Resource
HTML
From EditText
Manually
Editing Rich Text
Saving Rich Text
Manipulating Rich Text
Animators
Prerequisites
ViewPropertyAnimator
Native Implementation
Backport Via NineOldAndroids
The Foundation: Value and Object Animators
Animating Custom Types
Hardware Acceleration
The Three-Fragment Problem
The ThreePaneLayout
Using the ThreePaneLayout
The Results
The Backport
The Problems
Legacy Animations
Prerequisites
It’s Not Just For Toons Anymore
A Quirky Translation
Mechanics of Translation
Imagining a Sliding Panel
The Aftermath
Introducing SlidingPanel
Using the Animation
Fading To Black. Or Some Other Color.
Alpha Numbers
Animations in XML
Using XML Animations
When It’s All Said And Done
Loose Fill
Hit The Accelerator
Animate. Set. Match.
Active Animations
Custom Drawables
Prerequisites
Where Do These Things Go?
nodpi: Fallback
anydpi: Takeover
No Qualifier: Just Say “WTF?”
ColorDrawable
AnimationDrawable
Animated GIF Conversion
StateListDrawable
ColorStateList
LayerDrawable
TransitionDrawable
LevelListDrawable
ScaleDrawable and ClipDrawable
Scaling
Clipping
Seeing It In Action
InsetDrawable
ShapeDrawable
and
Put a Ring On It
BitmapDrawable
Composite Drawables
A Stitch In Time Saves Nine
The Name and the Border
Padding and the Box
Stretch Zones
Tooling
Using Nine-Patch Images
Mapping with Maps V2
Prerequisites
A Brief History of Mapping on Android
Where You Can Use Maps V2
Licensing Terms for Maps V2
What You Need to Start
Your Signing Key Fingerprint(s)
Your Google Account
Your API Key
The Play Services Library
The Book Samples… And You!
Setting Up a Basic Map
The Dependency
The Project Setup and the Manifest
The Play Services Detection
The Fragment and Activity
The Result
Playing with the Map
Map Tiles
Placing Simple Markers
Seeing All the Markers
Flattening and Rotating Markers
Sprucing Up Your “Info Windows”
Images and Your Info Window
Setting the Marker Icon
Responding to Taps
Dragging Markers
The “Final” Limitations
A Bit More About IPC
Finding the User
Dealing with the Runtime Permission
Tracking If We Should Follow the User
Showing the My-Location Layer
Supplying Location Data
Drawing Lines and Areas
Gestures and Controls
Tracking Camera Changes
Maps in Fragments and Pagers
Animating Marker Movement
Problem #1: Animating a LatLng
Problem #2: The Earth Is Not Flat (Really!)
Problem #3: 180 Equals –180, At Least For Longitude
Introducing Some Googly Assistance
Seeing This in Action
Honoring Traffic Rules, Like “Drive Only On Streets”
Maps, of the Indoor Variety
Taking a Snapshot of a Map
SupportMapFragment vs. MapView
About That AbstractMapActivity Class…
Helper Libraries for Maps V2
Problems with Maps V2 at Runtime
Problems with Maps V2 Deployment
What Non-Compliant Devices Show
Mapping Alternatives
Crafting Your Own Views
Prerequisites
Pick Your Poison
Colors, Mixed How You Like Them
The Layout
The Attributes
The Class
Constructor Flavors
Using the Attributes
Saving the State
The Rest of the Functionality
Seeing It In Use
ReverseChronometer: Simply a Custom Subclass
AspectLockedFrameLayout: A Custom Container
Mirror and MirroringFrameLayout: Draw It Yourself
MirroringFrameLayout
Mirror
Usage and Results
Limitations
Advanced Preferences
Prerequisites
Introducing PreferenceActivity
Defining Your Preference Headers
Creating Your PreferenceActivity
The Results
Intents for Headers or Preferences
Conditional Headers
Option #1: Do Not Define the Headers
Option #2: Go Directly to the Fragment
Dependent Preferences
Nested Screens
Listening to Preference Changes
Defaults, and Defaults
Listening to Preference Value Changes
Dynamic ListPreference Contents
Dealing with External Changes to Preferences
Preferences in Device Settings App
Custom Preference Storage
Custom Dialogs and Preferences
Prerequisites
Your Dialog, Chocolate-Covered
Basic AlertDialog Setup
Handling Color Changes
State Management
Preferring Your Own Preferences, Preferably
The Constructor
Creating the View
Dealing with Preference Values
Getting the Default Value
Setting the Initial Value
Closing the Dialog
Using the Preference
Progress Indicators
Prerequisites
Progress Bars
Circular vs. Horizontal
Specific vs. Indeterminate
Primary vs. Secondary
ProgressBar and Threads
Tailoring Progress Bars
Changing the Progress Colors
Changing the Indeterminate Animation
Progress Dialogs
Title Bar and Action Bar Progress Indicators
Direct Progress Indication
More Fun with Pagers
Prerequisites
Hosting ViewPager in a Fragment
Pages and the Action Bar
ViewPagers and Scrollable Contents
Showing More Pages
Columns or Pages
The Grid Pattern
Columns for Large, Pages for Small
The Layouts
The Activity
The Results
The Limitations
Focus Management and Accessibility
Prerequisites
Prepping for Testing
Controlling the Focus
Establishing Focus
Requesting (or Abandoning) Focus
Focus Ordering
Scrolling and Focusing Do Not Mix
Accessibility and Focus
Accessibility Beyond Focus
Content Descriptions
Labels
Custom Widgets and Accessibility Events
Announcing Events
Font Selection and Size
Widget Size
Gestures and Taps
Enhanced Keyboard Support
Audio and Haptics
Color and Color Blindness
Accessibility Beyond Impairment
Miscellaneous UI Tricks
Prerequisites
Full-Screen and Lights-Out Modes
Android 1.x/2.x
Android 4.0+
Offering a Delayed Timeout
Event Bus Alternatives
Prerequisites
A Brief Note About the Sample Apps
Standard Intents as Event Bus
LocalBroadcastManager as Event Bus
A Simple LocalBroadcastManager Sample
A More Elaborate Sample
The Activity
The PollReceiver
ScheduledService and Sending Events
EventLogFragment and Receiving Events
Reference, Not Value
Limitations of Local
greenrobot’s EventBus 3.x
Basic Usage and Sample App
ScheduledService and Sending Events
EventLogFragment and Receiving Events
Handling the “Nobody’s Home” Scenario
Other Notable Capabilities
Hey, What About Otto?
Tasks
Prerequisites
First, Some Terminology
Task
Back Stack
Recent Tasks
Overview Screen
Android 1.x/2.x
Android 3.x/4.x
Android 5.x
Running Tasks
And Now, a Bit About Task Killers
What Do Task Killers Do?
Killing vs. Force-Stopping
Why Use One?
A Canary for the Task’s Coal Mine
The Default User Experience
Starting from the Home Screen
Resuming from the Overview Screen
Starting Another App
Explaining the Default Behavior
When Tasks are Created
Task-Management Intent Flags
Task Affinities
When Tasks are Removed
When Tasks (and Processes) are Resumed
What Happens to Services
What’s Up with onDestroy()?
Basic Scenarios for Changing the Behavior
Reusing an Activity
Forcing a Clean Task
Starting a Cleared Task Yourself
Always Starting a Cleared Task
Launching an App Into a New Task
The Invisible Activity
Reparenting Tasks
The Self-Destructing Activity
The Hidden Task
Dealing with the Persistent Tasks
The State of Your State
Where You Return To
Documents As Tasks
When You Should Do This
Adding a Document
android:documentLaunchMode
FLAG_ACTIVITY_NEW_DOCUMENT
Capping the Number of Documents
Removing and Retaining Documents
Other Task-Related Activity Properties
launchMode
singleTop
singleTask
singleInstance
alwaysRetainTaskState
Other Task-Related Activity Methods
finishAffinity()
finishAndRemoveTask()
getTaskId()
isTaskRoot()
moveTaskToBack()
setTaskDescription()
The Assist API (“Now On Tap”)
Prerequisites
What Data Gets Disclosed
Screenshot
View Structure
Other Data
Adding to the Data
Accessibility
Assist-Specific Data
Globally
Per-Activity
Per-View
Removing from the Data
FLAG_SECURE
Password Fields
NoAssistFrameLayout
Blocking Assist as a User
Implementing Your Own Assistant
A Stub VoiceInteractionService
A Trivial VoiceInteractionSessionService
The VoiceInteractionSession
Basic Setup
onHandleScreenshot()
onHandleAssist()
Making a Real Assistant
Determining the Active Assistant
Leading the User to Make an Assistant Change
The Autofill API
Prerequisites
The Pieces of the Puzzle
The User Experience
While Completing a Form
After Completing a Form
What Data Gets Disclosed
Blocking Autofill as a User
Supporting Autofill with Standard Widgets
Identifying Roles via Hints
Indicating Importance
Supporting Autofill with Custom Widgets
Dealing with Dynamic Changes
Security Requirements of Autofill Services
First, the Flaw
Google’s Response
What Secure Autofill Services Need To Do
Partition the Dataset
Only Give Data Back to the App That Supplied It
Hint to the User What Data Is Being Autofilled In
What Google’s Advice Does Not Solve
The Data Binding Framework
Prerequisites
The What, Now?
The Basic Steps
Setting Up the Toolchain
Augmenting the Layout… and the Model
Applying the Binding
Creating the Binding
Pouring the Model into the Binding
Retrieving Widgets from the Binding
Getting the Actual View
Results
The Extended Layout Resource
Imports and Statics
Variables
The Binding Expression Language
Stuff You Won’t Find in Java
Caveats
Handling String Literals
Watch Out For Mis-Interpreted Integers
Other Caveats
Observables and Updating the Binding
Observable Primitives
ObservableField
ObservableArrayList and ObservableArrayMap
Custom Observables
An Observable Example
The Limitations of Earlier Examples
Questions vs. Items
Keeping Score (and the ID)
Refreshing the Data
Two-Way Binding
Other Features of Note
Obtaining Views via the Binding Class
Manipulating Variables in the Binding
Views, Setters, and Binding
Synthetic Properties
Using Different Methods
BindingAdapters, and the Picasso Scenario
Two-Way Binding and InverseBindingAdapter
Event Handling
Thinking Back to android:onClick
Tying Events to Methods Directly
Tying Events to Methods via Lambda Expressions
Converting to a RecyclerView/CardView UI
What About the Event Listeners?
Type Converters
Chained Expressions
Custom Binding Class Names
Extended Include Syntax
Custom Observables
Bindable Properties
Notifying About Intrinsic Changes
Thinking Outside the Box
Drag and Drop
Prerequisites
The Scope of Drag and Drop
What Are We Dragging and Dropping?
Where Are We Dragging From?
Where Are We Dropping To?
The Pieces of Drag-and-Drop
The Drag Shadow
…From a View
…From a Canvas
The Drag Event Listener
The Drag Events
ACTION_DRAG_STARTED
ACTION_DRAG_ENTERED
ACTION_DRAG_LOCATION
ACTION_DRAG_EXITED
ACTION_DROP
ACTION_DRAG_ENDED
Drag-and-Drop, within an Activity
The Landscape Layout
Registering as Drop Targets
Starting to Drag
Reacting to Drag Events
The Result
The Android 9.0 Bug
Drag-and-Drop, Between Apps
The Drag App
The Custom Shadow
The StreamProvider
The Drag Request
The Drop App
The Layout
The Drag Event
The Results
Detecting Cross-App Drag Events
Intra-App Cross-Window Drag-and-Drop
Pondering Legacy Multi-Window
Dragging and Dropping Simple Stuff
Multi-Action Drag-and-Drop
The Layout
Showing and Hiding the Action
Handling Drag Events
The Result
Nested Drop Targets
The Behavior Prior to Android 7.0
Android 7.0 Behavior
Getting Inclusive on Android 7.0
The State of the Bugs
Pondering Standards
Pondering Accessibility
Keyboard and Mouse Input
Prerequisites
Offering Keyboard Shortcuts
Action Bar Item Shortcuts
Arbitrary Hotkeys
Android 7.0 Keyboard Shortcuts Helper
Custom Copy-and-Paste
Physical Keyboards and Focusing
The Problem
A requestFocus BindingAdapter
Using the BindingAdapter
Offering Mouse Context Menus
Offering Tooltips
Android 7.1 and Older
Hover Events
Detecting a Long-Enough Hover
What We Are Missing
Android 8.0+
Pointer Capture
Viewing PDFs
Prerequisites
The Criteria
Where is the PDF?
Does It Work Offline?
How Complex is the PDF?
How Stable is the Solution?
How Private is the PDF?
The Classic Solution: ACTION_VIEW
The Really Bad Idea: Google Docs
The Built-In Option: PdfRenderer
The RecyclerView
Getting the PDF
Adding the PdfRenderer
Showing the Pages
The Thunder Lizard Choice: PDF.js
The Native Approach: Pdfium
What To Choose?
Home Screen App Widgets
Prerequisites
App Widgets and Security
The Big Picture for a Small App Widget
Crafting App Widgets
The Manifest
The uses-feature Element
The Metadata
The Layout
The BroadcastReceiver
The Result
Another and Another
App Widgets: Their Life and Times
Controlling Your (App Widget’s) Destiny
One Size May Not Fit All
Android 1.x/2.x
Android 3.0+
Lockscreen Widgets
Preview Images
Being a Good Host
Adapter-Based App Widgets
Prerequisites
AdapterViews for App Widgets
Building Adapter-Based App Widgets
The AppWidgetProvider
The RemoteViewsService
The RemoteViewsFactory
The Rest of the Story
The Results
Publishing Slices
What’s a Slice?
What Slices Contain
Where Slices Get Used
A Tale of Two Slices
Slice Sizes
Setting Up a Slice
The Gradle Settings
The SliceProvider
The Manifest Entry
The Activity That You Didn’t Write
Binding a Slice
Trying a Slice
Installing the Slice Viewer
Running Your Slice in the Viewer
The User Flow
The SliceAction
The Slice Item Templates
Simple Rows
Headers
Range Rows and Input Range Rows
Grid Rows
Hey, What About…?
Actions and Sizes
Shortcut Mode
Small and Large Modes
Asynchronous Slices
Dealing with No Data
Loading the Data
Using the Data
Warning: Make No Rendering Assumptions
Other Slice Viewer Features
Hosting Slices
What You Need to Know
Why?
How?
The Simple Way: SliceView
The Fully-Custom Way: Slice
The Catch: Discovering Slices
Slices… from the Web?
Advanced Permissions
Prerequisites
Securing Yourself
Enforcing Permissions via the Manifest
Enforcing Permissions Elsewhere
Requiring Standard System Permissions
Signature Permissions
Firmware-Only Permissions
Your Own Signature Permissions
The Custom Permission Vulnerability
Scenarios
The Application SDK Case (A, Then C)
The Application SDK Problem Case (C, Then A)
The Peer Apps Case, Part One (A, Then B)
The Peer Apps Case, Part Two (B, Then A)
The Downgraded-Level Malware Case (B, Then A, Again)
The Peer Apps Case With a Side Order of C
Behavior Analysis
Risk Assessment
Android 5.0’s “Fix”
Mitigation Using PermissionUtils
Custom Dangerous Permissions, and Android 6.0
Finding the Available Permissions
Restricted Profiles and UserManager
Prerequisites
Android Tablets and Multiple User Accounts
Primary User
Secondary User
Restricted Profile
Determining What the User Can Do
Impacts of Device-Level Restrictions
Restricting Location Access
Uninstalling Apps
Enabling Custom Restrictions
Stating Your Restrictions
Option #1: RestrictionEntry List
Option #2: Custom Restriction Activity
What the Primary User Sees
Finding Out the Current Restrictions
Implicit Intents May Go “Boom”
Device Authentication
Prerequisites
Is the Device Secure?
The DevicePolicyManager Approach
The KeyguardManager Approach
Reconfirming the User
Fingerprints
Authenticating the User
Via KeyguardManager
Using RxFingerprint
Directly
Encrypting Data Using Fingerprints and Libraries
RxFingerprint
Whorlwind
OK, So What Was That All About?
Limitations of Fingerprint-Based Encryption
Keys and the Keystore
Prerequisites
Terminology
Keys
KeyStore
KeyChain
Getting a KeyStore
Creating a Key
Tying the Key to Device Authentication
Learning More About Your Key
Encrypting Data
Introducing RxKeyBodega
Encrypting the Note
RxKeyBodega Client
RxKeyBodega Implementation
Some Quick Initialization Vector Notes
Escaping If Device Is Insecure
Starting Decryption in onCreate()
Decrypting the Note
RxKeyBodega Client
RxKeyBodega Implementation
Time-Limited Device Authentication
Encrypting Passphrases
A NoteRepository
RxPassphrase
Using the NoteRepository and RxPassphrase
A Key(Store) Limitation
Miscellaneous Security Techniques
Prerequisites
Public Key Validation
Scenarios
Checking Yourself
Checking Arbitrary Other Apps
The Easy Solution: SignatureUtils
Examining Public Keys
The UI Structure
Listing the Packages
Decoding the Key
Dumping the Key
The Result
Choosing Your Signing Keysize
Avoiding Accidental APIs
Export Only What’s Necessary
Export Defaults
The Chooser Bug
The ContentProvider Behavior Change
Sanitize Your Input Extras
Secure Your Output Extras
Other Ways to Expose Data
App Widgets
Notifications
Clipboard
ServerSocket and Kin
Jacking Attacks
Classic Tapjacking
The Problem
How to Address This
Activity Jacking
The Problem
How to Address This
Window Jacking
The Problem
How to Address This
The Problem with the Solution
Google’s Line of Defense: Obscuring the Foreground
Using FLAG_SECURE
Content Provider Theory
Prerequisites
Using a Content Provider
Pieces of a Uri
Getting a Handle
The Database-Style API
Makin’ Queries
Adapting to the Circumstances
Give and Take
The Streaming API
Working with the Stream
Retrieving Metadata
The DATA Anti-Pattern
Building Content Providers
First, Some Dissection
Next, Some Typing
Implementing the Database-Style API
Implement onCreate()
Implement query()
Implement insert()
Implement update()
Implement delete()
Implement getType()
Update the Manifest
Add Notify-On-Change Support
Implementing the Streaming API
Serving the Stream
Serving the Metadata
The Rest of the Requirements
Issues with Content Providers
Content Provider Implementation Patterns
Prerequisites
The Single-Table Database-Backed Content Provider
Step #1: Create a Provider Class
onCreate()
query()
insert()
update()
delete()
getType()
Step #2: Supply a Uri
Step #3: Declare the “Columns”
Step #4: Update the Manifest
The Local-File Content Provider
The FileProvider Class
onCreate()
openFile()
getDataLength()
The AbstractFileProvider Class
getType()
insert(), update(), and delete()
query() and getFileName()
copy()
The Manifest
Using this Provider
The Protected Provider
Step #1: Mark the Provider as Not Exported
Step #2: Grant Access to the Uri
The Stream Provider
The Pipes
The Revised openFile()
The Transfer
The Results
FileProvider
The Rationale
The Sources of Files
The Manifest Entry
The Legacy Compatibility
The Usage
StreamProvider
Exporting and Usage Patterns
Metadata Elements
Assets and Gradle
I Can Haz Uri?
Uri Prefixes
Extending StreamProvider
Customizing the Uri Prefix
Supporting Other Stream Locations
Supporting Other Stream Strategies
Adding Columns to query()
Totally Overhauling Uri Handling
Overriding Standard Methods
Adding Support for insert() and update()
The Loader Framework
Prerequisites
Introducing the Loader Framework
LoaderManager
LoaderCallbacks
Loader
Using CursorLoader
What Else Is Missing?
What Happens When…?
… the Data Behind the Loader Changes?
… the Configuration Changes?
… the Activity is Destroyed?
Writing a Custom Loader
Changing the Retrofit Interface
Implementing QuestionsLoader
The Constructor
Loading the Questions
Delivering Results
Starting, Stopping, and Resetting
Using QuestionsLoader
Considering the Loader Contract
The ContactsContract and CallLog Providers
Prerequisites
Introducing You to Your Contacts
Organizational Structure
A Look Back at Android 1.6
Pick a Peck of Pickled People
Picking a Contact
Viewing a Contact
Spin Through Your Contacts
Contact Permissions
Pre-Joined Data
The UI
Reacting to the Spinner
Loading the Data
Showing the Results
Makin’ Contacts
Looking at the CallLog
Pondering Permissions
Contents of CallLog.Calls
Showing the CallLog
The CalendarContract Provider
Prerequisites
You Can’t Be a Faker
Do You Have Room on Your Calendar?
Calendar Permissions
Querying for Events
The Permission
The CursorLoader
The RecyclerView
The Results
Penciling In an Event
The MediaStore Provider
Prerequisites
What Is the MediaStore?
Indexed Media
Indexed Non-Media
MediaStore and “Other” External Storage
How Does My Content Get Indexed?
How Do I Retrieve Video from the MediaStore?
Requesting Permission
Querying for Video
Showing the Thumbnails
Playing the Selection
The Results
Consuming Documents
Prerequisites
The Storage Access… What?
The Storage Access Framework Participants
Picking How to Pick (a Peck of Pickled Pepper Photos)
Opening a Document
Why We Want Things To Be Openable
The Rest of the CRUD
Create
Update
Delete
The DocumentFile Helper
CWAC-Document and DocumentFileCompat
Getting Durable Access
Another Durable Example: Diceware
Dice? Where?!?
We Want Words!
The Results
How We Got There
Loading Our Words
Getting More Words
Other Fiddly Bits
Document Trees
Getting a Tree
Working in the Tree
Getting a Tree: Example
The Objective: a Preference for Storage
What the User Sees
The Document Tree
The Preference XML
Populating the Preference
Choosing a Tree
The Storage Volume
The Preference XML
Populating the Preference
Choosing a Volume
Potential Issues
Scoped Directory Access Bug
Android 8.0 Changes
Document Tree Traversal
Web Links for Documents
Document Settings Activity
Providing Documents
Prerequisites
Have Your Content, and Provide it Too
Key Provider Concepts
Roots
Documents
Root and Document IDs
Pieces of a Provider
The Activity
The API Level Resources
The Manifest
The DocumentsProvider
onCreate()
queryRoots()
queryChildDocuments()
queryDocument()
openDocument()
The Results
Optional Provider Capabilities
Other CRUD Operations
Create
Update
Delete
Change Notification
Thumbnails
Recent Documents
Search
Other Flags
Encrypted Storage
Prerequisites
Scenarios for Encryption
Obtaining SQLCipher
Using SQLCipher
SQLCipher Limitations
Passwords and Sessions
About Those Passphrases…
Upgrading to Encryption
Changing Encryption Passphrases
Dealing with the Version 3.0.x Upgrade
Multi-Factor Authentication
Detecting Failed Logins
SQLCipher for Android and Performance
Encrypted Preferences
Encryption via Custom SharedPreferences
Encryption via Custom Preference UI and Accessors
IOCipher
Packaging and Distributing Data
Prerequisites
Packing a Database To Go
Create and Pack the Database
Unpack the Database, With a Little Help(er)
Upgrading Sans Java
Limitations
Advanced Database Techniques
Prerequisites
Full-Text Indexing
First, a Word About SQLite Versions
FTS3 and FTS4
Creating a Full-Text Indexed Table
Populating a Full-Text Indexed Table
Querying a Full-Text Indexed Table
Some Notes About the Rest of the Sample App
Adding a ModelFragment
Adding a SearchView
The Results
Getting Snippets
Data Backup
Prerequisites
First, Some Terminology
Differing Definitions of “Backup”
What Google Thinks “Backup” Means
What IT Thinks “Backup” Means
What Your Legal Counsel Thinks “Backup” Means
Implementing IT-Style Backup
Choosing the Backup Scope
Choosing a Backup Trigger
Generating the Dataset
Transmitting the Dataset
Initiating a Restore
Starting the Restore Activity
Downloading and Restoring the Dataset
Trying This Yourself… With a Little Help from Ol’ Blue Eyes
The Google Backup Bootstrap
What to Bootstrap?
Bootstrap Backup on Android 6.0+
Configuring the Backup
Testing the Backup and Restore Steps
Bootstrap Backup on Android 2.2-5.1
Boosting Backup Security
Securing Access to the Dataset
Securing Transmission of the Dataset
Encrypting the Dataset
Alternative Approaches
Data Versioning
Import and Export
Data Synchronization
SSL
Prerequisites
Basic SSL Operation
Problems in Paradise
Self-Signed Certificate
Wildcard Certificate
Custom Certificate Authority
Man in the Middle Attacks
Disabling SSL Certificate Validation
Ignoring Domain Names
Hacked CAs
Introducing Network Security Configuration
The Native Android 7.0 Version
The CWAC-NetSecurity Backport
SSL Problems and Network Security Configuration
Pinning the Certificate Authority
Unusual Certificate Authorities
Pinning the Certificate
Self-Signed Certificates
Self-Signed Certificates for Debug Builds
Blocking Cleartext Traffic
Supporting User-Added Certificates
Other SSL Strengthening Techniques
Certificate Memorizing
Requiring Encryption, Android 6.0 Style
Watching for Encryption
Advanced Uses of CWAC-NetSecurity
Using Alternative Network Security Configuration XML
Using the Backport Directly
Integrating with Other HTTP Client Libraries
Adding the TrustManager
Handling Cleartext
Handling Redirects
Debugging Certificate Chains
NetCipher
NetCipher
Prerequisites
Network Security’s Got Onions
A Quick Primer on Tor
Introducing Orbot
What NetCipher Provides
The NetCipher HTTP Integration APIs
Choose an HTTP Stack
Add the Dependencies
Set up OrbotHelper
Choose and Create a Builder
Get a Connection
Seeing the Builder in Action
The Rest of the Builder API
Common Configuration Methods
Differences Between the Stacks
StrongConnectionBuilder
StrongHttpClientBuilder
StrongVolleyQueueBuilder
StrongOkHttpClientBuilder
Miscellaneous Network Topics
Prerequisites
Downloading Files
The Permissions
The Layout
Requesting the Download
Keeping Track of Download Status
Download Broadcasts
What the User Sees
Limitations
Data Saver
Audio Playback
Prerequisites
Get Your Media On
MediaPlayer for Audio
Other Ways to Make Noise
SoundPool
AudioTrack
ToneGenerator
Audio Recording
Prerequisites
Recording by Intent
Recording to Files
Recording to Streams
Setting Up the Stream
Changes in Recording Configuration
Raw Audio Input
Requesting the Microphone
Video Playback
Prerequisites
Moving Pictures
Using the Camera via 3rd-Party Apps
Prerequisites
Being Specific About Features
Still Photos: Letting the Camera App Do It
Setting the Theme
Requesting the Feature
Adding the FileProvider
Taking a Picture
Saving the State
Viewing the Photo
The Caveats
Permissions and Third-Party Camera Apps
A Matter of Orientation
EXIF Tags
EXIF Tags and Camera Images
EXIF Tags and Android
You Spin (Photos) Right Round
And Then, There Are the Bugs
Scanning with ZXing
Videos: Letting the Camera App Do It
Using a Camera Library
CameraKit-Android
Adding the Dependency
Adding the Preview Display
Permissions
Integrating with the Lifecycle
Taking a Picture
Recording a Video
Fotoapparat
Adding the Dependency
Permissions
Adding the Preview Display
Configuring the Fotoapparat
Integrating with the Lifecycle
Taking a Picture
Directly Working with the Camera
Working Directly with the Camera
Prerequisites
Notes About the Code Snippets
A Tale of Two APIs
android.hardware.Camera
android.hardware.camera2
MediaRecorder
The APIs That You (Probably) Can’t Use
Performing Basic Camera Operations
Permissions
Features
A Camera is Optional
A Camera is Required
Other Camera Features
Finding Out What Cameras Exist
android.hardware.Camera
android.hardware.camera2
Opening and Closing a Camera
android.hardware.Camera
android.hardware.camera2
Setting Up a Preview Surface
SurfaceView for the Camera
TextureView for the Camera
Showing the Previews
android.hardware.Camera
android.hardware.camera2
Taking a Picture
android.hardware.Camera
android.hardware.camera2
Recording a Video
android.hardware.Camera
android.hardware.camera2
Using MediaRecorder
Configuring the Still Camera
Focus Mode
android.hardware.Camera
android.hardware.camera2
Flash Mode
android.hardware.Camera
android.hardware.camera2
Zoom
android.hardware.Camera
android.hardware.camera2
And Now, The Problems
Choosing a Preview Size
Previews and Aspect Ratios
Choosing a Picture or Video Size
Picture Orientation
Storage Considerations
Configuration Changes
Camera Peeking Attacks
Media Routes
Prerequisites
Terminology
Media
Route
MediaRouter
A Tale of Two MediaRouters
android.media
android.support.v7.media
Attaching to MediaRouter
Getting a MediaRouter Instance
Working with Routes
Registering a Callback
User Route Selection with MediaRouteActionProvider
The Basic Project and Dependencies
The Menu Resource
Initializing the MediaRouter and Selector
Configuring the ActionProvider
Registering for Route Changes
The Results
Live Audio Routes
Live Video Routes
Remote Playback Routes
Using Live Video Routes
Using Remote Playback Routes
Setting Up MediaRouteActionProvider
The Rest of the User Interface
Connecting and Session Management
What’s a Session?
Connecting the Client
Starting a Session
About the Action Bar
Session IDs
Playing
Stopping, and a Bug
The stop() Call, and the Bug
The Workaround: RunnableSessionActionCallback
Pausing and Resuming
Disconnecting
Other Remote Playback Features
Supporting External Displays
Prerequisites
A History of External Displays
What is a Presentation?
Playing with External Displays
Emulated
HDMI
MHL
SlimPort
USB 3.1 Type C
Miracast
WirelessHD
Detecting Displays
A Simple Presentation
The Presentation Itself
Detecting the Displays
Showing and Hiding the Presentation
The Results
A Simpler Presentation
Getting a Little Help
Help When You Need It
Presentations and Configuration Changes
Presentations as Fragments
The Reuse Reality
Presentations as Dialogs
The Context Conundrum
A PresentationFragment (and Subclasses)
Using PresentationFragment
Limits
Another Sample Project: Slides
The Slides
The PagerAdapter
The PresentationFragment
The Activity
Setting Up the Pager
Setting Up the Presentation
Controlling the Presentation
Offering an Action Bar
Device Support for Presentation
Presentations from a Service
Step #1: Attach the Libraries
Step #2: Create a Stub PresentationService
Step #3: Return the Theme
Step #4: Build the View
Step #5: Start and Stop the Service
Hey, What About Chromecast?
Google Cast and Chromecast
Prerequisites
Here a Cast, There a Cast
What is Chromecast?
What is Google Cast?
Common Chromecast Development Notes
Your API Choices
Senders and Receivers
The Sender App
The Receiver
Default Receiver
Styled Receiver
Custom Receiver
Supported Media Types
Cast SDK Dependencies
Developer Registration
The Terms of Service
Device Registration and Development Setup
The Official Libraries
The CastCompanionLibrary… Or Not
Developing Google Cast Apps
The “Ten-Foot UI”
Prerequisites
What is the “Ten-Foot UI”?
Overscan
Navigation
Stylistic Considerations
Fonts
Padding and Margins
Colors
Aspect Ratio
The Leanback UI
Where to Get Leanback
BrowseSupportFragment
Theme and Activity
Loading the Videos
Headers and Contents
Presenting the Presenters
Handling Clicks
The Results
Testing Your Theories
Putting the TVs All Together: Decktastic
Prerequisites
Introducing Decktastic
Launcher UI
Presentation UI
Implementing Decktastic
The Gradle Dependencies
The Presentation Format
The Model Classes
PresoContents
PresoRoster
The Launcher Activity: LeanbackActivity
Manifest Entry
RosterFragment
PresoPresenter
The Guts: MainActivity
Basic Setup
The ViewPager
Supporting the Direct-to-TV Scenario
Supporting External Displays
Supporting Chromecast and Remote Playback Devices
The Rest of the Story
Creating a MediaRouteProvider
Prerequisites
Terminology
DIY Chromecast
MediaRouteProvider
Player Device… and Maybe a Player App
Communications Protocol
Creating the MediaRouteProvider
Defining the Supported Actions
Creating the Descriptors
Receiving the Actions
Handling the Actions
Play
Pause, Resume, and Stop
Get Status and Seek
Publishing the Controller
Handling Discovery Requests
Consuming the MediaRouteProvider
Private Provider
Public Provider
Implementing This “For Realz”
Communicating with the Playback Device
Handling Other Actions/Protocols
Custom Actions
The Media Projection APIs
Prerequisites
Requesting Screenshots
Asking for Permission
Setting Up the Notification
Capturing a Screenshot
The ImageTransmogrifier
Saving the Screenshot
Recording the Screen
Requesting Media Projection… Without a GUI
Implementing a Control Channel… Without a GUI
Using the Control Channel… From the Command Line
Starting the Recording
Deciding How Big Our Recording Is
Actually Recording Stuff
Stopping the Recording
Usage Notes
AlarmManager and the Scheduled Service Pattern
Prerequisites
Scenarios
Options
Wake Up… Or Not?
Repeating… Or Not?
Inexact… Or Not?
Absolute Time… Or Not?
What Happens (Or Not???)
A Simple Example
The Five set…() Varieties
The Four Types of Alarms
When to Schedule Alarms
When User First Runs Your App
On Boot
After a Force-Stop
Archetype: Scheduled Service Polling
Back to the Main Application Thread
Problem: Keeping the Device Awake
Return of the JobIntentService
Examining a Sample
How the Magic Works
Warning: Not All Android Devices Play Nice
Debugging Alarms
Android 6.0 and the War on Background Processing
Android 7.0 and OnAlarmListener
PowerManager and WakeLocks
Prerequisites
Keeping the Screen On, UI-Style
The Role of the WakeLock
What WakefulIntentService Does
JobScheduler
Prerequisites
The Limitations of AlarmManager
Enter the JobScheduler
Employing JobScheduler
Defining and Scheduling the Job
Implementing the Job
Wiring in the Job Service
The Rest of the Sample
Pondering Backoff Criteria
Idle Jobs
Default Behavior
Custom Backoff Criteria
Other JobScheduler Features
JobScheduler Period Limits
GcmNetworkManager
Periodic Work, Across Device Versions
The Dependency
The Job
The JobCreator
The Application
Scheduling Jobs
Enabling GcmNetworkManager Support
Android 6.0 and “the War on Background Processing”
Doze Mode
App Standby Mode
How to Win the War
GCM
…AndAllowWhileIdle()
Use a Foreground Service
The Whitelist
setAlarmClock()
Hope Somebody Else Does Something
Scheduling Content Monitoring
JobScheduler as Work Queue
Defining Some “Work”
Enqueuing the Work
Working Off the Queue
Testing the Service
Work Limits
Accessing Location-Based Services
Prerequisites
Location Providers: They Know Where You’re Hiding
Finding Yourself
On the Move
Getting Permission
Modelling the Weather
Requesting Updates
Implementing the Listener
Displaying the Results
Getting Locations via PendingIntent
Are We There Yet? Are We There Yet? Are We There Yet?
Testing… Testing…
Alternative Flavors of Updates
The Fused Option
Locations and Features
The Fused Location Provider
Prerequisites
Why Use the Fused Location Provider?
Why Not Use the Fused Location Provider?
Finding Our Location, Once
Adding Dependencies
Deal With Runtime Permissions
Confirm Locations Are Available
Request the Location
Using the Location
Getting Periodic Locations
Defining a Location Request
Requesting Location Updates
Working with the Clipboard
Prerequisites
Working with the Clipboard
ClipData and Drag-and-Drop
Monitoring the Clipboard
The Android 4.3 Clipboard Bug
If Your App Monitors the Clipboard…
If Your App Pastes to the Clipboard…
Telephony
Prerequisites
Report To The Manager
You Make the Call!
No, Really, You Make the Call!
Working With SMS
Prerequisites
Sending Out an SOS, Give or Take a Letter
Sending Via the SMS Client
Sending SMS Directly
Inside the Sender Sample
SMS Sending Limitations
Monitoring and Receiving SMS
The Undocumented, Unsupported, Pre-Android 4.4 Way
The Android 4.4+ Way: Monitoring SMS
The Android 4.4+ Way: Receiving SMS
Receiving the Broadcasts
Other Expectations
Handling Both Receive Options
The SMS Inbox
The Undocumented, Unsupported, Pre-Android 4.4 Way
The Android 4.4+ Way
Asking to Change the Default
SMS and the Emulator
SMS Tokens
NFC
Prerequisites
What Is NFC?
… Compared to RFID?
… Compared to QR Codes?
To NDEF, Or Not to NDEF
NDEF Modalities
NDEF Structure and Android’s Translation
The Reality of NDEF
Some Tags are Read-Only
Some Tags Can’t Be Read-Only
Some Tags Need to be Formatted
Tags Have Limited Storage
NDEF Data Structures Are Documented Elsewhere
Tag and Device Compatibility
Sources of Tags
Writing to a Tag
Getting a URL
Detecting a Tag
Reacting to a Tag
Getting the Shared URL
Creating the Byte Array
Creating the NDEF Record and Message
Writing to a Tag
Responding to a Tag
Expected Pattern: Bootstrap
Mobile Devices are Mobile
Enabled and Disabled
Android Beam
The Fragment
Requesting the Beam
Sending the Beam
Receiving the Beam
The Scenarios
Beaming Files
Another Sample: SecretAgentMan
Configuration and Initialization
Writing to the Tag
Reading from the Tag
Beaming the Text
Beaming the File
Additional Resources
Device Administration
Prerequisites
Objectives and Scope
Defining and Registering an Admin Component
The Feature
The Metadata
The Manifest
The Receiver
The Demand for Device Domination
Going Into Lockdown
Passwords and Device Administration
Mandating Quality of Security
Establishing Password Requirements
Password-Related Events
Getting Along with Others
Basic Use of Sensors
Prerequisites
The Sensor Abstraction Model
Considering Rates
Reading Sensors
Obtaining a SensorManager
Identifying a Sensor of Interest
Getting Sensor Events
Interpreting Sensor Events
Wiring Together the Sample
The Results
Batching Sensor Readings
Printing and Document Generation
Prerequisites
The Android Print System
About the Sample App
Printing a Bitmap
Printing an HTML Document
Printing and WebView
Printing a URL
Limitations and Concerns
Printing a PDF File
The PrintDocumentAdapter Protocol
Introducing ThreadedPrintDocumentAdapter
A PdfDocumentAdapter
Using PdfDocumentAdapter
Printing Using a Canvas
Print Jobs
Printing, Threads, and Services
Printing Prior to Android 4.4
HTML Generation
Adding jmustache To Your App
Writing the Report Template
Creating a Report Context
Printing the Report
PDF Generation Options
Basic Bluetooth RFCOMM
Prerequisites
A Quick Bit of Scope
About the Sample App
The User Experience
The Code
Bluetooth and Permissions
The Rx for Your Bluetooth
I Can Haz Bluetooth?
I Feel a Bond Between Us
Getting the Paired Devices
Filtering the Devices
Listing the Devices
A Voyage of Discovery
Enabling Discoverability
Discovering Other Devices
Reacting to Discovery Results
Serving and Shouting
Service Scaffolding
A Quick Word About MutableLiveData
Keeping the UI in the Loop
Services with Services
Reach Out and Touch Someone
Finding Out When We Should Connect
Connecting and Disconnecting
Ping and Pong
Getting Our Client Streams
Sending the Message
Processing the Request
Receiving the Response
Differences with Android Things
Dealing with Different Hardware
Prerequisites
Filtering Out Devices
uses-feature
uses-configuration
uses-library
Runtime Capability Detection
Features
Other Capabilities
Dealing with Device Bugs
Writing and Using Parcelables
Prerequisites
The Role of Parcelable
Writing a Parcelable
By Annotations
By Code Generator Sites and Tools
By Hand
The Parcelable Interface
The CREATOR
By Hand, With a Little Bit of Help
The Limitations of Parcelable
The 1MB Limit
Pass-By-Value
The ClassLoader Conundrum
Sharing Between Apps
Beware the PendingIntent
Responding to URLs
Prerequisites
Manifest Modifications
Creating a Custom URL
Reacting to the Link
App Links
Setting Up the IntentFilter
Setting Up the JSON
Results
User Intervention
Testing Your Setup
App Shortcuts
Prerequisites
Enabling Deep Dives
App Shortcuts, from the User’s POV
Ad-Hoc Requests
Pinning
Alternatives
Offering Manifest App Shortcuts
Identify the Destinations
Ensure the Destination is “Evergreen”
Add Entry Points for Destination in Manifest
Write the XML
Add to the Manifest
Results
Disabling Manifest App Shortcuts
Offering Dynamic App Shortcuts
Grok the Adjectives
Ponder the IDs
Identify the Destinations
Craft the Intent
Define the Shortcuts
Remove the Shortcuts
Grok the Other Verbs
Contemplate Update vs. Replace
Get the Existing Shortcuts
Deal with Reality
Privacy, Security, and App Shortcuts
PackageManager Tricks
Prerequisites
Asking Around
Preferred Activities
Middle Management
Finding Applications and Packages
Finding Resources
Finding Components
Remote Services and the Binding Pattern
Prerequisites
The Binding Pattern
What the Service Does
What the Client Does
A Binding Sample
Starting and Binding
When IPC Attacks!
Write the AIDL
Implement the Interface
Service From Afar
Service Names
Remote Services and Implicit Intents
The Service
The Client
Tightening Up the Security
Adding the Dependency
Adding the Signature Check: Client
Adding the Signature Check: Service
So, Where Do We Get the Expected Hash From?
Servicing the Service
Callbacks via AIDL
Revising the Client
Revising the Service
Thinking About Security
The “Everlasting Service” Anti-Pattern
Advanced Manifest Tips
Prerequisites
Just Looking For Some Elbow Room
Configuring Your App to Reside on External Storage
What the User Sees
What the Pirate Sees
What Your App Sees… When External Storage is Inaccessible
Choosing Whether to Support External Storage
Android 6.0 and “Adoption” of Removable Storage
Using an Alias
Getting Meta (Data)
Miscellaneous Integration Tips
Prerequisites
Direct Share
The ChooserTargetService
The Manifest Entries
The Results
But… I Got Nothin’!
Best Practices
Take the Shortcut
Registering a Shortcut Provider
Implementing a Shortcut Provider
Using the Shortcuts
Homing Beacons for Intents
Integrating with Text Selection
Supporting ACTION_PROCESS_TEXT
The Manifest
The Extras
The Results (If Any)
Limitations of ACTION_PROCESS_TEXT
Security
Supporting ACTION_PROCESS_TEXT in Custom Views
Blocking ACTION_PROCESS_TEXT
Quick Settings and TileService
The Manifest Entry
Active and Passive Tiles
And, Of Course, Bugs
Only Enabling on Android 7.0+
The Service
The User Experience
The Other Features and Limitations
Installing Packages
Deleting Packages
Detecting Changes in Packages
Android Studio Editors and Dialogs
Prerequisites
Project Structure
SDK Location
Project Settings
Developer Services
Module Settings
Properties
Signing
Flavors
Build Types
Dependencies
Translations Editor
Advanced Emulator Capabilities
Prerequisites
Other Notable Configuration Options
Hardware Graphics Acceleration
Keyboard Behavior
Startup Settings
Camera Options
Memory and Storage Configuration
Frames and Skins
The Emulator Sidebar
Power and Navigation Controls
Screen Orientation and Zoom
Screenshots
Faking the Real World
Location
Network Status
Battery
Telephony
Emulator Window Operations
Headless Operation
Lint and the Support Annotations
Prerequisites
What It Is
When It Runs
Android Studio
Command Line
What to Fix
What to Configure
Android Studio
Command Line
Support Annotations
Permissions, Again
Methods
Intent Actions
ContentProviders
What Permissions Should I Annotate?
Type Roles, and the War on Enums
Resources
Custom Enum Replacement
Flags
Does It Null?
Data Validation
Size
Ranges
Colors
Thread Validation
Other Annotations
Inspecting Layouts
Launching the Layout Inspector
Viewing the View Hierarchy
Inspections and Captures
Screenshots and Screencasts
Prerequisites
Collecting from Android Studio
Screenshots
Screencasts
Collecting from the Command Line
Screenshots
Screencasts
Collecting from Another App
Tips and Tricks
ADB Tips and Tricks
Prerequisites
This is the Droid That You Are Looking For
Installing and Uninstalling Apps
Playing with Permissions
Starting and Stopping Components
Killing Processes and Clearing Data
Changing Display Metrics
Stetho
Wait, Wut? Chrome?
Basic Stetho Integration
Adding the Stetho Dependency
Creating a Debug Sourceset
Adding the Stetho Application
The Main Application
The Debug Application
Overriding the Application
Connecting Chrome to Your App
What You Get In Chrome Dev Tools
Elements: View Hierarchy
Network: HTTP Requests
Screencast: Your UI, Mostly
Resources: In-Place Database CLI
Console: Example Environment via JavaScript
Getting Help with Stetho
Hey, What About Sonar?
Issues with Speed
Prerequisites
Getting Things Done
Your UI Seems… Janky
Not Far Enough in the Background
Playing with Speed
Finding CPU Bottlenecks
Prerequisites
Android Studio’s Profiler
Opening the Profiler
Manipulating the Profiler
Hey, Why Is My App Running So Slow Now?
Method Tracing
OK, What Is Method Tracing, Really?
Collecting Trace Data
Debug Class
Android Studio
Displaying Trace Data
Interpreting Trace Data
Other General CPU Measurement Techniques
Logging
FPS Calculations
UI “Jank” Measurement
What, Exactly, is Jank?
Using gfxinfo
Enabling Developer Options
Toggling on GPU Profiling
Collecting Data
Disabling GPU Profiling
Analyzing the Results
Using systrace
Enabling and Collecting a Trace: Command-Line
Collecting Traces on Android 9.0 Devices
Choosing the Trace Tags
Augmenting the Trace from Java
Viewing and Interpreting the Results
Focus On: NDK
Prerequisites
The Role of the NDK
Dalvik: Secure, Yes; Speedy, Not So Much
Going Native
Speed
Porting
Knowing Your Limits
Android APIs
Cross-Platform Compatibility
Introducing CWAC-AndDown
Installing the NDK
The Contents of an NDK Project
Your C/C++ Code
Your Makefile
Your Gradle Changes
Building Your Library
Your Java and JNI Code
libhoudini and the NDK
Improving CPU Performance in Java
Prerequisites
Reduce CPU Utilization
Standard Java Optimizations
Avoid Excessive Synchronization
Avoid Floating-Point Math
Don’t Assume Built-In Algorithms are Best
Support Hardware-Accelerated Graphics
Minimize IPC
Remote Bound Service
Remote Content Provider
Remote OS Operation
Android-Specific Java Optimizations
Reduce Time on the Main Application Thread
Generate Less Garbage
View Recycling
Background Threads
Asynchronous BroadcastReceiver Operations
Saving SharedPreferences
Improve Throughput and Responsiveness
Minimize Disk Writes
Set Thread Priority
Do the Work Some Other Time
Finding and Eliminating Jank
Prerequisites
The Case: ThreePaneDemoBC
Are We Janky?
Finding the Source of the Jank
Traceview
Overdraw
Extraneous Views
Conclusion: Too Many layout() Calls?
Where Things Went Wrong
Removing the Jank
Frame Metrics API
What Data You Get
How You Get That Data
Issues with Bandwidth
Prerequisites
You’re Using Too Much of the Slow Stuff
You’re Using Too Much of the Expensive Stuff
You’re Using Too Much of Somebody Else’s Stuff
You’re Using Too Much… And There Is None
Focus On: TrafficStats
Prerequisites
TrafficStats Basics
Device Statistics
Per-Application Statistics
Interpreting the Results
Example: TrafficMonitor
TrafficRecord
TrafficSnapshot
TrafficMonitorActivity
Using TrafficMonitor
Other Ways to Employ TrafficStats
In Production
During Testing
Measuring Bandwidth Consumption
Prerequisites
On-Device Measurement
Yourself, via TrafficStats
Data Usage Screen in Settings
Off-Device Measurement
Wireshark
Networking Hardware
Android Studio Profiler
Being Smarter About Bandwidth
Prerequisites
Bandwidth Savings
Classic HTTP Solutions
GZip Encoding
If-Modified-Since / If-None-Match
Binary Payloads
Minification
Keep-Alive Semantics
Push versus Poll
Thumbnails and Tiles
Bandwidth Shaping
Driven by Preferences
Budgets
Connectivity
Windows
Driven by Other Usage
Avoiding Metered Connections
Data Saver
Issues with Application Heap
Prerequisites
You Are in a Heap of Trouble
Determining Your Heap Size At Runtime
Fragments of Memory
Getting a Trim
onTrimMemory() Callbacks
Warning: Contains Graphic Images
Bitmap Caching
Bitmap Sizing
Bitmap Color Space
Bitmap Reuse
Releasing SQLite Memory
Cheating
The 1MB IPC Transaction Limit
Finding Memory Leaks
Prerequisites
Android Studio Profiler
Getting Heap Dumps
In Android Studio
From Code
Analyzing Heap Dumps in Android Studio
Navigating the Heap Dump UI
Class List
Heap Selector
Package Tree View
Instance List
Identifying Leak Candidates
Common Leak Scenarios
The Static Widget
Thread References
Retaining Too Much
A Canary in a Leaky Coal Mine
Introducing LeakCanary
Adding LeakCanary to a Project
Adding the Dependencies
Adding the Application
Adding Manual Leak Checks
Testing with LeakCanary
The Notifications
Activity Output
Issues with System RAM
Prerequisites
Can’t We All Just Get Along?
Contributors to System RAM Consumption
Measuring System RAM Consumption: Tools
Process Stats in Settings
The Summary
The Roster
Refresh and Duration
Controlling What is Shown
Drilling Down Into an App
How You Want Your App to Appear
procstats
meminfo
Measuring System RAM Consumption: Runtime
getMemoryInfo()
getMyMemoryState()
getProcessMemoryInfo()
Learn To Let Go (Of Your Heap)
Issues with Battery Life
Prerequisites
You’re Getting Blamed
Not All Batteries Are Created Equal
Stretching Out the Last mWh
Power Measurement Options
Prerequisites
batterystats and the Battery Historian
Running a Test
Interpreting the Text Output
Battery History
Per-PID Stats
Daily Stats
“Statistics since last charge” Summary
WakeLock Summary
Per PID Summary
Installing the Battery Historian
Running the Battery Historian
Interpreting the Historian Output
PowerTutor
Battery Screen in Settings Application
BatteryInfo Dump
Sources of Power Drain
Prerequisites
Screen
Disk I/O
WiFi and Mobile Data
Use Less
Use What You Already Downloaded
Use In Batches
Use When the Server Wants You To
Use When Android Wants You To
Use Additional Reading
GPS
Camera
Additional Sources
CPU/GPU
Sensors
Audio Input and Output
Addressing Application Size Issues
Prerequisites
The APK Analyzer
Java Code, and the 64K Method Limit
What Is It?
64K Seems Like a Lot of Typing…
Where Are The Methods Coming From?
Mitigation Tactics
Use Granular Libraries
Use Better Libraries
Use ProGuard
Mitigation Strategies
Don’t Go Overboard
Smaller Apps, Loosely Connected
Multidex
Native Code
Mitigation via Per-CPU APKs
Mitigation via libhoudini
Mitigation via Ignoring Non-ARM
Images
Mitigation via Resource Aliases
Mitigation via pngquant
APK Expansion Files
Crash Reporting Using ACRA
Prerequisites
What Happens When Things Go “Boom”?
Introducing ACRA
Where ACRA Reports Crashes
An Existing Crash Logging Service
Acralyzer
Email
A Host for Testing
ACRA Integration Basics
Adding the Dependencies
Java 8
Build Types, Product Flavors, and ACRA
Creating a Custom Application
Implementing the Application
Configuring the Core
Configuring Report Delivery
Configuring User Notification
Initializing ACRA
Reporting Crashes
What the User Sees
Default: “Silent”
Dialog
Notification
Limitations
What You See
ACRA and Processes
In-App Diagnostics
Prerequisites
The Diagnostic Activity
The Sourceset
The Manifest
The Activity
The Results
The Limitations
The Diagnostic Overlay
The Gradle Setup
Introducing RVAdapterWrapper
TimingWrapper (a.k.a., StrictMode for RecyclerView)
The RecyclerViewActivity
Being Stupid
The Results
Areas for Improvement
What Changed in Android 6.0
Anti-Patterns
Prerequisites
Leak Threads… Or Things Attached to Threads
The Costs
The Counter-Arguments
Use Large Heap Unnecessarily
The Costs
The Counter-Arguments
Misuse the MENU Button
The Costs
The Counter-Arguments
Interfere with Navigation
The Costs
The Counter-Arguments
Use android:sharedUserId
The Costs
The Counter-Arguments
Implement a “Quit” Button
The Costs
The Counter-Arguments
Terminate Your Process
The Costs
The Counter-Arguments
Try to Hide from the User
The Costs
The Counter-Arguments
Use Multiple Processes
The Costs
The Counter-Arguments
Hog System Resources
The Counter-Arguments
Widget Catalog: AdapterViewFlipper
Key Usage Tips
A Sample Usage
Visual Representation
Widget Catalog: CalendarView
Key Usage Tips
A Sample Usage
Visual Representation
Widget Catalog: DatePicker
Key Usage Tips
A Sample Usage
Visual Representation
Widget Catalog: ExpandableListView
Key Usage Tips
A Sample Usage
Visual Representation
Widget Catalog: SeekBar
Key Usage Tips
A Sample Usage
Visual Representation
Widget Catalog: SlidingPaneLayout
Declaring a SlidingPaneLayout
Visual Representation
Interacting with a SlidingPaneLayout
Widget Catalog: StackView
Key Usage Tips
A Sample Usage
Visual Representation
Widget Catalog: TabHost and TabWidget
Deprecation Notes
Key Usage Tips
A Sample Usage
Visual Representation
Widget Catalog: TimePicker
Key Usage Tips
A Sample Usage
Visual Representation
Widget Catalog: ViewFlipper
Key Usage Tips
A Sample Usage
Visual Representation
Device Catalog: Chrome and Chrome OS
Prerequisites
How This Works
Chrome OS Form Factors
Testing Your App on Chrome OS
Step #1: Get a Compatible Chrome OS Device
Step #2: Enable Android Apps
Step #3: Switch the Device to the Dev Channel
Step #4: Enable Chrome OS Developer Mode
Chromebooks
Chrome OS Tablets
Chromeboxes
Where You Go From Here
Step #5: Set Up the Android Environment
Step #6: Side-Load and Install Your App
Step #7: Get adb Working
Step #7a: Configure the Chrome OS Device
Step #7b: Find Your Chrome OS IP Address
Step #7c: Connect to Chrome OS for Development
Be Prepared To Be Wiped Out
Compatibility and Your App
Trying to Get Onto Chrome OS
Trying to Stay Away From Chrome OS
Your App on Chrome OS
Environment
System Features
NDK Binaries
Other Values
Screen Size and Orientation
Lifecycle Events
Touchscreen and Keyboard Input
Storage
Notifications
Internet Access
Miscellaneous Oddities
Distribution Options
Getting Help
Device Catalog: BlackBerry
I Thought BlackBerry Had Their Own OS?
What Else Is Different?
Hardware
BlackBerry OS 10.3
Navigation
Nothing Googly
Package Name Length
What Are We Making?
Getting Your Development Environment Established
Checking and Repackaging Your App
Android Studio Plugin
Standalone GUIs
BlackBerry 10 Simulator
Developing on Hardware
How Does Distribution Work?
BlackBerry World
Amazon Appstore for Android
Alternatives
Device Catalog: Android TV
Prerequisites
Hey, Wait a Minute… I Thought the Name Was “Google TV”?
Some Android TV Hardware
ADT-1
Nexus Player
What Features and Configurations Does It Use?
Screen Size and Density
Input Devices
Other Hardware
What Is Really Different?
Overscan
Ethernet
Location
Media Keys
Getting Your Development Environment Established
Connecting to Physical Devices
How Does Distribution Work?
Getting Your App on Android TV
Supporting Only Android TV
Avoiding Android TV
Device Catalog: Amazon Fire TV and Fire TV Stick
Prerequisites
Introducing the Fire TV Devices
Fire TV
FIre TV Stick
What Features and Configurations Do They Use?
Screen Size, Density, and Orientation
Input Devices
Hardware Features
What Is Really Different?
Casting and Fire TV
Getting Your Development Environment Established
Working with the Remote and Controller
Wireless Remote
Gaming Controller
How Does Distribution Work?
Getting Help
Device Catalog: Samsung DeX
DeX Screen Modes
Screen Mirroring
DeX Mode
Other App Impacts
Configuration and State Changes
Moving In and Out of DeX
Resource Set Qualifiers
Networking
USB
Debugging Interface
Screenshots
Detecting DeX
Drag-and-Drop
For More Information
Appendix A: CWAC Libraries
cwac-document
cwac-layouts
cwac-netsecurity
cwac-presentation
cwac-provider
cwac-saferoom
cwac-security
Appendix B: Android 8.0
The War on Background Processing, Continued
Background Service Limitations
WakeLock Limitations
Manifest-Registered Broadcast Limitations
What Is Affected
Why This Ban Was Added
Workarounds for Senders
Workarounds for Receivers
Background Location Limitations
JobScheduler Enhancements
JobIntentService
JobScheduler as Work Queue
Auto-Fill
Notification Channels
Other Changes with Notifications
Multi-Window Changes
WebView Changes
ContentProvider Changes
Storage Access Framework Changes
Package Management
Fonts as Resources
Other Major Changes in Android 8.0
Cache Quotas
Content Annotations
Seekable Streams
Implementing a ProxyFileDescriptorCallback
Using a ProxyFileDescriptorCallback
The Woes of ProxyFileDescriptorCallback
Foreground Heap Compaction
Shortcuts, App Widgets, and Pinning
Auto-Sizing TextView
SMS Tokens
Custom Preference Storage
FragmentLifecycleCallbacks
Other Minor Changes in Android 8.0
Permission Granularity
Tooltips
ZoomButton Deprecated
App Categories
Changes in ANDROID_ID Scope
Alert Windows
Build.SERIAL Versus Build.getSerial()
StorageStatsManager
TextClassificationManager
Appendix C: Android 9.0
Major Breaking Changes
Native Fragment Deprecation
HTTPS Required By Default
No Hidden API Access
A Minimum targetSdkVersion
Foreground Service Permission
Background Apps and Privacy
“The War on Background Processing”, Continued
Device Administration Deprecations
Missing Stuff Returns
Removal of Deprecated Testing Classes
Signature Changes and Deprecations
Major Features
Slices
Notification Improvements
Fingerprint Improvements
BiometricPrompt
ACTION_FINGERPRINT_ENROLL
Other Notable Changes
Display Cutouts
ImageDecoder
AppComponentFactory
Indoor Positioning
JobScheduler Additions
StrictMode Callbacks
Example: ACRA Reporting
Example: Greylist Violation Reporting
WebView Improvements
Disabling It
Tracing It
Autofill Service Detection
Storage Volume Action
KeyEvent Fallback Processing
Magnifier
Notes About the Support Library
Package Names
Further Library Subdivision
RecyclerView Selection
New Design Widgets
Getting Help with 9.0
Appendix D: Community Theater and the Appinars
Viewing the Appinar Roster
Managing Appinars
Viewing an Appinar
Pausing Playback
Navigating the Appinar
Manipulating the Content
WOW! eBook www.wowebook.org
The Busy Coder's Guide to Android Development by Mark L. Murphy
The Busy Coder's Guide to Android Development by Mark L. Murphy Copyright © 2008-2019 CommonsWare, LLC. All Rights Reserved. Printed in the United States of America. Printing History: February 2019 FINAL Version ISBN: 978-0-9816780-0-9 The CommonsWare name and logo, “Busy Coder's Guide”, and related trade dress are trademarks of CommonsWare, LLC. All other trademarks referenced in this book are trademarks of their respective firms. The publisher and author(s) assume no responsibility for errors or omissions or for damages resulting from the use of the information contained herein. WOW! eBook www.wowebook.org
Table of Contents Headings formatted in bold-italic have changed since the last version. • Preface ◦ Welcome to the Book! ...................................................................... xliii ◦ First-Generation Book ...................................................................... xliii ◦ The Book’s Structure ......................................................................... xliv ◦ The Trails ............................................................................................. xlv ◦ About the Updates ................................................................................. l ◦ About the APK Edition .......................................................................... l ◦ Source Code and Its License ................................................................ li ◦ Creative Commons and the Four-to-Free (42F) Guarantee ............... li ◦ Acknowledgments ............................................................................... lii • Key Android Concepts ◦ Android Applications ............................................................................ 1 ◦ Android Devices ................................................................................... 6 ◦ Don’t Be Scared .................................................................................... 10 • Choosing Your Development Toolchain ◦ Android Studio ..................................................................................... 11 ◦ Eclipse .................................................................................................... 11 ◦ IntelliJ IDEA ......................................................................................... 12 ◦ Command-Line Builds via Gradle ...................................................... 12 ◦ Yet Other Alternatives ......................................................................... 12 ◦ IDEs… And This Book ........................................................................... 13 ◦ What We Are Not Covering ................................................................. 13 • Tutorial #1 - Installing the Tools ◦ But First, Some Notes About Android’s Emulator ............................. 15 ◦ Step #1: Checking Your Hardware ...................................................... 16 ◦ Step #2: Setting Up Java and 32-Bit Linux Support ............................ 17 ◦ Step #3: Install Android Studio ........................................................... 18 ◦ Step #4: Install the SDKs and Add-Ons ............................................. 19 ◦ In Our Next Episode… ......................................................................... 27 • Android and Projects ◦ Projects and Android Studio ............................................................... 29 • Tutorial #2 - Creating a Stub Project ◦ About Our Tutorial Project ................................................................. 37 ◦ About the Rest of the Tutorials ........................................................... 38 ◦ About Our Tools .................................................................................. 38 i WOW! eBook www.wowebook.org
◦ Step #1: Importing the Project ............................................................ 38 ◦ Step #2: Get Ready for the x86 Emulator ........................................... 43 ◦ Step #3: Set Up the AVD ..................................................................... 44 ◦ Step #4: Set Up the Device .................................................................. 51 ◦ Step #5: Running the Project .............................................................. 56 ◦ In Our Next Episode… ......................................................................... 58 • Getting Around Android Studio ◦ Navigating The Project Explorer ......................................................... 59 ◦ Running Projects ................................................................................. 62 ◦ Viewing Output ................................................................................... 63 ◦ Accessing Android Tools ..................................................................... 65 ◦ Android Studio and Release Channels .............................................. 66 ◦ Visit the Trails! .................................................................................... 68 • Contents of Android Projects ◦ What You Get, In General .................................................................. 69 ◦ More About the Directory Structure .................................................. 72 ◦ What You Get Out Of It ...................................................................... 74 • Introducing Gradle and the Manifest ◦ Gradle: The Big Questions .................................................................. 75 ◦ Obtaining Gradle ................................................................................. 77 ◦ Versions of Gradle and the Android Gradle Plugin ........................... 79 ◦ Gradle Environment Variables ........................................................... 80 ◦ Examining the Gradle Files ................................................................ 80 ◦ Introducing the Manifest .................................................................... 83 ◦ Things In Common Between the Manifest and Gradle ................... 84 ◦ Other Gradle Items of Note ............................................................... 86 ◦ Where’s the GUI? ................................................................................. 87 ◦ The Rest of the Manifest ..................................................................... 87 ◦ Learning More About Gradle ............................................................. 89 ◦ Visit the Trails! .................................................................................... 90 • Tutorial #3 - Manifest Changes ◦ Some Notes About Relative Paths ...................................................... 91 ◦ Step #1: Supporting Screens ................................................................ 91 ◦ Step #2: Blocking Backups .................................................................. 92 ◦ Step #3: Ignoring Lint .......................................................................... 92 ◦ In Our Next Episode… ........................................................................ 94 ◦ String Theory ....................................................................................... 95 ◦ Got the Picture? ................................................................................. 102 ◦ Dimensions ........................................................................................ 105 ◦ The Resource That Shall Not Be Named… Yet ................................. 107 • Some Words About Resources ii WOW! eBook www.wowebook.org
• Icons ◦ App Icons… And Everything Else ...................................................... 109 ◦ Creating an App Icon with the Asset Studio .................................... 110 ◦ Creating Other Icons with the Asset Studio ..................................... 116 • Tutorial #4 - Adjusting Our Resources ◦ Step #1: Changing the Name .............................................................. 117 ◦ Step #2: Changing the Icon ................................................................ 118 ◦ Step #3: Running the Result ............................................................... 123 ◦ In Our Next Episode… ........................................................................ 123 • The Theory of Widgets ◦ What Are Widgets? ............................................................................ 125 ◦ Size, Margins, and Padding ................................................................ 127 ◦ What Are Containers? ........................................................................ 127 ◦ The Absolute Positioning Anti-Pattern ............................................ 128 ◦ The Theme of This Section: Themes ................................................ 129 • The Android User Interface • Basic Widgets ◦ The Activity ......................................................................................... 135 ◦ Dissecting the Activity ...................................................................... 136 ◦ Using XML-Based Layouts ................................................................. 137 ◦ Common Concepts ............................................................................. 141 ◦ Introducing the Graphical Layout Editor ........................................ 144 ◦ And Now, Some Notes About the Book’s Sample Projects .............. 153 ◦ Assigning Labels ................................................................................ 154 ◦ A Commanding Button ..................................................................... 159 ◦ Fleeting Images .................................................................................. 162 ◦ Fields of Green. Or Other Colors. .................................................... 168 ◦ More Common Concepts ................................................................... 171 ◦ Visit the Trails! .................................................................................... 174 • Debugging Your App • The Classic Container Classes ◦ Get Thee To a Stack Trace ................................................................. 176 ◦ The Case of the Confounding Class Cast .......................................... 177 ◦ Point Break ......................................................................................... 178 ◦ Introducing the Sampler App ........................................................... 179 ◦ RTL and Your Layouts ....................................................................... 180 ◦ LinearLayout and the Box Model ...................................................... 181 ◦ All Things Are Relative ...................................................................... 207 ◦ Tabula Rasa ......................................................................................... 217 ◦ Hey, What About ConstraintLayout? ............................................... 223 ◦ Turning Back to RTL .......................................................................... 224 iii WOW! eBook www.wowebook.org
• Other Common Widgets and Containers ◦ Just a Box to Check ............................................................................ 227 ◦ Don’t Like Checkboxes? How About Toggles or Switches? ............. 231 ◦ Turn the Radio Up ............................................................................. 235 ◦ Scrollwork ........................................................................................... 238 ◦ Making Progress with ProgressBars ................................................. 242 ◦ Framing the Scene ............................................................................. 242 ◦ Visit the Trails! ................................................................................... 243 • Tutorial #5 - Creating a Layout • GUI Building, Continued ◦ Step #1: Creating a New Layout Resource ........................................ 245 ◦ Step #2: Defining the UI ................................................................... 246 ◦ In Our Next Episode… ....................................................................... 250 ◦ Making Your Selection ...................................................................... 252 ◦ Including Includes ............................................................................. 252 ◦ Preview of Coming Attractions ......................................................... 254 • AdapterViews and Adapters • The WebView Widget ◦ Adapting to the Circumstances ........................................................ 256 ◦ Lists of Naughty and Nice ................................................................. 257 ◦ Clicks versus Selections .................................................................... 260 ◦ Spin Control ....................................................................................... 263 ◦ Grid Your Lions (Or Something Like That…) .................................. 267 ◦ Fields: Now With 35% Less Typing! ................................................. 272 ◦ Customizing the Adapter .................................................................. 277 ◦ Visit the Trails! ................................................................................... 285 ◦ Role of WebView ............................................................................... 287 ◦ Daddy, Where Do WebViews Come From? .................................... 288 ◦ Adding the Widget ........................................................................... 288 ◦ Loading Content Via a URL ............................................................. 289 ◦ Links and Redirects ........................................................................... 291 ◦ Supporting JavaScript ........................................................................ 291 ◦ Alternatives for Loading Content ..................................................... 292 ◦ Listening for Events ........................................................................... 293 ◦ Addressing the Link/Redirect Behavior .......................................... 296 ◦ Opting Out of Google Monitoring .................................................. 298 ◦ Visit the Trails! .................................................................................. 299 ◦ Styles: DIY DRY .................................................................................. 301 ◦ Elements of Style ............................................................................... 303 ◦ Themes: Would a Style By Any Other Name… ................................ 306 iv • Defining and Using Styles WOW! eBook www.wowebook.org
• Dependencies ◦ What Happens If You Have No Theme ............................................ 306 ◦ Android Studio’s Theme Editor ........................................................ 307 ◦ What’s a Dependency? ....................................................................... 313 ◦ Dependency Scopes ........................................................................... 314 ◦ Depending on a Local JAR ................................................................. 315 ◦ What’s an Artifact? ............................................................................ 316 ◦ Artifacts and Repositories ................................................................. 316 ◦ Major Library Families from Google ................................................ 316 ◦ Requesting Dependencies .................................................................. 317 ◦ The Android Support Library ........................................................... 320 • Tutorial #6 - Adding a Library • Introducing ConstraintLayout ◦ Step #1: Getting Rid of Existing Cruft ............................................... 325 ◦ Step #2: Requesting New Dependencies .......................................... 326 ◦ In Our Next Episode… ....................................................................... 328 ◦ Why Another Container? .................................................................. 329 ◦ Comparing with the Classics ............................................................. 331 ◦ Getting ConstraintLayout .................................................................. 331 ◦ Using Widgets and Containers from Libraries ................................ 332 ◦ Using a ConstraintLayout ................................................................. 332 ◦ Converting Existing Layouts ............................................................. 346 ◦ Visit the Trails! ................................................................................... 348 • RecyclerView • The Action Bar ◦ AdapterView and its Discontents ..................................................... 349 ◦ Enter RecyclerView ............................................................................ 350 ◦ A Trivial List ........................................................................................ 351 ◦ Divider Options ................................................................................. 359 ◦ Handling Click Events ....................................................................... 366 ◦ Visit the Trails! ................................................................................... 373 ◦ Bar Hopping ....................................................................................... 375 ◦ Yet Another History Lesson .............................................................. 382 ◦ Your Action Bar Options ................................................................... 382 ◦ Setting the Target .............................................................................. 384 ◦ Defining the Resource ....................................................................... 386 ◦ Applying the Resource ...................................................................... 388 ◦ Responding to Events ........................................................................ 388 ◦ The Rest of the Sample Activity ....................................................... 389 ◦ MENU Key, We Hardly Knew Ye ...................................................... 396 ◦ Action Bars, Live in Living Color! ..................................................... 397 v WOW! eBook www.wowebook.org
分享到:
收藏