The Busy Coder's Guide to Advanced Android Development
Mark L. Murphy
Computers & Technology
The Busy Coder's Guide to Advanced Android Development

At over 3,200 pages, this book covers everything from introductory steps all the way to very advanced topics. More importantly, this book is continuously updated to reflect changes in Android itself, with new material being added every couple of months.

This edition, licensed under Creative Commons, is version 5.0 (2013), and may be significantly out of date. Android keeps advancing, and these books will refer to classes, tools, and techniques that are no longer available or recommended. You are strongly encouraged to obtain other Android development knowledge — whether from CommonsWare or somebody else — that is more current to go along with anything you obtain from here.

With a "Warescription", available from Commonsware, you are assured of having current Android programming information at your fingertips.

The book is divided into core chapters plus the trails.

The core chapters — representing ~800 pages — are set up as a typical programming guide, covering the basics of getting an Android app up and running. The book includes material on setting up your development tools, constructing a user interface, loading data from a local database or the Internet, handling the differences between phones and tablets, and much more.

The core chapters also include an integrated set of 19 tutorials, offering you step-by-step guides for creating an Android application from scratch. Hence, whether you "learn by reading" or "learn by doing", you have the material in the core chapters to accomplish your goal.

The rest of the book comprises the trails. These are linked sets of chapters covering advanced topics, organized by theme. However, while the core chapters are designed to be read in sequence, the trails are designed to be read on an as-needed basis, when you want to dive into those specific topics.

The Busy Coder's Guide to Android Development
Table of Contents
Welcome to the Book!
The Book’s Structure
The Trails
Advanced UI
Home Screen Effects
Data Storage and Retrieval
Hardware and System Services
Integration and Introspection
Scripting Languages
Tuning Android Applications
Alternatives for App Development
Miscellaneous Topics
Widget Catalog
Device Catalog
Accessory Catalog
About the Updates
Getting Help
Book Bug Bounty
Source Code And Its License
Creative Commons and the Four-to-Free (42F) Guarantee
Key Android Concepts
Android Applications
Programming Language
Content Providers
Broadcast Receivers
Widgets, Containers, Resources, and Fragments
Apps and Packages
Android Devices
The Emulator
OS Versions and API Levels
Processes and Threads
Don’t Be Scared
Choosing Your IDE
What the ADT Gives You
Alternative IDEs
IDEs… And This Book
About App Inventor
Tutorial #1 - Installing the Tools
Step #1 - Checking Your Hardware Requirements
Step #2 - Setting Up Java
Install the JDK
Step #3 - Install the Android SDK
Install the Base Tools
Install the SDKs and Add-Ons
Step #4 - Install the ADT for Eclipse
Step #5 - Install Apache Ant
Step #6 - Set Up the Emulator
Step #7 - Set Up the Device
Windows Update
Standard Android Driver
Manufacturer-Supplied Driver
OS X and Linux
In Our Next Episode…
Tutorial #2 - Creating a Stub Project
About Our Tutorial Project
About the Rest of the Tutorials
About the Eclipse Instructions
Step #1: Creating the Project
Command Line
Step #2: Running the Project
Command Line
In Our Next Episode…
Contents of Android Projects
Root Contents
The Sweat Off Your Brow
What You Get Out Of It
Inside the Manifest
In The Beginning, There Was the Root, And It Was Good
An Application For Your Application
Specifying Versions
Supporting Multiple Screens
Other Stuff
Tutorial #3 - Changing Our Manifest
Step #1: Supporting Screens
Outside of Eclipse
Step #2: Validating our Minimum and Target SDK Versions
In Our Next Episode…
Some Words About Resources
String Theory
Plain Strings
Styled Text
The Directory Name
String Resources and Eclipse
Got the Picture?
Drawable Resources and Eclipse
Using Android System Drawables
Directly Referencing SDK Drawables
Copying Android System Drawables
Dimension Resources and Eclipse
The Resource That Shall Not Be Named… Yet
Tutorial #4 - Adjusting Our Resources
Step #1: Changing the Name
Outside of Eclipse
Step #2: Changing the Icon
Outside of Eclipse
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 Android User Interface
The Activity
Dissecting the Activity
Using XML-Based Layouts
What Is an XML-Based Layout?
XML Layouts and Eclipse
Why Use XML-Based Layouts?
Using Layouts from Java
Basic Widgets
Common Concepts
Widgets and Attributes
Referencing Widgets By ID
Assigning Labels
Eclipse Graphical Layout Editor
Editing the Text
Editing the ID
Notable TextView Attributes
A Commanding Button
Eclipse Graphical Layout Editor
Tracking Button Clicks
Fleeting Images
Eclipse Graphical Layout Editor
Fields of Green. Or Other Colors.
Eclipse Graphical Layout Editor
Notable EditText Attributes
More Common Concepts
Other Useful Attributes
Useful Methods
Visit the Trails!
Debugging Crashes
Get Thee To a Stack Trace
The Case of the Confounding Class Cast
Point Break
LinearLayout and the Box Model
Concepts and Properties
Fill Model
Eclipse Graphical Layout Editor
Other Common Widgets and Containers
Just a Box to Check
Eclipse Graphical Layout Editor
Don’t Like Checkboxes? How About Toggles?
Eclipse Graphical Layout Editor
Turn the Radio Up
Eclipse Graphical Layout Editor
All Things Are Relative
Concepts and Properties
Positions Relative to Container
Relative Notation in Properties
Positions Relative to Other Widgets
Order of Evaluation
Eclipse Graphical Layout Editor
Tabula Rasa
Concepts and Properties
Putting Cells in Rows
Non-Row Children of TableLayout
Stretch, Shrink, and Collapse
Eclipse Graphical Layout Editor
Eclipse Graphical Layout Editor
Making Progress with ProgressBars
Visit the Trails!
Tutorial #5 - Making Progress
Step #1: Removing The “Hello, World”
Outside of Eclipse
Step #2: Adding a ProgressBar
Outside of Eclipse
Step #3: Seeing the Results
In Our Next Episode…
GUI Building, Continued
Making Your Selection
Including Includes
Wrap It Up (In a Container)
Morphing Widgets
Preview of Coming Attractions
AdapterViews and Adapters
Adapting to the Circumstances
Using ArrayAdapter
Lists of Naughty and Nice
Clicks versus Selections
Selection Modes
Clicks versus Selections, Revisited
Spin Control
Grid Your Lions (Or Something Like That…)
Fields: Now With 35% Less Typing!
Galleries, Give Or Take The Art
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
WebView and WebKit
Adding the Widget
Loading Content Via a URL
Supporting JavaScript
Alternatives for Loading Content
Listening for Events
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…
JARs and Library Projects
The Dalvik VM
The Easy Part
The Outer Limits
OK, So What is a Library Project?
Creating a Library Project
Using a Library Project
Limitations of Library Projects
The Android Support Package
What’s In There?
About the Names
Getting It
Attaching It To Your Project
JAR Dependency Management
Tutorial #6 - Adding a Library
Step #1: Downloading and Unpacking ActionBarSherlock
Step #2: Adding the Library to Your Project
Outside of Eclipse
In Our Next Episode…
Options Menus and the Action Bar
Bar Hopping (a.k.a., Terminology)
Android 1.x/2.x
Android 3.0–4.1, Tablets
Android 4.0+, Phones
Android 4.2, Tablets
Yet Another History Lesson
Your Action Bar Options
Pure Native
Base Activity Class
What We Will Be Doing
Setting the Target
Minding Narrow
Defining the Resource
Action Layouts
Applying the Resource
Responding to Events
Attaching to Action Layouts
The Rest of the Sample Activity
Floating Action Bars
Visit the Trails!
Tutorial #7 - Adding the Action Bar
Step #1: Setting the Theme and Splitting the Bar
Outside of Eclipse
Step #2: Changing to SherlockFragmentActivity
Step #3: Defining Some Options
Outside of Eclipse
Step #4: Loading and Responding to Our Options
Step #5: Running the Result
In Our Next Episode…
Android’s Process Model
When Processes Are Created
BACK, HOME, and Your Process
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
Augmenting the Manifest
Warning! Contains Explicit Intents!
Using Implicit Intents
Extra! Extra!
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
Tutorial #8 - Setting Up An Activity
Step #1: Creating the Stub Activity Class
Outside of Eclipse
Step #2: Adding the Activity to the Manifest
Outside of Eclipse
Step #3: Launching Our Activity
In Our Next Episode…
The Tactics of Fragments
The Six Questions
Your First Fragment
The Project
The Fragment Layout
The Fragment Class
The Activity Layout
The Activity Class
The Result
The Fragment Lifecycle Methods
Your First Dynamic Fragment
The ListFragment Class
The Activity Class
The Result
Fragments and the Action Bar
Fragments Within Fragments: Just Say “Maybe”
Fragments and Multiple Activities
Tutorial #9 - Starting Our Fragments
Step #1: Copy In WebViewFragment
Outside of Eclipse
Step #2: Examining WebViewFragment
Step #3: Creating AbstractContentFragment
Outside of Eclipse
Step #4: Examining AbstractContentFragment
In Our Next Episode…
Swiping with ViewPager
Swiping Design Patterns
Paging Fragments
The Prerequisites
The Activity Layout
The Activity
The PagerAdapter
The Fragment
The Result
Paging Other Stuff
PagerTitleStrip and PagerTabStrip
Third-Party Indicators
Fragment-Free Paging
Hosting ViewPager in a Fragment
Pages and the Action Bar
ViewPagers and Scrollable Contents
Tutorial #10 - Rigging Up a ViewPager
Step #1: Add a ViewPager to the Layout
Step #2: Obtaining Our ViewPager
Step #3: Creating a ContentsAdapter
Outside of Eclipse
Step #4: 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
Default Change Behavior
Destroy and Recreate the Activity
Rebuild the Fragments
Recreate the Views
Retain Some Widget State
Your Options for Configuration Changes
Do Nothing
Retain Your Fragments
Model Fragment
Add to the Bundle
Fragments and a Bundle
Retain Other Objects
Blocking Rotations
Dealing with Threads
The Main Application Thread
Getting to the Background
Asyncing Feeling
The Theory
AsyncTask, Generics, and Varargs
The Stages of AsyncTask
A Quick Note About Toasts
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
Requesting Permissions
Mother, May I?
New Permissions in Old Applications
Permissions: Up Front Or Not At All
Signature Permissions
Requiring Permissions
Assets, Files, and Data Parsing
Packaging Files with Your App
Raw Resources
XML Resources
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
When to Write
Letting the User See Your Files
Permissions for External Storage
Limits on External Storage Open Files
Multiple User Accounts
Linux Filesystems: You Sync, You Win
StrictMode: Avoiding Janky Code
XML Parsing Options
JSON Parsing Options
Tutorial #11 - Adding Simple Content
Step #1: Adding Some Content
Step #2: Create a SimpleContentFragment
Outside of Eclipse
Step #3: Examining SimpleContentFragment
Step #4: Using SimpleContentFragment
Step #5: Launching Our Activities, For Real This Time
In Our Next Episode…
Tutorial #12 - Displaying the Book
Step #1: Adding a Book
Step #2: Defining Our Model
Outside of Eclipse
Step #3: Examining Our Model
Step #4: Creating a ModelFragment
Outside of Eclipse
Step #5: Examining the ModelFragment
Step #6: Supplying the Content
Step #7: Adapting the Content
Step #8: Going Home, Again
In Our Next Episode…
Using Preferences
Getting What You Want
Stating Your Preference
Introducing PreferenceActivity
What We Are Aiming For
Defining Your Preferences
Defining Your Preference Headers
Creating Your PreferenceFragments
Creating Your PreferenceActivity
Types of Preferences
CheckBoxPreference and SwitchPreference
ListPreference and MultiSelectListPreference
Intents for Headers or Preferences
Conditional Headers
Option #1: Do Not Define the Headers
Option #2: Go Directly to the Fragment
Tutorial #13 - Using Some Preferences
Step #1: Adding a StockPreferenceFragment
Outside of Eclipse
Step #2: Defining the Preference XML Files
Outside of Eclipse
Step #3: Creating Our PreferenceActivity
Outside of Eclipse
Step #4: Adding To Our Action Bar
Outside of Eclipse
Step #5: Launching the PreferenceActivity
Step #6: Loading Our Preferences
Step #7: Saving the Last-Read Position
Step #8: Restoring the Last-Read Position
Step #9: 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?
Visit the Trails!
Tutorial #14 - Saving Notes
Step #1: Adding a DatabaseHelper
Outside of Eclipse
Step #2: Examining DatabaseHelper
Step #3: Creating a NoteFragment
Outside of Eclipse
Step #4: Examining NoteFragment
Step #5: Creating the NoteActivity
Outside of Eclipse
Step #6: Loading and Saving Notes
Step #7: Add Notes to the Action Bar
Step #8: Support Deleting Notes
In Our Next Episode…
Internet Access
Introducing the Sample
Asking Permission
A Task for Updating
Doing the Internet Thing
Dealing with the Result
Running the Sample
What Android Brings to the Table
Testing with StrictMode
What About HttpClient?
HTTP via DownloadManager
Using Third-Party JARs
Basic SSL Operation
Certificate Verification
Custom TrustManager
Wildcard Certificates
Anti-Pattern: Disabling SSL Certificate Validation
About That Man in the Middle
Disabling SSL Certificate Validation
Ignoring Domain Names
Hacked CAs
Certificate Memorizing
Using HTTP Client Libraries
Downloading and Installing Retrofit
Creating Your Data Model
Creating Your Service Interface
Creating the RestAdapter
Making Requests
The Rest of the Story
Downloading and Installing Picasso
Updating the Model
Requesting the Images
The Rest of the Story
Other Candidate Libraries
Hey, What About Volley?
Intents, Intent Filters, Broadcasts, and Broadcast Receivers
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
Broadcasts and Receivers
Sending a Simple Broadcast
Receiving a Broadcast: In an Activity
Receiving a Broadcast: Via the Manifest
Example System Broadcasts
At Boot Time
On Battery State Changes
Sticky Intents and the Battery
Battery and the Emulator
Downloading Files
The Permissions
The Layout
Requesting the Download
Keeping Track of Download Status
OK, So Why Is This In This Chapter?
What the User Sees
The Order of Things
Keeping It Local
Using LocalBroadcastManager
Reference, Not Value
Limitations of Local
Tutorial #15 - Sharing Your Notes
Step #1: Adding a Share Action Bar Item
Step #2: Sharing the Note
Step #3: Tying Them Together
Step #4: 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
Communicating From Services
Broadcast Intents
Pending Results
Scenario: The Downloader
The Design
Using the Service
The Service Implementation
Receiving the Broadcast
Tutorial #16 - Updating the Book
Step #1: Adding a Stub DownloadCheckService
Outside of Eclipse
Step #2: Tying the Service Into the Action Bar
Step #3: Adding a Stub DownloadCompleteReceiver
Outside of Eclipse
Step #4: Completing the DownloadCheckService
Step #5: Adding a Stub DownloadInstallService
Outside of Eclipse
Step #6: Completing the DownloadCompleteReceiver
Step #7: Completing the DownloadInstallService
Step #8: Updating ModelFragment
Step #9: Adding a BroadcastReceiver to EmPubLiteActivity
Step #10: Discussing the Flaws
In Our Next Episode…
AlarmManager and the Scheduled Service Pattern
Wake Up… Or Not?
Repeating… Or Not?
Inexact… Or Not?
Absolute Time… Or Not?
What Happens (Or Not???)
A Simple Example
The Three Repeat Varieties
The Four Types of Alarms
When to Schedule Alarms
When User First Runs Your App
On Boot
After a Force-Stop
Get Moving, First Thing
The Permission
The Receiver Element
The Receiver Implementation
New Behavior With Android 3.1
Archetype: Scheduled Service Polling
The Main Application Thread Strikes Back
Examining a Sample
Staying Awake at Work
Mind the Gap
The WakefulIntentService
The Polling Archetype, Revisited
How the Magic Works
Warning: Not All Android Devices Play Nice
Debugging Alarms
Tutorial #17 - Periodic Book Updates
Step #1: Adding a Stub UpdateReceiver
Outside of Eclipse
Step #2: Scheduling the Alarms
Step #3: Adding the WakefulIntentService
Step #4: Using WakefulIntentService
Step #5: Completing the UpdateReceiver
In Our Next Episode…
What’s a Notification?
Showing a Simple Notification
Notifications and Foreground Services
Seeking Some Order
The Activity-Or-Notification Scenario
Other Scenarios
Big (and Rich) Notifications
The Styles
The Builders
The Sample
The Results
The Target Requirement
Disabled Notifications
Tutorial #18 - Notifying the User
Step #1: Adding the InstallReceiver
Outside of Eclipse
Step #2: Completing the InstallReceiver
In Our Next Episode…
Large-Screen Strategies and Tactics
Objective: Maximum Gain, Minimum Pain
The Fragment Strategy
Changing Layout
Changing Fragment Mix
The Role of the Activity
Fragment Example: The List-and-Detail Pattern
Describing the App
The Activities
The Results
Other European Flavors
Static CountriesFragment
Going With One Activity
The Revised Layouts
The New onCountrySelected()
The New onCreate()
The “OMG! Our Fragments Have No Views!” Changes
The Results
The Mashup Possibilities
The SlidingPaneLayout Variant
The Role of SlidingPaneLayout
Converting to SlidingPaneLayout
What SlidingPaneLayout Looks Like
Showing More Pages
Columns or Pages
Fragment FAQs
Does Everything Have To Be In a Fragment?
What If Fragments Are Not Right For Me?
Do Fragments Work on Google TV?
Screen Size and Density Tactics
Dimensions and Units
Layouts and Stretching
Drawables That Resize
Drawables By Density
Other Considerations
Small-Screen Devices
Avoid Full-Screen Backgrounds
Manifest Elements for Screen Sizes
Considering Newer Densities
Tutorial #19 - Supporting Large Screens
Step #1: Creating Our Layouts
Outside of Eclipse
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
Another Example: AsyncTask
Keeping Track of Changes
Getting Help
Questions. Sometimes, With Answers.
Heading to the Source
Getting Your News Fix
Introducing GridLayout
Issues with the Classic Containers
Nested Containers
Eclipse Drag-and-Drop
The New Contender: GridLayout
GridLayout and the Android Support Package
Eclipse and GridLayout
Trying to Have Some Rhythm
Our Test App
Replacing the Classics
Horizontal LinearLayout
Vertical LinearLayout
Implicit Rows and Columns
Row and Column Spans
Should You Use GridLayout?
Dialogs and DialogFragments
DatePickerDialog and TimePickerDialog
Changes (and Bugs) in Jelly Bean
DialogFragment: The Other Flavor
Dialogs: Modal, Not Blocking
Advanced ListViews
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
Action Bar Navigation
List Navigation
Tabs (And Sometimes List) Navigation
Custom Navigation
Action Modes and Context Menus
Another Wee Spot O’ History
Manual Action Modes
Choosing Your Trigger
Starting the Action Mode
Implementing the Action Mode
Multiple-Modal-Choice Action Modes
Split Action Modes
What Came Before: Context Menus
Creating a Context Menu
Responding to a Context Menu
Advanced Uses of WebView
Friends with Benefits
Turnabout is Fair Play
Navigating the Waters
Settings, Preferences, and Options (Oh, My!)
The Input Method Framework
Keyboards, Hard and Soft
Tailored To Your Needs
Tell Android Where It Can Go
Fitting In
Jane, Stop This Crazy Thing!
Love The One You’re With
Here a Glyph, There a Glyph
Rich Text
The Span Concept
TextView and Spanned
Available Spans
Loading Rich Text
String Resource
From EditText
Editing Rich Text
Saving Rich Text
Manipulating Rich Text
Mapping with Maps V2
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 Project Setup
The Manifest
The Play Services Detection
The Fragment and Activity
The License
The Result
Playing with the Map
Placing Simple Markers
Sprucing Up Your “Info Windows”
Setting the Marker Icon
Responding to Taps
Dragging Markers
The “Final” Limitations
A Bit More About IPC
Finding the User
Drawing Lines and Areas
Gestures and Controls
Tracking Camera Changes
Maps in Fragments and Pagers
Maps, of the Indoor Variety
MapFragment vs. MapView
Maps and ActionBarSherlock
About That AbstractMapActivity Class…
Getting Maps V2 Ready to Go
Handling the License Terms
Problems with Maps V2 at Runtime
Problems with Maps V2 Deployment
Mapping Alternatives
News and Getting Help
Mapping with the Legacy MapView
Terms, Not of Endearment
Piling On
The Key To It All
The Bare Bones
Optional Maps
Exercising Your Control
Layers Upon Layers
Overlay Classes
Drawing the ItemizedOverlay
Handling Screen Taps
My, Myself, and MyLocationOverlay
Rugged Terrain
Maps and Fragments
Limit Yourself to Android 3.0
Use onCreateView() and onActivityCreated()
Host the Fragment in a MapActivity
Get to the Point
Getting the Latitude and Longitude
Getting the Screen Position
Not-So-Tiny Bubbles
Options for Pop-up Panels
Defining a Panel Layout
Creating a PopupPanel Class
Showing and Hiding the Panel
Tying It Into the Overlay
Sign, Sign, Everywhere a Sign
Selected States
Per-Item Drawables
Changing Drawables Dynamically
In A New York Minute. Or Hopefully a Bit Faster.
A Little Touch of Noo Yawk
Touch Events
Finding an Item
Dragging the Item
Custom Drawables
ScaleDrawable and ClipDrawable
Seeing It In Action
<padding> and <size>
Put a Ring On It
Composite Drawables
XML Drawables and Eclipse
A Stitch In Time Saves Nine
The Name and the Border
Padding and the Box
Stretch Zones
Using Nine-Patch Images
Native Implementation
Backport Via NineOldAndroids
The Foundation: Value and Object Animators
Hardware Acceleration
The Three-Fragment Problem
The ThreePaneLayout
Using the ThreePaneLayout
The Results
The Backport
The Problems
Legacy Animations
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
Crafting Your Own Views
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
Usage and Results
Custom Dialogs and Preferences
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
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
Action Bar Refresh-and-Progress Items
Direct Progress Indication
Advanced Notifications
Custom Views: or How Those Progress Bars Work
Custom Content
Custom Tickers
Seeing It In Action
The Activity
The IntentService
The Builder
The ProgressBar
The Rest of the Story
The Results
Life After Delete
The Mysterious Case of the Missing Number
More Fun with Pagers
ViewPager with Action Bar Tabs
Tying Tabs to Pages
Tying Pages to Tabs
The Results
Using ViewPagerIndicator
Downloading VPI
Replacing PagerTabStrip with TabPageIndicator
Styling the Indicator
Columns for Large, Pages for Small
The Plume Example
The Layouts
The Activity
The Results
The Limitations
Introducing ArrayPagerAdapter
Adding the JAR
Choosing the Package
Creating PageDescriptors
Creating and Populating the Adapter
Modifying the Contents
Other Useful Methods
Columns for Large Landscape, Pages for the Rest
Fragments Inside and Outside the ViewPager
The Revised PagerAdapter
The Revised Activity
Adding, Removing, and Moving Pages
Reviewing the Core Functionality
Add and Split
Inside ArrayPagerAdapter
PageDescriptor and PageEntry
Class Declaration and Generics
Core PagerAdapter Methods
instantiateItem() and destroyItem()
startUpdate() and finishUpdate()
State Management
Content Manipulation and Position Management
Focus Management and Accessibility
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
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
Secondary Screens via a Presentation
A History of Secondary Screens
What is a Presentation?
Playing with Secondary Screens
Detecting Displays
Using DisplayManager
Using MediaRouter
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
Device Support for Presentation
Miscellaneous UI Tricks
Full-Screen and Lights-Out Modes
Android 1.x/2.x
Android 4.0+
Offering a Delayed Timeout
Home Screen App Widgets
East is East, and West is West…
The Big Picture for a Small App Widget
Crafting App Widgets
The Manifest
The Metadata
The Layout
The BroadcastReceiver
The Result
Stock Android 1.x/2.x
Stock Android 3.0+
Another and Another
App Widgets: Their Life and Times
Controlling Your (App Widget’s) Destiny
Change Your Look
One Size May Not Fit All
Lockscreen Widgets
Being a Good Host
Adapter-Based App Widgets
New Widgets for App Widgets
Preview Images
Adapter-Based App Widgets
The AppWidgetProvider
The RemoteViewsService
The RemoteViewsFactory
The Rest of the Story
The Results
Content Provider Theory
Using a Content Provider
Pieces of Me
Getting a Handle
The Database-Style API
Makin’ Queries
Adapting to the Circumstances
Give and Take
The File System-Style API
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 File System-Style API
Issues with Content Providers
Content Provider Implementation Patterns
The Single-Table Database-Backed Content Provider
Step #1: Create a Provider Class
Step #2: Supply a Uri
Step #3: Declare the “Columns”
Step #4: Update the Manifest
The Local-File Content Provider
Step #1: Create the Provider Class
All Those Other Ones
Step #2: Update the Manifest
Using this Provider
The Protected Provider
Step #1: Declare a Permission
Step #2: Use the Permission
Step #3: Protect with the Permission
Step #4: Grant the Permission
The Stream Provider
The Pipes
The Revised openFile()
The Transfer
The Results
The Loader Framework
Cursors: Issues with Management
Introducing the Loader Framework
Honeycomb… Or Not
Using CursorLoader
Using SQLiteCursorLoader
Inside SQLiteCursorLoader
What Else Is Missing?
Issues, Issues, Issues
Loaders Beyond Cursors
Implementation Notes
What Happens When…?
… the Data Behind the Loader Changes?
… the Configuration Changes?
… the Activity is Destroyed?
… the Activity is Stopped?
The ContactsContract Provider
Introducing You to Your Contacts
Organizational Structure
A Look Back at Android 1.6
Pick a Peck of Pickled People
Spin Through Your Contacts
Contact Permissions
Pre-Joined Data
The Sample Activity
Dealing with API Versions
Accessing Contact Information
Makin’ Contacts
The CalendarContract Provider
You Can’t Be a Faker
Do You Have Room on Your Calendar?
The Collections
Calendar Permissions
Querying for Events
Penciling In an Event
Encrypted Storage
Scenarios for Encryption
Obtaining SQLCipher
Employing SQLCipher
SQLCipher Limitations
Passwords and Sessions
About Those Passphrases…
Upgrading to Encryption
Changing Encryption Passphrases
Multi-Factor Authentication
Detecting Failed Logins
Encrypted Preferences
Encryption via Custom SharedPreferences
Encryption via Custom Preference UI and Accessors
Tutorial: Upgrading to SQLCipher
Step #1: Getting Your Starting Point
Step #2: Adding SQLCipher for Android
Step #3: Adding a New Launcher Activity
Outside of Eclipse
Step #4: Collect Passphrase For New Encryption
Step #5: Create or Encrypt the Database
Step #6: Collect Passphrase For Decryption
Packaging and Distributing Data
Packing a Database To Go
Create and Pack the Database
Unpack the Database, With a Little Help(er)
Upgrading Sans Java
Audio Playback
Get Your Media On
MediaPlayer for Audio
Streaming Limitations
Other Ways to Make Noise
Audio Recording
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
Moving Pictures
Using the Camera via 3rd-Party Apps
Being Specific About Features
Still Photos: Letting the Camera App Do It
The Implementation
The Caveats
Scanning with ZXing
Videos: Letting the Camera App Do It
Directly Working with the Camera
Working Directly with the Camera
Basic CameraFragment Usage
Simple CameraFragment Configuration
Controlling the Names and Locations of Output Files
Controlling Which Camera is Used
Controlling FFC Mirror Correction
Handling Exceptions
Wrapping the Preview UI
Core Camera Concepts
The Permission and the Features
A Camera is Optional
A Camera is Required
Other Camera Features
What the Demo Uses
Warning: Do Not Use Yet
The Preview Surface
SurfaceView for the Camera
TextureView for the Camera
What CWAC-Camera Does
Obtaining and Initializing the Camera
Choosing a Camera
Opening and Closing the Camera
Showing the Camera Preview
Configuring the Preview
Starting and Stopping the Preview
Taking a Photo
The Rest of the Demo
Recording a Video
The MediaRecorder Recipe
Recording in CWAC-Camera
Advanced CWAC-Camera Features
Overriding Photo Saving
Controlling the Shutter Callback
Choosing a DeviceProfile
Working Directly with CameraView
Advanced Permissions
Securing Yourself
Enforcing Permissions via the Manifest
Enforcing Permissions Elsewhere
Requiring Standard System Permissions
Signature Permissions
Firmware-Only Permissions
Your Own Signature Permissions
What is Tapjacking?
World War Z (Axis)
Enter the Jackalope
Thinking Like a Malware Author
Detecting Potential Tapjackers
Who Holds a Permission?
Who is Running?
Combining the Two: TJDetect
Defending Against Tapjackers
Filtering Touch Events
Implementing the Filter
The User Experience and the Hoped-For Security
The Flaws
Why Is This Being Discussed?
What Changed in 4.0.3?
Accessing Location-Based Services
Location Providers: They Know Where You’re Hiding
Finding Yourself
On the Move
Are We There Yet? Are We There Yet? Are We There Yet?
Testing… Testing…
Alternative Flavors of Updates
The Fused Option
The Fused Location Provider
Why Use the Fused Location Provider?
Why Not Use the Fused Location Provider?
Finding Our Location, Once
Installing Google Play Services
Attaching Google Play Services
Checking for Google Play Services
Clients, Connections, and Callbacks
Finding the Current Location
Requesting Location Updates
Delivery Options
Request Options
Gaps in the Fused Location Provider
Working with the Clipboard
Using the Clipboard on Android 1.x/2.x
Advanced Clipboard on Android 3.x
Copying Rich Data to the Clipboard
Pasting Rich Data from the Clipboard
ClipData and Drag-and-Drop
Report To The Manager
You Make the Call!
No, Really, You Make the Call!
Working With SMS
Sending Out an SOS, Give or Take a Letter
Sending Via the SMS Client
Sending SMS Directly
Inside the Sender Sample
SMS Sending Limitations
You Can’t Get There From Here
Receiving SMS
Working With Existing Messages
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
Objectives and Scope
Defining and Registering an Admin Component
The Metadata
The Manifest
The Receiver
The Demand for Device Domination
Going Into Lockdown
Mandating Quality of Security
Getting Along with Others
PowerManager and WakeLocks
Keeping the Screen On, UI-Style
The Role of the WakeLock
What WakefulIntentService Does
Push Notifications with GCM
The Precursor: C2DM
The Replacement: GCM
The Re-Replacement: GCM 2013
The Pieces of Push
Play Services Framework
Android App
Custom Permission
Additional Permissions
Your Registration Code
GCM BroadcastReceiver
Your Server (a.k.a., the Thing Doing the Pushing)
Google’s Server and the Google Services Framework
A Simple Push
The Client
The Activity
The Service
The “Server”
Message Options and Advanced Features
Collapse Keys
Pre-Release Features
Cloud Connection Services
Upstream Messages
User Notifications
Considering Encryption
Issues with GCM
Requires Play Services Framework
Requires API Level 8
4K Message Limit
Basic Use of Sensors
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
Other System Settings and Services
Setting Expectations
Basic Settings
Secure Settings
Can You Hear Me Now? OK, How About Now?
Attaching SeekBars to Volume Streams
The Rest of the Gang
Dealing with Different Hardware
Filtering Out Devices
Runtime Capability Detection
Other Capabilities
Dealing with Device Bugs
Responding to URLs
Manifest Modifications
Creating a Custom URL
Reacting to the Link
Plugin Patterns
Definitions, Scenarios, and Scope
The Keys to Any Plugin System
Discovery… By the User
Discovery… By Your App
Scanning with PackageManager
Watching Package-Related Broadcasts
Discovery and Usage of the IPC Endpoints
Component IPC Options
Static Data Options
User Safe from Permission Leakage
Host Safe from Trojans
Case Study: DashClock
What is DashClock?
Discovery… By the User
Discovery… By Your App
Discovery and Usage of the IPC Endpoints
Other Plugin Examples
Plugins by Remote
RemoteViews, Beyond App Widgets
Thinking About Plugins
Finding Available Plugins
Responding to the Call for Plugins
Requesting RemoteViews
Responding with RemoteViews
Dealing with Android 3.1+
The Permission Scheme
Other Plugin Features and Issues
ContentProvider Plugins
The Problem: Permission Creep
A Solution: ContentProvider Proxies
Limitations of the Approach
PackageManager Tricks
Asking Around
Preferred Activities
Middle Management
Finding Applications and Packages
Finding Resources
Finding Components
Searching with SearchManager
Hunting Season
Search Yourself
Craft the Search Activity
Update the Manifest
Searching for Meaning In Randomness
May I Make a Suggestion?
Custom Suggestion Providers
Integrating Suggestion Providers
Putting Yourself (Almost) On Par with Google
Implement a Suggestions Provider
Augment the Metadata
Convince the User
The Results
Handling System Events
I Sense a Connection Between Us…
Feeling Drained
Sticky Intents and the Battery
Battery and the Emulator
Other Power Triggers
Remote Services and the Binding Pattern
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
The Service
The Client
Servicing the Service
Callbacks via AIDL
Revising the Client
Revising the Service
Thinking About Security
The “Everlasting Service” Anti-Pattern
Advanced Manifest Tips
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
Using an Alias
Getting Meta (Data)
Miscellaneous Integration Tips
Take the Shortcut
Registering a Shortcut Provider
Implementing a Shortcut Provider
Using the Shortcuts
Homing Beacons for Intents
Reusable Components
Where Do I Find Them?
How Are They Packaged?
Library Projects
How Do I Create Them?
Standard Library Projects
Binary-Only Library Projects
The Future: AAR
Other Considerations for Publishing Reusable Code
Your License
Third-Party License Impacts
Documenting the Usage
Naming Conventions
The Role of Scripting Languages
All Grown Up
Following the Script
Your Expertise
Your Users’ Expertise
Going Off-Script
Cross-Platform Compatibility
Maturity… On Android
The Scripting Layer for Android
The Role of SL4A
On-Device Development
Getting Started with SL4A
Installing SL4A
Installing Interpreters
Running Supplied Scripts
Writing SL4A Scripts
Editing Options
Calling Into Android
Browsing the API
Running SL4A Scripts
Android 1.x/2.x
Android 3.0+
Other Alternatives
Potential Issues
Security… From Scripts
Security… From Other Apps
JVM Scripting Languages
Languages on Languages
A Brief History of JVM Scripting
Android SDK Limits
Wrong Bytecode
SL4A and JVM Languages
Embedding JVM Languages
Architecture for Embedding
Inside the InterpreterService
The Interpreter Interface
Loading Interpreters and Executing Scripts
Delivering Results
Packaging the InterpreterService
Using the InterpreterService
BeanShell on Android
What is BeanShell?
Getting BeanShell Working on Android
Integrating BeanShell
Rhino on Android
What is Rhino?
Getting Rhino Working on Android
Integrating Rhino
Other JVM Scripting Languages
JUnit and Android
You Get What They Give You
Command Line
Your Test Cases
POJTCs (Plain Old JUnit Test Cases)
Other Test Cases
Your Test Suite
Running Your Tests
Command Line
MonkeyRunner and the Test Monkey
Writing a MonkeyRunner Script
Executing MonkeyRunner
Monkeying Around
Testing with UIAutomator
What Is UIAutomator?
Why Choose UIAutomator Over Alternatives?
Creating Some Tests
Setting Up for Command-Line Builds
Creating the Test Project
Creating a Test Case
Performing Device-Level Actions
Inspecting and Interacting with the UI
Finding and Interaction with Widgets
Dealing with Collections
Finding Widgets By Type
Asserting Conditions
Two Sample Test Methods
Cleaning Up
Running Your Tests
Building and Pushing the JAR
Executing uiautomator
Finding Your Widgets
Limitations of uiautomator
Advanced Emulator Capabilities
x86 Images
Android 4.0.3
Android 2.3.3
Hardware Graphics Acceleration
Old AVDs
New AVDs
Defining New Devices
Keyboard Behavior
Headless Operation
Using Lint
What It Is
When It Runs
What to Fix
What to Configure
Command Line
Using Hierarchy View
Launching Hierarchy View
Viewing the View Hierarchy
Using DDMS
Starting DDMS
File Push and Pull
Location Updates
Placing Calls and Messages
Signing Your App
Role of Code Signing
What Happens In Debug Mode
Creating a Production Signing Key
Signing with the Production Key
Two Types of Key Security
Related Keys
Get Ready To Go To Market
Package Name
Icon and Label
Issues with Speed
Getting Things Done
Your UI Seems… Janky
Not Far Enough in the Background
Playing with Speed
Finding CPU Bottlenecks
What Is Traceview?
Collecting Trace Data
Debug Class
Performance While Tracing
Displaying Trace Data
Standalone Traceview
Interpreting Trace Data
Other General CPU Measurement Techniques
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
Enabling and Collecting a Trace: Eclipse
Viewing and Interpreting the Results
Focus On: NDK
The Role of the NDK
Dalvik: Secure, Yes; Speedy, Not So Much
Going Native
Knowing Your Limits
Android APIs
Cross-Platform Compatibility
Available Expertise
NDK Installation and Project Setup
Installing the NDK
Download and Unpack
Environment Variables
Setting Up an NDK Project
Writing Your C/C++ Code
Writing Your Makefile(s)
Building Your Library
Using Your Library Via JNI
Building and Deploying Your Project
Improving CPU Performance in Java
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
The Case: ThreePaneDemoBC
Are We Janky?
Finding the Source of the Jank
Extraneous Views
Conclusion: Too Many layout() Calls?
Where Things Went Wrong
Removing the Jank
Issues with Bandwidth
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
TrafficStats Basics
Device Statistics
Per-Application Statistics
Interpreting the Results
Example: TrafficMonitor
Using TrafficMonitor
Other Ways to Employ TrafficStats
In Production
During Testing
Measuring Bandwidth Consumption
On-Device Measurement
Yourself, via TrafficStats
Existing Android Applications
Off-Device Measurement
Networking Hardware
Tactical Measurement in DDMS
Being Smarter About Bandwidth
Bandwidth Savings
Classic HTTP Solutions
GZip Encoding
If-Modified-Since / If-None-Match
Binary Payloads
Push versus Poll
Thumbnails and Tiles
Collaborative Bandwidth
Bandwidth Shaping
Driven by Preferences
Driven by Other Usage
Avoiding Metered Connections
Issues with Memory
You Are in a Heap of Trouble
Warning: Contains Graphic Images
In Too Deep (on the Stack)
Finding Memory Leaks with MAT
Setting Up MAT
Getting Heap Dumps
DDMS Perspective
Standalone DDMS
From Code
Automating Heap Dumps in Testing
Basic MAT Operation
Loading Your Dump
Finding Your Objects
Getting Back to Your Roots
Identifying What Else is Floating Around
Some Leaks and Their MAT Analysis
Widget in Static Data Member
Leaked Thread
All Sorts of Bugs
Leaks Via Configuration Changes
Leaks from Unregistered System Listeners
What MAT Won’t Tell You
Issues with Battery Life
You’re Getting Blamed
Stretching Out the Last mWh
Focus On: MDP and Trepn
What Are You Talking About?
What’s an MDP?
What’s a Trepn?
The Big Problem: Cost
Running Trepn Tests
Recording Application States
Examining Trepn Results
Other Power Measurement Options
Battery Screen in Settings Application
BatteryInfo Dump
The Role of Alternative Environments
In the Beginning, There Was Java…
… And It Was OK
Bucking the Trend
Support, Structure
Caveat Developer
Offline Applications
What Does It Mean?
How Do You Use It?
About the Sample App
“Installing” Checklist on Your Phone
Examining the HTML
Examining the Manifest
Web Storage
What Does It Mean?
How Do You Use It?
Web SQL Database
Going To Production
Signing and Distribution
Issues You May Encounter
Android Device Versions
Screen Sizes and Densities
Limited Platform Integration
Performance and Battery
Look and Feel
HTML5: The Baseline
What Is PhoneGap?
What Do You Write In?
What Features Do You Get?
What Do Apps Look Like?
How Does Distribution Work?
What About Other Platforms?
How Is It Licensed?
Using PhoneGap
Creating and Installing Your Project
PhoneGap and the Checklist Sample
Sticking to the Standards
Adding PhoneGap APIs
Set up Device-Ready Event Handler
Use What PhoneGap Gives You
Issues You May Encounter
Screen Sizes and Densities
Look and Feel
For More Information
Other Alternative Environments
Flash, Flex, and AIR
JRuby and Ruboto
App Inventor
Titanium Mobile
Other JVM Compiled Languages
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
Do Not 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: SlidingDrawer
Key Usage Tips
A Sample Usage
Visual Representation
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: Google TV
What Features and Configurations Does It Use?
Screen Size and Density
Input Devices
Other Hardware
What Is Really Different?
The Emulator
Media Keys
Channels and Listings
User Base
Getting Your Development Environment Established
Installing the SDK Add-On
Getting KVM Set Up
Creating the Emulator
Connecting to Physical Devices
How Does Distribution Work?
Getting Your App on Google TV
Supporting Only Google TV
Avoiding Google TV
Dealing with Other Televisions
Getting Help
Device Catalog: OUYA
What Features and Configurations Does It Use?
Screen Size and Density
Input Devices
Other Hardware
Other Resource Set Qualifiers
What Is Really Different?
Internet Access
User Base
Getting Your Development Environment Established
Downloading the ODK
Setting Up a Console
Setting Up the Emulator… Or Something Else
Your OUYA Project
Build Target
“Launcher” Category and Artwork
Detecting an OUYA
How Does Distribution Work?
Getting Help
Device Catalog: Kindle Fire
Introducing the Kindle Fire series
What Features and Configurations Does It Use?
OS Version
Screen Size and Density
Hardware Features
What Is Really Different?
The Menu Bar
Nothing Googly
Sideloading Limitations
Getting Your Development Environment Established
Emulator Configuration
Developing on Hardware
How Does Distribution Work?
Amazon AppStore
Amazon Equivalents of Google Services
Getting Help with the Kindle Fire
Device Catalog: Barnes & Noble NOOK Tablet
What Features and Configurations Does It Use?
Screen Size and Density
Hardware Features
What Is Really Different?
Status/System Bar and Navigation Norms
Nothing Googly
No Side-loading
Toasts to the Top
Unsupported APIs
Getting Your Development Environment Established
Emulator Configuration
Developing on Hardware
How Does Distribution Work?
Device Catalog: RIM Blackberry Playbook
What Features and Configurations Does It Use?
Screen Size and Density
Hardware Features
What Is Really Different?
Nothing Googly
BARs as Packages
Unsupported APIs
Package Name Length
Getting Your Development Environment Established
Checking and Repackaging Your App
Eclipse Plugin
Online Repackager
Command-Line Tools
Playbook Simulator
Developing on Hardware
How Does Distribution Work?
Blackberry App World
Accessory Catalog: SONY SmartWatch
What Can This Thing Really Do?
What Are You Really Writing?
Getting Your Development Environment Established
How Does Distribution Work?
Example: WatchAuth
The ExtensionReceiver
The ExtensionService
The RegistrationInformation
The ControlExtension
Getting the Size
Rendering the UI
Responding to Touch Events
The Permission
Highlights of the Business Logic
The Result
Getting Help
The book hasn't received reviews yet.