ENGLISH

The Busy Coder’s Guide to Android Development 8.12

Book information

Publisher
CommonsWare
ISBN
0981678009
Language
english
Format
PDF
Filesize
76 MB (79497006 bytes)
Series
The Busy Coder’s Guide to Android Development
Pages
4301\4301
Topic
Computers\\Programming
Time added
2018-08-14 05:59:38

Description

Do you want current information about how to develop Android apps? This book covers the latest Android Studio version and the latest version of Android, plus all the information you need to get your apps working on older devices. This book contains over 200 chapters, covering everything from the first steps in getting an app going to advanced development techniques. The core chapters — representing ~900 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 18 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. Table of Contents......Page 4 The Book’s Structure......Page 46 Testing......Page 47 Advanced UI......Page 48 Data Storage and Retrieval......Page 49 Hardware and System Services......Page 50 Tuning Android Applications......Page 51 Appendices......Page 52 What’s New in Version 8.12?......Page 53 Warescription......Page 54 Book Bug Bounty......Page 55 Source Code and Its License......Page 56 Acknowledgments......Page 57 Android Applications......Page 62 Programming Language......Page 63 Activities......Page 64 Broadcast Receivers......Page 65 Widgets, Containers, and Resources......Page 66 Android Devices......Page 67 The Emulator......Page 68 OS Versions and API Levels......Page 69 Dalvik and ART......Page 70 Don’t Be Scared......Page 71 Eclipse......Page 72 Yet Other Alternatives......Page 73 App Inventor......Page 74 App Generators......Page 75 But First, Some Notes About Android’s Emulator......Page 76 Step #1: Checking Your Hardware......Page 77 Step #3: Install Android Studio......Page 78 Step #4: Install the SDKs and Add-Ons......Page 80 Using SDK Manager and Updating Your Environment......Page 87 In Our Next Episode…......Page 88 Creating a New Project......Page 90 Importing a Project......Page 95 Starter Project Generators......Page 96 About Our Tutorial Project......Page 98 Step #1: Importing the Project......Page 99 Windows......Page 103 Step #3: Set Up the AVD......Page 104 Step #4: Set Up the Device......Page 111 Standard Android Driver......Page 114 macOS and Linux......Page 115 Step #5: Running the Project......Page 116 In Our Next Episode…......Page 118 Navigating The Project Explorer......Page 120 Classic Project View......Page 121 Opening Files from the Explorer......Page 122 The Basics......Page 123 Build View......Page 124 Logcat......Page 125 SDK and AVD Managers......Page 126 Android Studio and Release Channels......Page 127 Visit the Trails!......Page 129 The Modules......Page 130 The Java......Page 131 The Build Instructions......Page 132 The App Directory......Page 133 The Source Sets......Page 134 What You Get Out Of It......Page 135 What is Gradle?......Page 136 What is Groovy?......Page 137 Direct Installation......Page 138 The gradlew Wrapper......Page 139 Versions of Gradle and the Android Gradle Plugin......Page 140 The Project-Level File......Page 141 buildscript......Page 142 The Module-Level Gradle File......Page 143 Introducing the Manifest......Page 144 Package Name and Application ID......Page 145 minSdkVersion and targetSdkVersion......Page 146 Other Gradle Items of Note......Page 147 An Application For Your Application......Page 148 Supporting Multiple Screens......Page 149 Other Stuff......Page 150 Visit the Trails!......Page 151 Step #1: Supporting Screens......Page 152 Step #3: Ignoring Lint......Page 153 In Our Next Episode…......Page 155 String Theory......Page 156 Plain Strings......Page 157 Um, Wait, My Manifest Does Not Look Like That......Page 158 Styled Text......Page 160 Multi-Locale Support......Page 161 Got the Picture?......Page 162 Some Notes About WebP......Page 165 Dimensions......Page 166 Editing Dimension Resources......Page 167 The Resource That Shall Not Be Named… Yet......Page 168 App Icons… And Everything Else......Page 170 Creating an App Icon with the Asset Studio......Page 171 Foreground Layer......Page 172 Background Layer......Page 173 Legacy......Page 174 Generating the Icon......Page 175 Creating Other Icons with the Asset Studio......Page 176 Step #1: Changing the Name......Page 178 Step #2: Changing the Icon......Page 179 Step #3: Running the Result......Page 183 In Our Next Episode…......Page 184 What Are Widgets?......Page 186 What Are Containers?......Page 188 The Absolute Positioning Anti-Pattern......Page 189 The Theme of This Section: Themes......Page 190 Holo, There!......Page 191 Considering the Material......Page 192 Doing More with Themes......Page 193 The Activity......Page 194 Dissecting the Activity......Page 195 What Is an XML-Based Layout?......Page 196 Why Use XML-Based Layouts?......Page 198 Using Layouts from Java......Page 199 Widgets and Attributes......Page 200 The Curious Case of the Cast......Page 201 Size......Page 202 Palette......Page 203 Preview......Page 204 Blueprint......Page 205 Upper Right Toolbar......Page 207 Attributes......Page 208 Text Tab......Page 211 And Now, Some Notes About the Book’s Sample Projects......Page 212 Assigning Labels......Page 213 Editing the Text......Page 214 Editing the ID......Page 216 Notable TextView Attributes......Page 217 A Commanding Button......Page 218 Android Studio Graphical Layout Editor......Page 219 Tracking Button Clicks......Page 220 Fleeting Images......Page 221 Android Studio Graphical Layout Editor......Page 222 Scaling Images......Page 224 Fields of Green. Or Other Colors.......Page 227 Android Studio Graphical Layout Editor......Page 228 Notable EditText Attributes......Page 229 Padding......Page 230 Colors......Page 231 Useful Methods......Page 232 Visit the Trails!......Page 233 Debugging Your App......Page 234 Logcat in Android Studio......Page 235 The Case of the Confounding Class Cast......Page 236 Point Break......Page 237 Introducing the Sampler App......Page 238 RTL and Your Layouts......Page 239 Orientation......Page 240 Weight......Page 241 Gravity......Page 242 Android Studio Graphical Layout Editor......Page 243 The XML......Page 244 Android Studio Graphical Layout Editor......Page 246 The XML......Page 248 Android Studio Graphical Layout Editor......Page 249 Example: URL Dialog......Page 250 The XML......Page 251 Android Studio Graphical Layout Editor......Page 253 The XML......Page 261 Android Studio Graphical Layout Editor......Page 263 All Things Are Relative......Page 264 Relative Notation in Attributes......Page 265 Positions Relative to Other Widgets......Page 266 Android Studio Graphical Layout Editor......Page 267 The XML......Page 268 Android Studio Graphical Layout Editor......Page 269 Example: URL Dialog......Page 271 Example: Overlap......Page 273 Putting Cells in Rows......Page 275 Non-Row Children of TableLayout......Page 276 Stretch, Shrink, and Collapse......Page 277 Example: A Bigger Form......Page 278 Example: URL Dialog......Page 280 Hey, What About ConstraintLayout?......Page 281 Turning Back to RTL......Page 282 Just a Box to Check......Page 284 Android Studio Graphical Layout Editor......Page 286 Don’t Like Checkboxes? How About Toggles or Switches?......Page 287 Turn the Radio Up......Page 291 Android Studio Graphical Layout Editor......Page 293 Scrollwork......Page 294 Making Progress with ProgressBars......Page 297 Framing the Scene......Page 298 Visit the Trails!......Page 299 Step #1: Creating a New Layout Resource......Page 300 Step #2: Defining the UI......Page 301 In Our Next Episode…......Page 305 Making Your Selection......Page 306 Including Includes......Page 307 Preview of Coming Attractions......Page 309 AdapterViews and Adapters......Page 310 Using ArrayAdapter......Page 311 Lists of Naughty and Nice......Page 312 Choice Modes......Page 315 Clicks versus Selections, Revisited......Page 317 Spin Control......Page 318 Grid Your Lions (Or Something Like That…)......Page 321 Fields: Now With 35% Less Typing!......Page 325 Customizing the Adapter......Page 329 Step #1: Design Your Row......Page 330 Step #2: Extend ArrayAdapter......Page 331 Step #3: Override the Constructor and getView()......Page 332 Optimizing with the ViewHolder Pattern......Page 334 Dealing with Multiple Row Layouts......Page 337 Visit the Trails!......Page 338 Role of WebView......Page 340 Adding the Widget......Page 341 Loading Content Via a URL......Page 342 Supporting JavaScript......Page 344 Alternatives for Loading Content......Page 345 Listening for Events......Page 346 Addressing the Link/Redirect Behavior......Page 349 Safe Browsing......Page 351 Visit the Trails!......Page 352 Styles: DIY DRY......Page 354 Where to Apply a Style......Page 356 Inheriting a Style......Page 357 The Possible Values......Page 358 Themes: Would a Style By Any Other Name…......Page 359 Android Studio’s Theme Editor......Page 360 What’s a Dependency?......Page 366 Dependency Scopes......Page 367 Depending on a Local JAR......Page 368 Major Library Families from Google......Page 369 Configure the Repositories......Page 370 Identify the Dependencies and Versions......Page 371 Add the Dependencies......Page 372 About the Names......Page 373 Choosing a Version......Page 374 Attaching It To Your Project......Page 375 Step #1: Getting Rid of Existing Cruft......Page 378 Step #2: Requesting New Dependencies......Page 379 In Our Next Episode…......Page 381 Drag-and-Drop GUI Builders......Page 382 Performance......Page 383 Getting ConstraintLayout......Page 384 Using a ConstraintLayout......Page 385 The XML......Page 386 The Android Studio Graphical Layout Editor......Page 388 Basic Anchoring, Dual Axis......Page 393 Playing the Percentages......Page 396 Converting Existing Layouts......Page 399 Visit the Trails!......Page 400 RecyclerView......Page 402 Enter RecyclerView......Page 403 A Trivial List......Page 404 A RecyclerViewActivity......Page 405 The LayoutManager......Page 407 The Adapter......Page 408 The ViewHolder......Page 409 The Results......Page 410 What’s Missing?......Page 411 CardView......Page 412 Manual......Page 414 DividerItemDecoration......Page 415 DIY Decorators......Page 416 Handling Click Events......Page 419 Responding to Clicks......Page 420 Visual Impact of Clicks......Page 421 Option #1: Translucent Selector on Top......Page 422 Option #2: Background Selector......Page 423 Option #3: Controlled Ripple Emanation Point......Page 425 Visit the Trails!......Page 426 Android 1.x/2.x......Page 428 Android 3.0-4.1, Tablets......Page 429 Android 4.0-4.4, Phones......Page 431 Android 4.2-4.4, Tablets......Page 432 Android 5.0+......Page 433 Yet Another History Lesson......Page 434 Your Action Bar Options......Page 435 A Quick Note About Toasts......Page 436 Setting the Target......Page 437 Defining the Resource......Page 438 A Quick Note About Android Studio......Page 440 Responding to Events......Page 441 The Rest of the Sample Activity......Page 442 MENU Key, We Hardly Knew Ye......Page 448 Material Tint Effects......Page 449 Color Resources......Page 450 Applying the Theme......Page 451 The Results......Page 452 Restoring the Icon (Sort Of)......Page 453 Action Bar Style Generator......Page 454 Designing the Scheme......Page 455 Implementing the Scheme......Page 457 Visit the Trails!......Page 459 Getting the Artwork......Page 460 Android Studio Vector Asset Wizard......Page 461 Using the Artwork......Page 464 VectorDrawableCompat......Page 465 Gradle Configuration......Page 466 Use in Java......Page 467 Step #1: Adding Some Icons......Page 472 Step #2: Defining Some Options......Page 474 Step #3: Loading and Responding to Our Options......Page 477 Step #4: Supporting Older Devices......Page 478 Step #5: Trying It Out......Page 479 In Our Next Episode…......Page 481 When Processes Are Created......Page 482 BACK, HOME, and Your Process......Page 483 Termination......Page 484 You and Your Heap......Page 485 Activities and Their Lifecycles......Page 486 Defining the Class and Resources......Page 487 Populating the Class and Resources......Page 489 Augmenting the Manifest......Page 490 Warning! Contains Explicit Intents!......Page 491 Using Implicit Intents......Page 493 Where Do We Get These Uri Values?......Page 498 Extra! Extra!......Page 499 Pondering Parcelable......Page 500 Schroedinger’s Activity......Page 502 onCreate() and onDestroy()......Page 503 onPause() and onResume()......Page 504 When Activities Die......Page 505 Walking Through the Lifecycle......Page 506 Recycling Activities......Page 509 Application: Transcending the Activity......Page 510 The Case of the Invisible Activity......Page 511 Step #1: Creating the Stub Activity Class and Manifest Entry......Page 514 Step #2: Launching Our Activity......Page 516 In Our Next Episode…......Page 517 What?......Page 518 WHY?!?!?......Page 519 Screen Sizes......Page 520 Where You Get Your Fragments From......Page 521 The Fragment Layout......Page 522 The Fragment Class......Page 523 The Activity Layout......Page 524 The Activity Class......Page 525 The Fragment Lifecycle Methods......Page 526 onAttach() Versus onAttach()......Page 527 The ListFragment Class......Page 528 The Activity Class......Page 529 Fragments and the Action Bar......Page 531 Step #1: Create a SimpleContentFragment......Page 534 Step #2: Examining SimpleContentFragment......Page 536 In Our Next Episode…......Page 537 Pieces of a Pager......Page 538 The Activity......Page 539 The PagerAdapter......Page 540 The Fragment......Page 541 The Result......Page 542 Indicators......Page 544 PagerTitleStrip and PagerTabStrip......Page 545 Revisiting the Containers Sampler......Page 548 The Data......Page 549 The Fragment......Page 551 The Activity......Page 552 The PagerAdapter......Page 553 Visit the Trails!......Page 554 Step #1: Add a ViewPager to the Layout......Page 556 Step #2: Creating a ContentsAdapter......Page 557 Step #3: Setting Up the ViewPager......Page 558 In Our Next Episode…......Page 561 What’s a Configuration? And How Do They Change?......Page 562 Configurations and Resource Sets......Page 563 Screen Size and Orientation......Page 564 The Modern: Developer-Defined Buckets......Page 565 About That API Level......Page 566 Coping with Complexity......Page 567 Choosing The Right Resource......Page 568 Scenario #2: Disparate Resource Set Categories......Page 569 Scenario #5: Screen Density......Page 570 Scenario #6: Screen Sizes......Page 571 Use Case: Themes by API Level......Page 572 Destroy and Recreate the Activity......Page 574 Retain Some Widget State......Page 575 State Saving Scenarios......Page 576 Do Nothing......Page 577 Retain Your Fragments......Page 578 Model Fragment......Page 583 Add to the Bundle......Page 584 Fragments and a Bundle......Page 586 onRetainNonConfigurationInstance()......Page 587 DIY......Page 589 Blocking Rotations......Page 591 And Now, a Word From the Android Project View......Page 592 Multi-Locale Support......Page 593 Screen Zoom/Dynamic Density......Page 594 Basic Tinting Options......Page 598 Official Google-Approved Colors......Page 603 The Main Application Thread......Page 604 The Theory......Page 606 The Stages of AsyncTask......Page 607 A Sample Task......Page 608 The Fragment and its AsyncTask......Page 609 The Activity and the Results......Page 613 Where Not to Use AsyncTask......Page 614 About the AsyncTask Thread Pool......Page 615 Alternatives to AsyncTask......Page 616 Event Buses......Page 618 What Is an Event Bus?......Page 619 Requesting the Artifact......Page 620 Defining Events......Page 621 Posting Events......Page 622 Receiving Events......Page 623 The Activity......Page 625 Visit the Trails!......Page 627 Requesting Permissions......Page 628 What Are Some Common Permissions, and What Do They Defend?......Page 629 How Do I Request a Permission?......Page 630 Installing Through SDK Tools......Page 631 Installing from the Play Store, Android 6.0+......Page 632 Installing by Other Means, Android 6.0+......Page 633 Name......Page 634 Dangerous......Page 635 Minimum SDK Version......Page 636 New Permissions in Old Applications......Page 637 What Permissions Are Affected By This?......Page 638 How Do I Know If I Have Permission?......Page 639 How Do I Ask the User For Permission?......Page 642 When Do I Not Ask the User For Permission?......Page 645 What Do I Do If the User Says “No, And Please Stop Asking”?......Page 646 What Happens When My App Has a Lower Target SDK Version?......Page 648 Should I Be Using PermissionChecker?......Page 649 Examining the Protocol......Page 650 Requesting the Permission......Page 651 Handling the Result......Page 652 Dealing with (Configuration) Change......Page 653 Raw Resources......Page 654 Assets......Page 655 Internal vs. External......Page 656 Working with Internal Storage......Page 657 Where to Write......Page 665 Relevant Permissions......Page 666 When to Write......Page 669 Letting the User See Your Files......Page 670 Limits on External Storage Open Files......Page 671 The Workarounds......Page 672 Linux Filesystems: You Sync, You Win......Page 673 StrictMode: Avoiding Janky Code......Page 675 Mounting as a Drive......Page 677 Browsing Files Via Android Studio......Page 678 Push and Pull for External Storage......Page 682 Run-As for Internal Storage......Page 684 XML Parsing Options......Page 685 Using Files with Implicit Intents......Page 686 Visit the Trails!......Page 687 Step #1: Adding Some Content......Page 688 Step #2: Using SimpleContentFragment......Page 689 Step #3: Launching Our Activities, For Real This Time......Page 690 Step #4: Getting a Bit More Material......Page 691 Step #5: Seeing the Results......Page 693 In Our Next Episode…......Page 695 Step #1: Adding a Book......Page 696 Step #2: Creating a ModelFragment......Page 697 Step #3: Defining Our Model......Page 698 Step #5: Defining Our Event......Page 700 Step #6: Loading Our Model......Page 701 Step #7: Registering for Events......Page 704 Step #8: Adapting the Content......Page 705 Step #9: Showing the Content When Loaded......Page 706 Step #10: Attaching our ModelFragment......Page 707 Step #11: Showing the Content After a Configuration Change......Page 708 Step #12: Setting Up StrictMode......Page 709 In Our Next Episode…......Page 710 Getting What You Want......Page 712 Stating Your Preference......Page 713 Showing the Current Values......Page 714 Defining Your Preferences......Page 717 Creating Your PreferenceFragment......Page 719 The Results......Page 720 Android Studio’s Preferences Editor......Page 721 CheckBoxPreference and SwitchPreference......Page 722 EditTextPreference......Page 723 RingtonePreference......Page 724 ListPreference and MultiSelectListPreference......Page 725 Step #1: Defining the Preference XML Files......Page 728 Step #2: Creating Our Preference Activity......Page 732 Step #4: Launching the Preference Activity......Page 733 Step #5: Loading the Preferences......Page 736 Step #6: Saving the Last-Read Position......Page 740 Step #7: Restoring the Last-Read Position......Page 741 Step #8: Keeping the Screen On......Page 742 In Our Next Episode…......Page 744 Introducing SQLite......Page 746 Start with a Helper......Page 747 Employing Your Helper......Page 751 Getting Data Out......Page 752 Your Query Options......Page 753 Using the Cursor Manually......Page 754 Introducing CursorAdapter......Page 755 Getting Data Out, Asynchronously......Page 757 The Primary Option: execSQL()......Page 759 Alternative Options......Page 760 Asynchronous CRUD and UI Updates......Page 761 Setting Transaction Bounds......Page 764 Visit the Trails!......Page 765 Step #1: Adding a DatabaseHelper......Page 768 Step #2: Examining DatabaseHelper......Page 769 Step #3: Creating a NoteFragment......Page 770 Step #5: Creating the NoteActivity......Page 771 Step #6: Examining NoteActivity......Page 772 Step #7: Add Notes to the Action Bar......Page 773 Step #8: Defining a NoteLoadedEvent......Page 775 Step #9: Loading a Note from the Database......Page 776 Step #10: Loading the Note Into the Fragment......Page 777 Step #11: Updating the Database......Page 778 Step #12: Saving the Note......Page 779 Step #13: Adding a Delete Action Bar Item......Page 781 Step #14: Closing the NoteFragment When Deleted......Page 784 In Our Next Episode…......Page 789 DIY HTTP......Page 790 Creating Your Data Model......Page 791 A Thread for Loading......Page 794 A Fragment for Questions......Page 795 An Activity for Orchestration......Page 798 What Android Brings to the Table......Page 799 What About HttpClient?......Page 800 Using Third-Party Libraries......Page 801 Using HTTP Client Libraries......Page 802 OkHttp......Page 803 Dependencies......Page 806 Creating the Interface......Page 807 Making the Request......Page 808 Downloading and Installing Picasso......Page 810 Updating the Model......Page 811 Requesting the Images......Page 812 The Rest of the Story......Page 813 Volley......Page 814 Making a Manager......Page 815 Requesting JSON......Page 817 Requesting Images......Page 820 Other Candidate Libraries......Page 823 Visit the Trails......Page 824 Pieces of Intents......Page 826 Intent Routing......Page 827 Responding to Implicit Intents......Page 828 Requesting Implicit Intents......Page 831 Many Matches, Default Behavior......Page 832 The Chooser Override......Page 833 ShareActionProvider......Page 835 Practice Safe Content Resolution......Page 838 Receiving a Broadcast: In an Activity......Page 840 Receiving a Broadcast: Via the Manifest......Page 841 Getting Out of the Stopped State......Page 842 At Boot Time......Page 843 On Battery State Changes......Page 845 Sticky Broadcasts and the Battery......Page 850 Battery and the Emulator......Page 851 The Order of Things......Page 852 Visit the Trails!......Page 853 Step #1: Adding a ShareActionProvider......Page 854 Step #2: Sharing the Note......Page 855 Step #3: Testing the Result......Page 857 In Our Next Episode…......Page 860 Why Services?......Page 862 The Service Class......Page 863 Lifecycle Methods......Page 864 Manifest Entry......Page 865 Sending Commands with startService()......Page 866 Binding to Services......Page 867 The Service Implementation......Page 868 Using the Service......Page 870 The Power of the PendingIntent......Page 871 How Do We Create One?......Page 872 Why Not Just Pass the Intent?......Page 873 Broadcast Intents......Page 874 Messenger......Page 875 The Design......Page 876 Using the Service......Page 877 The Service Implementation......Page 879 Receiving the Broadcast......Page 882 JobIntentService......Page 883 Services and Configuration Changes......Page 887 Scenario #1: You Stop It......Page 888 Scenario #4: Automatically, After a Minute......Page 889 What Happens?......Page 890 What Are the Alternatives?......Page 892 Step #1: Adding a Stub DownloadCheckService......Page 894 Step #2: Tying the Service Into the Action Bar......Page 895 Step #4: Defining Our JSON......Page 897 Step #5: Defining Our Retrofit Interface......Page 898 Step #6: Retrieving Our JSON Via Retrofit......Page 899 Step #7: Downloading the Update......Page 901 Step #8: Unpacking the Update......Page 902 Step #9: Using the Update......Page 906 In Our Next Episode…......Page 911 Step #1: Creating Our Layouts......Page 912 Step #2: Loading Our Sidebar Widgets......Page 916 Step #3: Opening the Sidebar......Page 917 Step #4: Loading Content Into the Sidebar......Page 918 Step #5: Removing Content From the Sidebar......Page 921 Think Forwards, Not Backwards......Page 928 A Target-Rich Environment......Page 930 Lint: It’s Not Just For Belly Buttons......Page 931 Avoid the New on the Old......Page 932 @TargetAPI......Page 933 Resources......Page 934 Components......Page 935 Keeping Track of Changes......Page 936 What is a System Service?......Page 938 What System Services Are There?......Page 939 …From the Standpoint of Developers?......Page 942 What Is In the Play Services SDK?......Page 943 Google Account Login / Sign In with Google......Page 944 Google Cast......Page 945 Google Cloud Messaging......Page 946 Google Fit......Page 947 Google Mobile Ads / AdMob......Page 948 SafetyNet......Page 949 The Metadata......Page 950 Detecting If We Have Permission......Page 951 Requesting Permissions......Page 952 Handling the Result......Page 953 Checking for Play Services......Page 954 Initializing the GoogleApiClient......Page 955 Connecting and Disconnecting......Page 957 Questions. Sometimes, With Answers.......Page 960 Heading to the Source......Page 961 Creating a Library Module......Page 964 Library Modules and the Manifest......Page 967 Library Modules and Transitive Dependencies......Page 968 Limitations of Library Modules......Page 969 Key Build-Related Tasks......Page 970 Results......Page 973 Objectives of the Project Structure......Page 974 Source Sets......Page 975 Product Flavors......Page 976 Build Variants......Page 977 Source Sets......Page 978 build.gradle Settings......Page 979 Order of Precedence......Page 981 Adding Product Flavors and Getting Build Variants......Page 982 Scoping Your Splits......Page 984 Requesting Density Splits......Page 985 The Build Variants View......Page 986 The Android Project View......Page 987 Flavors, Build Types, and the Project Structure Dialog......Page 988 Manifest Scenarios......Page 990 App Manifest and Product Flavors......Page 991 Markers and Selectors......Page 992 Placeholders......Page 993 Viewing Merged Manifests in Android Studio......Page 994 Merging Elements and Attributes......Page 995 Example #1: Manifest Attributes......Page 996 Example #2: Additional Permissions......Page 998 Example #3: Additional Components......Page 999 Example #4: Intent Filter......Page 1000 uses-sdk......Page 1001 Markers and Selectors......Page 1002 Employing Placeholders......Page 1005 Role of Code Signing......Page 1010 Synchronizing Your Debug Signing Key......Page 1011 Manually......Page 1012 Android Studio......Page 1014 Gradle......Page 1016 Two Types of Key Security......Page 1018 Versioning......Page 1020 Logging......Page 1021 EULA......Page 1023 Customizing a Gradle Build......Page 1026 Code Generation......Page 1027 Writing a Plugin......Page 1028 Create a Java Module......Page 1029 Apply the Groovy Plugin......Page 1030 Add a Groovy Source Directory and Package......Page 1031 Implement a Plugin......Page 1032 Using Both Groovy and Java......Page 1033 Adding Plugin Metadata......Page 1034 Distributing the Plugin......Page 1035 Using the Plugin......Page 1037 Trying the Sample App......Page 1040 Integrating with the Android Plugin......Page 1041 Writing a Task Class......Page 1042 Splicing Your Task Into the Build......Page 1043 Configuring the Plugin......Page 1044 What Drives the Custom Code?......Page 1046 Other Project Files......Page 1047 Java as Poetry......Page 1048 Writing a Code Generation Plugin......Page 1049 Designing the Output......Page 1050 Crafting the Plugin......Page 1051 Writing the Task......Page 1054 Generating Java Code......Page 1056 Using the Generated Code......Page 1060 It’s build.gradle All The Way Down......Page 1062 gradle.properties......Page 1063 Custom Properties Files......Page 1064 Auto-Incrementing the versionCode......Page 1065 Adding to BuildConfig......Page 1067 Instrumentation Tests and Unit Tests......Page 1072 Where Your Test Code Runs......Page 1073 The Test Methods......Page 1074 Setup and Teardown......Page 1075 Testing Activities......Page 1077 Testing Context-Dependent Code......Page 1078 The Test Runner......Page 1080 Android Studio Ad-Hoc Test Runs......Page 1081 Android Studio Run Configuration......Page 1082 Examining the Test Results......Page 1084 Testing and Runtime Permissions......Page 1086 The Android Test Orchestrator......Page 1087 Prerequisites......Page 1092 Adding a Shot of Espresso......Page 1093 Finding Widgets via Hamcrest Matchers......Page 1095 Performing Actions......Page 1096 Validating via Assertions… And Possibly More Matchers......Page 1097 Custom Assertions......Page 1098 Starting and Recording......Page 1101 Is This Worthwhile?......Page 1105 Testing AdapterView......Page 1106 Testing RecyclerView......Page 1107 Intent Testing......Page 1110 Testing Activity Re-Creation and Configuration Changes......Page 1113 Waiting for the World to Change......Page 1116 What’s an IdlingResource?......Page 1117 Using an IdlingResource......Page 1118 Implementing a Custom IdlingResource......Page 1121 Why Choose UI Automator Over Alternatives?......Page 1122 Gradle and Android Studio Settings......Page 1123 Performing Device-Level Actions......Page 1124 Starting Your Activity......Page 1125 UiSelector......Page 1126 UiObject, UiCollection, and UiScrollable......Page 1127 Asserting Conditions......Page 1128 Finding Your Widgets......Page 1129 Using the UI Automator Viewer......Page 1130 Who Tests the Testers?......Page 1134 Branch Coverage......Page 1135 Loop Coverage......Page 1136 Coverage and Your Instrumentation Tests......Page 1137 Prerequisites......Page 1142 Scenario: Clean Architecture......Page 1143 Setting Up Unit Testing......Page 1144 Adding the Test JUnit Dependency......Page 1145 Adding the Test Package......Page 1146 Writing a Test Case......Page 1147 Running Unit Tests......Page 1150 From Android Studio......Page 1151 From the Command Line......Page 1153 Why Are We Being Mean to Android?......Page 1154 Why Mockito?......Page 1155 Setting Up Mockito......Page 1156 Using Mockito in Unit Tests......Page 1157 Robolectric......Page 1162 Choosing an API Level......Page 1163 Writing Robolectric Tests......Page 1164 Running Robolectric Tests......Page 1166 OK, So, Why Bother?......Page 1167 MonkeyRunner......Page 1168 Writing a MonkeyRunner Script......Page 1169 Monkeying Around......Page 1170 Prerequisites......Page 1176 The Basic Idea......Page 1177 Using Lambda Expressions......Page 1178 Enabling Lambda Expressions......Page 1179 Replacing Listeners with Lambdas......Page 1180 Alternative: Method References......Page 1182 Life is But a Stream......Page 1186 Action and Reaction......Page 1188 A Rx For What Ails You......Page 1189 A Simple Stream......Page 1190 Replacing the Loop......Page 1191 Be Your Own Stream......Page 1193 Removing the AsyncTask......Page 1194 observeOn()......Page 1198 subscribe()......Page 1199 Lambdas and Lifetimes......Page 1200 Streaming from a Resource......Page 1201 Error Handling......Page 1202 Transmogrification......Page 1203 Rx-Enabled Libraries......Page 1204 Further Reading......Page 1206 What About LiveData?......Page 1207 What’s a Notification?......Page 1210 Showing a Simple Notification......Page 1213 The Activity-Or-Notification Scenario......Page 1219 The Styles......Page 1220 The Sample......Page 1223 The Results......Page 1226 Isn’t “Foreground Service” an Oxymoron?......Page 1227 Putting Your Service in the Foreground......Page 1228 Disabled Notifications......Page 1230 Android 4.x......Page 1231 Android 5.0+......Page 1232 Android 8.0+......Page 1233 Being a Good Citizen......Page 1234 What You Do with Channels......Page 1235 Creating Channel Groups......Page 1236 Creating Channels......Page 1237 What the User Sees......Page 1239 Backwards Compatibility......Page 1241 Simple Notification......Page 1242 “Big” Style and Action Button......Page 1244 Foreground Service......Page 1246 Stacking Notifications......Page 1247 …And the Passage of Time......Page 1252 Avoiding Wear......Page 1253 Pages......Page 1254 Wear-Only Actions......Page 1257 The Activity and Notification......Page 1262 The Receiver......Page 1264 The Results......Page 1266 Remote Input, On-Device......Page 1268 Notification Groups......Page 1273 Lockscreen Notifications......Page 1275 Public Notifications......Page 1278 A Visibility Sample......Page 1279 Priority, Importance, and Heads-Up Notifications......Page 1284 Specifying the Priority......Page 1285 Results on Older Devices......Page 1286 Requesting Full-Screen Output......Page 1287 Results on Android 3.0-4.4 Devices......Page 1288 Progress Notifications......Page 1289 Everything but the Icky Parts......Page 1290 The Interceptor......Page 1292 The ProgressResponseBody......Page 1294 Updating the Notification......Page 1296 What If We Had an Activity in the Foreground?......Page 1297 The Notification Layout......Page 1298 Using the Layout......Page 1299 Styling Custom Views......Page 1301 Notifications and MessagingStyle......Page 1302 Changes in API Level 23......Page 1308 Sounds and Android 7.0......Page 1309 Launcher Icon Badge......Page 1310 A History of Windows......Page 1314 What The User Sees......Page 1315 What Your Code Sees......Page 1317 Opting In......Page 1319 Configuring the Layout......Page 1320 Avoiding Stutter......Page 1322 Handling the Screen Size Transition......Page 1323 Parallel Processing......Page 1324 Split-Screen, HOME, and Your Activity......Page 1326 Forcing Your App Into Multi-Window/Multi-Instance......Page 1327 Using Sidecar......Page 1328 Choosing the Activity......Page 1329 Implementing the TileService......Page 1331 Forcing Activities to Resize......Page 1333 Breaking the Sidecar......Page 1334 Supporting Legacy Proprietary Multi-Window......Page 1335 Playing with Freeform......Page 1338 The adb Setting......Page 1339 The Freecar App......Page 1342 Freeform and Your App......Page 1344 Picture-in-Picture......Page 1345 Multi-Display Support......Page 1349 Guidelines......Page 1358 Barriers to Entry......Page 1362 Disclosing Your Bias......Page 1367 Centering Yourself......Page 1373 Keeping Things Proportional......Page 1377 …of Children of the ConstraintLayout......Page 1378 …of the ConstraintLayout Itself......Page 1381 How Do We Set up a Chain?......Page 1383 Spread......Page 1384 Chains and Biases......Page 1385 Chains and Weights......Page 1386 What If We’re GONE?......Page 1387 Going in a Circle......Page 1388 Groups of Views… But Not ViewGroups......Page 1391 Nested Containers......Page 1396 Drag-and-Drop......Page 1397 GridLayout and the Android Support Package......Page 1398 Our Test App......Page 1399 Horizontal LinearLayout......Page 1402 Vertical LinearLayout......Page 1403 TableLayout......Page 1405 Implicit Rows and Columns......Page 1408 Row and Column Spans......Page 1409 DatePickerDialog and TimePickerDialog......Page 1416 Changes and Bugs......Page 1421 AlertDialog......Page 1422 DialogFragments......Page 1423 Dialogs: Modal, Not Blocking......Page 1428 Multiple Row Types, and Self Inflation......Page 1430 Our Data Model and Planned UI......Page 1431 The Basic BaseAdapter......Page 1432 Requesting Multiple Row Types......Page 1434 Creating and Recycling the Rows......Page 1435 Choice Modes and the Activated Style......Page 1437 Custom Mutable Row Contents......Page 1438 From Head To Toe......Page 1444 Enter RecyclerView......Page 1447 Action Modes......Page 1448 A Matter of Context......Page 1449 Choosing Your Trigger......Page 1450 Starting the Action Mode......Page 1451 onCreateActionMode()......Page 1452 onActionItemClicked()......Page 1453 Multiple-Choice-Modal Action Modes......Page 1455 Long-Click To Initiate an Action Mode......Page 1459 Addressing Configuration Changes......Page 1460 Resetting the Choice Mode......Page 1462 The Results......Page 1463 Action Layouts......Page 1466 Action Views and Action Providers......Page 1467 SearchView… in the Menu Resource......Page 1468 SearchView… in the Action Bar Configuration......Page 1469 onQueryTextChange()......Page 1471 onClose()......Page 1472 SearchView… From the User’s Perspective......Page 1473 Floating Action Bars......Page 1474 Basic Toolbar Mechanics......Page 1478 Use Case: Split Action Bar......Page 1479 Enabling Stock Android 4.x Behavior......Page 1480 Adding the Toolbar......Page 1481 Using the Layout......Page 1482 Populating and Using the Toolbar......Page 1483 Results and Changes......Page 1484 Use Case #2: Replacement Action Bar......Page 1485 Ummmm… Why?......Page 1488 Materialistic......Page 1489 Forced......Page 1490 Your Build Settings......Page 1491 Your Menu Resources......Page 1492 Your Activity and Fragments......Page 1493 Your Results......Page 1496 Tinting......Page 1498 Switch Backport......Page 1499 Overlay......Page 1500 SearchView......Page 1502 Toolbar and AppCompat......Page 1504 To Material, or Not to Material......Page 1508 The Android Design Support Library......Page 1510 GUIs and the Support Package......Page 1511 Introducing CWAC-CrossPort......Page 1512 Alerts......Page 1513 Action Bars. No, Not Those Action Bars.......Page 1515 CWAC-CrossPort......Page 1517 Absolutely FABulous......Page 1519 FAB Mechanics......Page 1521 Coordinating with Snackbars......Page 1524 CWAC-CrossPort......Page 1526 Third-Party FABs… and FAMs......Page 1527 Material Tabs with TabLayout......Page 1528 CWAC-CrossPort......Page 1534 Floating Labels......Page 1535 Using TextInputLayout......Page 1536 CWAC-CrossPort......Page 1542 Third-Party Floating Labels......Page 1543 What About Cursors?......Page 1546 A Simple Grid......Page 1554 Choosing the Number of Columns......Page 1555 A List with Headers......Page 1557 A Grid-Style Table......Page 1561 Mutable Row Contents......Page 1570 Switching to the Activated Style......Page 1578 But, What About Single-Choice?......Page 1582 Keyboard Navigation......Page 1587 Action Modes......Page 1592 Updating Existing Contents......Page 1598 Adding and Removing Items......Page 1603 The Gradle Change......Page 1604 The RecyclerViewFragment......Page 1605 The SortedList......Page 1606 The IconicAdapter......Page 1607 The SortedList.Callback......Page 1608 The AsyncTask......Page 1610 The Results......Page 1611 Other Bits of Goodness......Page 1612 Model......Page 1613 The Menu......Page 1615 The Diff-ing......Page 1617 The SimpleCallback......Page 1619 Expandable Rows......Page 1620 RecyclerView as Pager......Page 1626 Adding the Dependency......Page 1627 Populating the Pages......Page 1628 Dealing with Recycling......Page 1631 Dealing with Configuration Changes......Page 1632 Using SnapHelper......Page 1634 Adding Tabs......Page 1636 Transcript Mode......Page 1640 Friends with Benefits......Page 1644 JavaScript Calling Java: addJavascriptInterface()......Page 1645 Java Calling JavaScript: loadUrl() and evaluateJavascript()......Page 1651 Java Calling JavaScript: WebMessage......Page 1653 JavaScript Calling Java: WebMessagePort......Page 1655 Settings, Preferences, and Options (Oh, My!)......Page 1659 Rogue JavaScript Risks......Page 1660 The Same-Origin Policy Bug......Page 1661 Multi-Process Mode......Page 1663 Honors Cleartext Traffic Setting......Page 1664 Chrome Custom Tabs......Page 1666 Keyboards, Hard and Soft......Page 1668 Tailored To Your Needs......Page 1669 Tell Android Where It Can Go......Page 1674 Fitting In......Page 1676 Jane, Stop This Crazy Thing!......Page 1679 Love The One You’re With......Page 1680 Yeah, But Do We Really Have To Do This in Java?......Page 1684 Here a Glyph, There a Glyph......Page 1685 Auto-Sizing TextView......Page 1686 Justified Text......Page 1691 The Span Concept......Page 1692 TextView and Spanned......Page 1693 String Resource......Page 1694 HTML......Page 1695 Manually......Page 1696 Editing Rich Text......Page 1697 Manipulating Rich Text......Page 1701 ViewPropertyAnimator......Page 1704 Native Implementation......Page 1705 Backport Via NineOldAndroids......Page 1708 The Foundation: Value and Object Animators......Page 1709 Animating Custom Types......Page 1712 Hardware Acceleration......Page 1713 The Three-Fragment Problem......Page 1714 The ThreePaneLayout......Page 1715 Using the ThreePaneLayout......Page 1718 The Results......Page 1722 The Backport......Page 1724 The Problems......Page 1725 It’s Not Just For Toons Anymore......Page 1726 Mechanics of Translation......Page 1727 Introducing SlidingPanel......Page 1728 Fading To Black. Or Some Other Color.......Page 1731 Animations in XML......Page 1732 When It’s All Said And Done......Page 1733 Loose Fill......Page 1734 Animate. Set. Match.......Page 1735 Active Animations......Page 1737 Prerequisites......Page 1738 No Qualifier: Just Say “WTF?”......Page 1739 AnimationDrawable......Page 1740 Animated GIF Conversion......Page 1743 StateListDrawable......Page 1744 ColorStateList......Page 1745 LayerDrawable......Page 1747 TransitionDrawable......Page 1748 LevelListDrawable......Page 1749 Scaling......Page 1751 Seeing It In Action......Page 1752 InsetDrawable......Page 1760 ShapeDrawable......Page 1761 ......Page 1763 ......Page 1764 ......Page 1766 ......Page 1768 Put a Ring On It......Page 1769 BitmapDrawable......Page 1772 Composite Drawables......Page 1779 The Name and the Border......Page 1783 Padding and the Box......Page 1784 Stretch Zones......Page 1785 Tooling......Page 1786 Using Nine-Patch Images......Page 1787 Prerequisites......Page 1794 Where You Can Use Maps V2......Page 1795 Your Signing Key Fingerprint(s)......Page 1796 Your API Key......Page 1798 The Dependency......Page 1799 The Project Setup and the Manifest......Page 1800 The Fragment and Activity......Page 1802 The Result......Page 1803 Playing with the Map......Page 1804 Placing Simple Markers......Page 1807 Seeing All the Markers......Page 1810 Flattening and Rotating Markers......Page 1812 Sprucing Up Your “Info Windows”......Page 1816 Images and Your Info Window......Page 1821 Setting the Marker Icon......Page 1828 Responding to Taps......Page 1830 Dragging Markers......Page 1831 The “Final” Limitations......Page 1834 Finding the User......Page 1837 Dealing with the Runtime Permission......Page 1838 Tracking If We Should Follow the User......Page 1840 Showing the My-Location Layer......Page 1841 Supplying Location Data......Page 1842 Drawing Lines and Areas......Page 1843 Gestures and Controls......Page 1846 Tracking Camera Changes......Page 1847 Maps in Fragments and Pagers......Page 1850 Animating Marker Movement......Page 1855 Problem #2: The Earth Is Not Flat (Really!)......Page 1856 Seeing This in Action......Page 1857 Honoring Traffic Rules, Like “Drive Only On Streets”......Page 1861 Taking a Snapshot of a Map......Page 1862 SupportMapFragment vs. MapView......Page 1863 About That AbstractMapActivity Class…......Page 1864 Helper Libraries for Maps V2......Page 1868 What Non-Compliant Devices Show......Page 1872 Mapping Alternatives......Page 1873 Pick Your Poison......Page 1874 Colors, Mixed How You Like Them......Page 1875 The Layout......Page 1877 The Attributes......Page 1879 Constructor Flavors......Page 1880 Using the Attributes......Page 1881 The Rest of the Functionality......Page 1883 Seeing It In Use......Page 1884 ReverseChronometer: Simply a Custom Subclass......Page 1886 AspectLockedFrameLayout: A Custom Container......Page 1892 Mirror and MirroringFrameLayout: Draw It Yourself......Page 1895 MirroringFrameLayout......Page 1897 Mirror......Page 1901 Usage and Results......Page 1904 Limitations......Page 1907 Introducing PreferenceActivity......Page 1908 Defining Your Preference Headers......Page 1909 Creating Your PreferenceActivity......Page 1910 The Results......Page 1911 Intents for Headers or Preferences......Page 1913 Option #1: Do Not Define the Headers......Page 1914 Option #2: Go Directly to the Fragment......Page 1918 Dependent Preferences......Page 1919 Nested Screens......Page 1922 Listening to Preference Changes......Page 1925 Defaults, and Defaults......Page 1928 Dynamic ListPreference Contents......Page 1929 Dealing with External Changes to Preferences......Page 1934 Preferences in Device Settings App......Page 1935 Custom Preference Storage......Page 1938 Your Dialog, Chocolate-Covered......Page 1944 Basic AlertDialog Setup......Page 1946 Handling Color Changes......Page 1947 Preferring Your Own Preferences, Preferably......Page 1948 Creating the View......Page 1949 Getting the Default Value......Page 1950 Closing the Dialog......Page 1951 Using the Preference......Page 1952 Progress Bars......Page 1956 Circular vs. Horizontal......Page 1957 Specific vs. Indeterminate......Page 1959 ProgressBar and Threads......Page 1960 Changing the Progress Colors......Page 1963 Changing the Indeterminate Animation......Page 1970 Progress Dialogs......Page 1973 Title Bar and Action Bar Progress Indicators......Page 1975 Direct Progress Indication......Page 1977 Hosting ViewPager in a Fragment......Page 1980 Pages and the Action Bar......Page 1982 ViewPagers and Scrollable Contents......Page 1984 Showing More Pages......Page 1985 The Grid Pattern......Page 1989 Columns for Large, Pages for Small......Page 1990 The Layouts......Page 1991 The Activity......Page 1992 The Results......Page 1994 The Limitations......Page 1995 Prerequisites......Page 1996 Controlling the Focus......Page 1997 Requesting (or Abandoning) Focus......Page 1998 Focus Ordering......Page 2004 Scrolling and Focusing Do Not Mix......Page 2006 Accessibility and Focus......Page 2007 Content Descriptions......Page 2008 Announcing Events......Page 2009 Font Selection and Size......Page 2010 Widget Size......Page 2015 Enhanced Keyboard Support......Page 2016 Audio and Haptics......Page 2017 Accessibility Beyond Impairment......Page 2018 Android 1.x/2.x......Page 2020 Android 4.0+......Page 2021 Offering a Delayed Timeout......Page 2031 Standard Intents as Event Bus......Page 2036 LocalBroadcastManager as Event Bus......Page 2037 A Simple LocalBroadcastManager Sample......Page 2038 The Activity......Page 2040 The PollReceiver......Page 2041 ScheduledService and Sending Events......Page 2042 EventLogFragment and Receiving Events......Page 2043 Reference, Not Value......Page 2047 greenrobot’s EventBus 3.x......Page 2048 Basic Usage and Sample App......Page 2049 ScheduledService and Sending Events......Page 2050 EventLogFragment and Receiving Events......Page 2051 Handling the “Nobody’s Home” Scenario......Page 2052 Hey, What About Otto?......Page 2053 First, Some Terminology......Page 2056 Recent Tasks......Page 2057 Overview Screen......Page 2058 Android 3.x/4.x......Page 2059 Android 5.x......Page 2060 What Do Task Killers Do?......Page 2062 Why Use One?......Page 2063 Finding Killable Apps......Page 2064 Displaying Killable Apps......Page 2066 That App Needed Killin’......Page 2068 A Canary for the Task’s Coal Mine......Page 2069 Resuming from the Overview Screen......Page 2072 Starting Another App......Page 2074 Task-Management Intent Flags......Page 2076 When Tasks are Removed......Page 2077 What Happens to Services......Page 2078 Reusing an Activity......Page 2079 Starting a Cleared Task Yourself......Page 2082 Launching an App Into a New Task......Page 2084 The Invisible Activity......Page 2086 Reparenting Tasks......Page 2087 The Self-Destructing Activity......Page 2091 The Hidden Task......Page 2093 The State of Your State......Page 2094 Where You Return To......Page 2095 When You Should Do This......Page 2096 android:documentLaunchMode......Page 2097 Capping the Number of Documents......Page 2098 Other Task-Related Activity Properties......Page 2099 launchMode......Page 2100 singleTop......Page 2101 singleTask......Page 2103 singleInstance......Page 2106 finishAndRemoveTask()......Page 2108 setTaskDescription()......Page 2109 The Assist API (“Now On Tap”)......Page 2110 What Data Gets Disclosed......Page 2111 Other Data......Page 2112 Accessibility......Page 2113 Per-Activity......Page 2114 FLAG_SECURE......Page 2116 NoAssistFrameLayout......Page 2117 Blocking Assist as a User......Page 2119 A Stub VoiceInteractionService......Page 2122 The VoiceInteractionSession......Page 2124 onHandleScreenshot()......Page 2125 onHandleAssist()......Page 2127 Determining the Active Assistant......Page 2133 Leading the User to Make an Assistant Change......Page 2134 The Autofill API......Page 2136 The Pieces of the Puzzle......Page 2137 While Completing a Form......Page 2138 After Completing a Form......Page 2139 What Data Gets Disclosed......Page 2140 Blocking Autofill as a User......Page 2154 Supporting Autofill with Standard Widgets......Page 2156 Identifying Roles via Hints......Page 2157 Indicating Importance......Page 2158 Dealing with Dynamic Changes......Page 2159 Security Requirements of Autofill Services......Page 2160 Google’s Response......Page 2161 Partition the Dataset......Page 2162 Only Give Data Back to the App That Supplied It......Page 2163 What Google’s Advice Does Not Solve......Page 2164 Prerequisites......Page 2166 The What, Now?......Page 2167 Setting Up the Toolchain......Page 2168 Augmenting the Layout… and the Model......Page 2169 Creating the Binding......Page 2172 Pouring the Model into the Binding......Page 2173 The Extended Layout Resource......Page 2174 Imports and Statics......Page 2175 Variables......Page 2177 Stuff You Won’t Find in Java......Page 2178 Watch Out For Mis-Interpreted Integers......Page 2180 Observables and Updating the Binding......Page 2181 ObservableField......Page 2182 Custom Observables......Page 2183 An Observable Example......Page 2185 Questions vs. Items......Page 2186 Keeping Score (and the ID)......Page 2187 Refreshing the Data......Page 2191 Two-Way Binding......Page 2194 Obtaining Views via the Binding Class......Page 2197 Synthetic Properties......Page 2198 Using Different Methods......Page 2200 BindingAdapters, and the Picasso Scenario......Page 2201 Two-Way Binding and InverseBindingAdapter......Page 2205 Thinking Back to android:onClick......Page 2206 Tying Events to Methods Directly......Page 2207 Tying Events to Methods via Lambda Expressions......Page 2208 Converting to a RecyclerView/CardView UI......Page 2209 What About the Event Listeners?......Page 2213 Type Converters......Page 2214 Chained Expressions......Page 2216 Custom Binding Class Names......Page 2217 Extended Include Syntax......Page 2218 Custom Observables......Page 2219 Bindable Properties......Page 2220 Notifying About Intrinsic Changes......Page 2222 Thinking Outside the Box......Page 2223 The Scope of Drag and Drop......Page 2226 Where Are We Dropping To?......Page 2227 …From a View......Page 2228 The Drag Event Listener......Page 2229 ACTION_DRAG_STARTED......Page 2230 ACTION_DROP......Page 2231 The Landscape Layout......Page 2232 Registering as Drop Targets......Page 2234 Starting to Drag......Page 2235 Reacting to Drag Events......Page 2236 The Result......Page 2238 Drag-and-Drop, Between Apps......Page 2241 The Custom Shadow......Page 2242 The StreamProvider......Page 2243 The Drag Request......Page 2245 The Layout......Page 2247 The Drag Event......Page 2249 The Results......Page 2251 Intra-App Cross-Window Drag-and-Drop......Page 2253 Dragging and Dropping Simple Stuff......Page 2256 The Layout......Page 2257 Showing and Hiding the Action......Page 2259 Handling Drag Events......Page 2262 Nested Drop Targets......Page 2263 The Behavior Prior to Android 7.0......Page 2265 Android 7.0 Behavior......Page 2267 Getting Inclusive on Android 7.0......Page 2269 The State of the Bugs......Page 2271 Pondering Accessibility......Page 2272 Offering Keyboard Shortcuts......Page 2274 Action Bar Item Shortcuts......Page 2275 Arbitrary Hotkeys......Page 2276 Android 7.0 Keyboard Shortcuts Helper......Page 2278 Custom Copy-and-Paste......Page 2284 The Problem......Page 2288 A requestFocus BindingAdapter......Page 2289 Using the BindingAdapter......Page 2291 Offering Mouse Context Menus......Page 2292 Hover Events......Page 2298 Detecting a Long-Enough Hover......Page 2301 Android 8.0+......Page 2304 Pointer Capture......Page 2306 Prerequisites......Page 2308 How Complex is the PDF?......Page 2309 How Private is the PDF?......Page 2310 The Really Bad Idea: Google Docs......Page 2311 The Built-In Option: PdfRenderer......Page 2312 The RecyclerView......Page 2313 Getting the PDF......Page 2314 Adding the PdfRenderer......Page 2316 Showing the Pages......Page 2318 The Thunder Lizard Choice: PDF.js......Page 2321 The Native Approach: Pdfium......Page 2325 What To Choose?......Page 2329 App Widgets and Security......Page 2332 The Big Picture for a Small App Widget......Page 2333 The Manifest......Page 2334 The Metadata......Page 2336 The Layout......Page 2337 The BroadcastReceiver......Page 2338 The Result......Page 2340 Another and Another......Page 2341 Controlling Your (App Widget’s) Destiny......Page 2342 Android 3.0+......Page 2343 Lockscreen Widgets......Page 2349 Preview Images......Page 2355 Being a Good Host......Page 2357 AdapterViews for App Widgets......Page 2358 Building Adapter-Based App Widgets......Page 2359 The AppWidgetProvider......Page 2360 The RemoteViewsService......Page 2362 The RemoteViewsFactory......Page 2364 The Rest of the Story......Page 2367 The Results......Page 2369 What Slices Contain......Page 2374 Slice Sizes......Page 2375 Setting Up a Slice......Page 2377 The Gradle Settings......Page 2378 The SliceProvider......Page 2379 The Activity That You Didn’t Write......Page 2380 Binding a Slice......Page 2381 Trying a Slice......Page 2384 Running Your Slice in the Viewer......Page 2385 The User Flow......Page 2387 The SliceAction......Page 2388 Simple Rows......Page 2389 Headers......Page 2390 Range Rows and Input Range Rows......Page 2391 Hey, What About…?......Page 2392 Small and Large Modes......Page 2393 Dealing with No Data......Page 2394 Loading the Data......Page 2397 Using the Data......Page 2400 Warning: Make No Rendering Assumptions......Page 2401 Other Slice Viewer Features......Page 2402 Securing Yourself......Page 2404 Enforcing Permissions via the Manifest......Page 2405 Requiring Standard System Permissions......Page 2406 Firmware-Only Permissions......Page 2407 Your Own Signature Permissions......Page 2408 Scenarios......Page 2409 The Application SDK Case (A, Then C)......Page 2410 The Peer Apps Case, Part One (A, Then B)......Page 2411 The Peer Apps Case, Part Two (B, Then A)......Page 2412 The Peer Apps Case With a Side Order of C......Page 2413 Risk Assessment......Page 2414 Android 5.0’s “Fix”......Page 2415 Custom Dangerous Permissions, and Android 6.0......Page 2416 Finding the Available Permissions......Page 2420 PackageManager and Permission Groups......Page 2421 The Activity and ViewPager......Page 2425 The Tab Content......Page 2427 A Bit More Rx......Page 2428 The Results......Page 2429 Android Tablets and Multiple User Accounts......Page 2432 Primary User......Page 2433 Secondary User......Page 2434 Restricted Profile......Page 2435 Determining What the User Can Do......Page 2438 Enabling Custom Restrictions......Page 2441 Option #1: RestrictionEntry List......Page 2442 What the Primary User Sees......Page 2446 Finding Out the Current Restrictions......Page 2450 Implicit Intents May Go “Boom”......Page 2452 Is the Device Secure?......Page 2454 The KeyguardManager Approach......Page 2455 Reconfirming the User......Page 2459 Via KeyguardManager......Page 2461 Using RxFingerprint......Page 2462 Directly......Page 2468 RxFingerprint......Page 2469 OK, So What Was That All About?......Page 2474 Limitations of Fingerprint-Based Encryption......Page 2475 Prerequisites......Page 2476 KeyStore......Page 2477 Creating a Key......Page 2478 Tying the Key to Device Authentication......Page 2479 Learning More About Your Key......Page 2480 Introducing RxKeyBodega......Page 2481 RxKeyBodega Client......Page 2482 RxKeyBodega Implementation......Page 2484 Some Quick Initialization Vector Notes......Page 2487 Starting Decryption in onCreate()......Page 2488 RxKeyBodega Client......Page 2489 RxKeyBodega Implementation......Page 2490 Time-Limited Device Authentication......Page 2492 Encrypting Passphrases......Page 2495 A NoteRepository......Page 2496 RxPassphrase......Page 2500 Using the NoteRepository and RxPassphrase......Page 2502 A Key(Store) Limitation......Page 2504 Public Key Validation......Page 2506 Checking Yourself......Page 2507 Checking Arbitrary Other Apps......Page 2508 The Easy Solution: SignatureUtils......Page 2509 The UI Structure......Page 2510 Listing the Packages......Page 2511 Dumping the Key......Page 2514 Decoding the Key......Page 2515 Choosing Your Signing Keysize......Page 2518 Avoiding Accidental APIs......Page 2519 The Chooser Bug......Page 2520 The ContentProvider Behavior Change......Page 2522 Secure Your Output Extras......Page 2523 Notifications......Page 2524 Jacking Attacks......Page 2525 The Problem......Page 2526 Activity Jacking......Page 2527 The Problem......Page 2528 How to Address This......Page 2529 The Problem......Page 2530 How to Address This......Page 2531 Using FLAG_SECURE......Page 2533 Using a Content Provider......Page 2538 Getting a Handle......Page 2539 Makin’ Queries......Page 2540 Adapting to the Circumstances......Page 2542 Give and Take......Page 2543 Retrieving Metadata......Page 2545 Building Content Providers......Page 2546 First, Some Dissection......Page 2547 Implementing the Database-Style API......Page 2548 Implement query()......Page 2549 Implement getType()......Page 2550 Update the Manifest......Page 2551 Add Notify-On-Change Support......Page 2552 Serving the Stream......Page 2553 Issues with Content Providers......Page 2554 Step #1: Create a Provider Class......Page 2556 onCreate()......Page 2557 query()......Page 2559 update()......Page 2560 getType()......Page 2561 Step #3: Declare the “Columns”......Page 2562 Step #4: Update the Manifest......Page 2563 onCreate()......Page 2564 openFile()......Page 2565 getType()......Page 2567 insert(), update(), and delete()......Page 2568 query() and getFileName()......Page 2569 The Manifest......Page 2571 Using this Provider......Page 2572 Step #1: Mark the Provider as Not Exported......Page 2573 Step #2: Grant Access to the Uri......Page 2574 The Stream Provider......Page 2575 The Revised openFile()......Page 2576 The Transfer......Page 2577 The Results......Page 2578 The Sources of Files......Page 2579 The Manifest Entry......Page 2580 The Legacy Compatibility......Page 2581 The Usage......Page 2582 StreamProvider......Page 2584 Exporting and Usage Patterns......Page 2585 Metadata Elements......Page 2586 Assets and Gradle......Page 2587 Uri Prefixes......Page 2588 Customizing the Uri Prefix......Page 2589 Supporting Other Stream Locations......Page 2590 Totally Overhauling Uri Handling......Page 2591 Adding Support for insert() and update()......Page 2592 Prerequisites......Page 2594 LoaderCallbacks......Page 2595 Using CursorLoader......Page 2596 … the Data Behind the Loader Changes?......Page 2598 Writing a Custom Loader......Page 2599 Implementing QuestionsLoader......Page 2600 Loading the Questions......Page 2601 Delivering Results......Page 2602 Starting, Stopping, and Resetting......Page 2603 Using QuestionsLoader......Page 2604 Considering the Loader Contract......Page 2605 Prerequisites......Page 2606 A Look Back at Android 1.6......Page 2607 Picking a Contact......Page 2608 Viewing a Contact......Page 2609 Contact Permissions......Page 2610 The UI......Page 2611 Loading the Data......Page 2613 Showing the Results......Page 2615 Makin’ Contacts......Page 2618 Pondering Permissions......Page 2622 Contents of CallLog.Calls......Page 2623 Showing the CallLog......Page 2624 The CalendarContract Provider......Page 2628 Do You Have Room on Your Calendar?......Page 2629 The Permission......Page 2630 The CursorLoader......Page 2631 The RecyclerView......Page 2632 The Results......Page 2635 Penciling In an Event......Page 2636 Prerequisites......Page 2638 Indexed Media......Page 2639 MediaStore and “Other” External Storage......Page 2640 How Do I Retrieve Video from the MediaStore?......Page 2641 Requesting Permission......Page 2642 Querying for Video......Page 2643 Showing the Thumbnails......Page 2645 The Results......Page 2646 The Storage Access… What?......Page 2648 Picking How to Pick (a Peck of Pickled Pepper Photos)......Page 2650 Opening a Document......Page 2651 Why We Want Things To Be Openable......Page 2655 Update......Page 2656 CWAC-Document and DocumentFileCompat......Page 2657 Getting Durable Access......Page 2658 Another Durable Example: Diceware......Page 2667 We Want Words!......Page 2668 The Results......Page 2669 Loading Our Words......Page 2670 Getting More Words......Page 2674 Other Fiddly Bits......Page 2678 Getting a Tree......Page 2681 The Objective: a Preference for Storage......Page 2682 What the User Sees......Page 2683 The Preference XML......Page 2689 Populating the Preference......Page 2690 Choosing a Tree......Page 2691 The Preference XML......Page 2694 Populating the Preference......Page 2695 Choosing a Volume......Page 2697 Scoped Directory Access Bug......Page 2699 Web Links for Documents......Page 2700 Document Settings Activity......Page 2701 Have Your Content, and Provide it Too......Page 2702 Root and Document IDs......Page 2704 The Activity......Page 2705 The Manifest......Page 2706 onCreate()......Page 2707 queryRoots()......Page 2708 queryChildDocuments()......Page 2711 queryDocument()......Page 2713 openDocument()......Page 2714 The Results......Page 2716 Create......Page 2720 Update......Page 2721 Change Notification......Page 2722 Recent Documents......Page 2723 Other Flags......Page 2724 Encrypted Storage......Page 2726 Obtaining SQLCipher......Page 2727 Using SQLCipher......Page 2728 SQLCipher Limitations......Page 2729 Passwords and Sessions......Page 2730 Upgrading to Encryption......Page 2731 Dealing with the Version 3.0.x Upgrade......Page 2734 Multi-Factor Authentication......Page 2736 SQLCipher for Android and Performance......Page 2737 Encryption via Custom SharedPreferences......Page 2738 Encryption via Custom Preference UI and Accessors......Page 2739 IOCipher......Page 2740 Packing a Database To Go......Page 2742 Create and Pack the Database......Page 2743 Unpack the Database, With a Little Help(er)......Page 2744 Limitations......Page 2745 Full-Text Indexing......Page 2746 First, a Word About SQLite Versions......Page 2747 Creating a Full-Text Indexed Table......Page 2748 Populating a Full-Text Indexed Table......Page 2749 Querying a Full-Text Indexed Table......Page 2750 Adding a ModelFragment......Page 2751 Adding a SearchView......Page 2755 The Results......Page 2757 Getting Snippets......Page 2761 Prerequisites......Page 2764 What Google Thinks “Backup” Means......Page 2765 What IT Thinks “Backup” Means......Page 2766 Implementing IT-Style Backup......Page 2767 Choosing the Backup Scope......Page 2769 Choosing a Backup Trigger......Page 2770 Generating the Dataset......Page 2771 Transmitting the Dataset......Page 2776 Initiating a Restore......Page 2779 Starting the Restore Activity......Page 2784 Downloading and Restoring the Dataset......Page 2786 Trying This Yourself… With a Little Help from Ol’ Blue Eyes......Page 2790 What to Bootstrap?......Page 2792 Configuring the Backup......Page 2793 Testing the Backup and Restore Steps......Page 2796 Bootstrap Backup on Android 2.2-5.1......Page 2799 Securing Transmission of the Dataset......Page 2801 Alternative Approaches......Page 2802 Import and Export......Page 2803 Data Synchronization......Page 2804 Basic SSL Operation......Page 2808 Self-Signed Certificate......Page 2809 Custom Certificate Authority......Page 2810 Ignoring Domain Names......Page 2811 Introducing Network Security Configuration......Page 2812 The CWAC-NetSecurity Backport......Page 2813 SSL Problems and Network Security Configuration......Page 2815 Pinning the Certificate Authority......Page 2816 Unusual Certificate Authorities......Page 2820 Pinning the Certificate......Page 2821 Self-Signed Certificates......Page 2823 Blocking Cleartext Traffic......Page 2824 Supporting User-Added Certificates......Page 2825 Certificate Memorizing......Page 2826 Requiring Encryption, Android 6.0 Style......Page 2827 Using Alternative Network Security Configuration XML......Page 2828 Adding the TrustManager......Page 2829 Debugging Certificate Chains......Page 2830 NetCipher......Page 2831 A Quick Primer on Tor......Page 2832 What NetCipher Provides......Page 2833 Choose an HTTP Stack......Page 2834 Set up OrbotHelper......Page 2835 Choose and Create a Builder......Page 2836 Seeing the Builder in Action......Page 2837 Common Configuration Methods......Page 2841 Differences Between the Stacks......Page 2845 StrongConnectionBuilder......Page 2846 StrongHttpClientBuilder......Page 2847 StrongVolleyQueueBuilder......Page 2849 StrongOkHttpClientBuilder......Page 2850 Why a Web Server?......Page 2854 Production Uses......Page 2855 Embedding a Simple Server......Page 2856 The Dependencies......Page 2857 Setting Up the AsyncHttpServer......Page 2858 Serving Pages from Assets......Page 2859 Making a Foreground Service......Page 2862 Raising Status Events......Page 2863 The Rest of the Lifecycle......Page 2865 The Activity......Page 2866 The Results......Page 2870 Template-Driven Responses, with Handlebars......Page 2873 Loading Handlebars Templates......Page 2874 Handlebars’ Context (No, Not That Context)......Page 2876 Supporting WebSockets......Page 2878 Registering the WebSocket Listener......Page 2879 Receiving Messages on the Client......Page 2881 Reversing the Communications Flow......Page 2883 Disabling on Mobile Data Connections......Page 2884 Implementing an Inactivity Timeout......Page 2885 Supporting Random URLs......Page 2887 Detecting Attacks......Page 2889 What About SSL?......Page 2890 Gradle Changes......Page 2891 buildForegroundNotification()......Page 2892 configureRoutes()......Page 2893 getMaxSequentialInvalidRequests()......Page 2894 Integrating WebSocket and Handlebars......Page 2895 Stopping the Service......Page 2897 Trimming Back the Project......Page 2899 Reusing the Module via Relative Paths......Page 2900 Downloading Files......Page 2902 The Permissions......Page 2903 Requesting the Download......Page 2905 Keeping Track of Download Status......Page 2908 Download Broadcasts......Page 2909 What the User Sees......Page 2910 Limitations......Page 2915 Data Saver......Page 2916 Get Your Media On......Page 2920 MediaPlayer for Audio......Page 2921 SoundPool......Page 2926 ToneGenerator......Page 2927 Recording by Intent......Page 2930 Recording to Files......Page 2933 Setting Up the Stream......Page 2938 Changes in Recording Configuration......Page 2940 Requesting the Microphone......Page 2941 Moving Pictures......Page 2942 Being Specific About Features......Page 2948 Setting the Theme......Page 2949 Adding the FileProvider......Page 2950 Taking a Picture......Page 2952 Viewing the Photo......Page 2954 The Caveats......Page 2955 Permissions and Third-Party Camera Apps......Page 2956 EXIF Tags and Camera Images......Page 2957 EXIF Tags and Android......Page 2958 You Spin (Photos) Right Round......Page 2959 And Then, There Are the Bugs......Page 2963 Scanning with ZXing......Page 2964 Videos: Letting the Camera App Do It......Page 2965 Using a Camera Library......Page 2968 CameraKit-Android......Page 2969 Adding the Preview Display......Page 2970 Integrating with the Lifecycle......Page 2972 Recording a Video......Page 2974 Adding the Dependency......Page 2975 Adding the Preview Display......Page 2976 Configuring the Fotoapparat......Page 2977 Taking a Picture......Page 2979 Directly Working with the Camera......Page 2980 Notes About the Code Snippets......Page 2982 android.hardware.camera2......Page 2983 Performing Basic Camera Operations......Page 2984 Features......Page 2985 Other Camera Features......Page 2986 android.hardware.Camera......Page 2987 android.hardware.camera2......Page 2988 android.hardware.Camera......Page 2989 android.hardware.camera2......Page 2990 Setting Up a Preview Surface......Page 2992 TextureView for the Camera......Page 2993 android.hardware.Camera......Page 2994 android.hardware.camera2......Page 2996 android.hardware.Camera......Page 2999 android.hardware.camera2......Page 3001 android.hardware.camera2......Page 3005 Using MediaRecorder......Page 3006 Configuring the Still Camera......Page 3007 android.hardware.Camera......Page 3008 Flash Mode......Page 3009 android.hardware.camera2......Page 3010 Zoom......Page 3011 android.hardware.Camera......Page 3012 android.hardware.camera2......Page 3013 Previews and Aspect Ratios......Page 3016 Picture Orientation......Page 3017 Storage Considerations......Page 3018 Camera Peeking Attacks......Page 3019 Media......Page 3022 android.support.v7.media......Page 3023 Getting a MediaRouter Instance......Page 3024 Registering a Callback......Page 3025 The Basic Project and Dependencies......Page 3026 Initializing the MediaRouter and Selector......Page 3028 Registering for Route Changes......Page 3030 The Results......Page 3031 Live Audio Routes......Page 3032 Live Video Routes......Page 3035 Remote Playback Routes......Page 3036 Using Remote Playback Routes......Page 3041 Setting Up MediaRouteActionProvider......Page 3042 The Rest of the User Interface......Page 3044 Connecting and Session Management......Page 3046 What’s a Session?......Page 3047 Starting a Session......Page 3048 About the Action Bar......Page 3049 Session IDs......Page 3050 Playing......Page 3051 The Workaround: RunnableSessionActionCallback......Page 3054 Pausing and Resuming......Page 3056 Disconnecting......Page 3058 Other Remote Playback Features......Page 3059 A History of External Displays......Page 3060 What is a Presentation?......Page 3061 Emulated......Page 3062 Miracast......Page 3066 Detecting Displays......Page 3068 The Presentation Itself......Page 3069 Detecting the Displays......Page 3070 Showing and Hiding the Presentation......Page 3071 The Results......Page 3074 Getting a Little Help......Page 3075 Help When You Need It......Page 3078 Presentations and Configuration Changes......Page 3081 The Reuse Reality......Page 3082 The Context Conundrum......Page 3083 A PresentationFragment (and Subclasses)......Page 3084 Using PresentationFragment......Page 3089 Another Sample Project: Slides......Page 3093 The PagerAdapter......Page 3094 The PresentationFragment......Page 3096 Setting Up the Pager......Page 3097 Setting Up the Presentation......Page 3098 Controlling the Presentation......Page 3099 Offering an Action Bar......Page 3100 Device Support for Presentation......Page 3101 Presentations from a Service......Page 3102 Step #4: Build the View......Page 3103 Hey, What About Chromecast?......Page 3105 What is Chromecast?......Page 3108 What is Google Cast?......Page 3109 Your API Choices......Page 3110 The Receiver......Page 3111 Supported Media Types......Page 3112 The Terms of Service......Page 3113 The Official Libraries......Page 3114 Developing Google Cast Apps......Page 3115 Prerequisites......Page 3116 Overscan......Page 3117 Navigation......Page 3118 Fonts......Page 3119 Colors......Page 3120 Where to Get Leanback......Page 3121 BrowseSupportFragment......Page 3122 Theme and Activity......Page 3123 Loading the Videos......Page 3126 Headers and Contents......Page 3129 Presenting the Presenters......Page 3131 Handling Clicks......Page 3135 The Results......Page 3136 Testing Your Theories......Page 3138 Putting the TVs All Together: Decktastic......Page 3140 Launcher UI......Page 3141 Presentation UI......Page 3143 The Presentation Format......Page 3145 PresoContents......Page 3147 PresoRoster......Page 3148 The Launcher Activity: LeanbackActivity......Page 3150 Manifest Entry......Page 3151 RosterFragment......Page 3152 PresoPresenter......Page 3155 Basic Setup......Page 3159 The ViewPager......Page 3161 Supporting the Direct-to-TV Scenario......Page 3163 Supporting External Displays......Page 3166 Supporting Chromecast and Remote Playback Devices......Page 3170 The Rest of the Story......Page 3175 Terminology......Page 3180 MediaRouteProvider......Page 3181 Player Device… and Maybe a Player App......Page 3182 Defining the Supported Actions......Page 3183 Creating the Descriptors......Page 3185 Receiving the Actions......Page 3187 Handling the Actions......Page 3189 Play......Page 3190 Get Status and Seek......Page 3191 Publishing the Controller......Page 3192 Handling Discovery Requests......Page 3193 Private Provider......Page 3194 Public Provider......Page 3197 Handling Other Actions/Protocols......Page 3198 Custom Actions......Page 3199 Requesting Screenshots......Page 3200 Introducing andprojector......Page 3201 Asking for Permission......Page 3204 Creating the MediaProjection......Page 3206 Processing the Screenshots......Page 3210 The HTML......Page 3213 Dealing with Configuration Changes......Page 3214 Recording the Screen......Page 3215 Requesting Media Projection… Without a GUI......Page 3216 Implementing a Control Channel… Without a GUI......Page 3219 Using the Control Channel… From the Command Line......Page 3225 Starting the Recording......Page 3227 Deciding How Big Our Recording Is......Page 3228 Actually Recording Stuff......Page 3232 Stopping the Recording......Page 3234 Usage Notes......Page 3235 The Activity......Page 3236 Setting Up the Notification......Page 3237 Capturing a Screenshot......Page 3239 Scenarios......Page 3244 Wake Up… Or Not?......Page 3245 Inexact… Or Not?......Page 3246 A Simple Example......Page 3247 The Five set…() Varieties......Page 3249 When to Schedule Alarms......Page 3251 After a Force-Stop......Page 3252 Back to the Main Application Thread......Page 3253 Return of the JobIntentService......Page 3254 Examining a Sample......Page 3255 How the Magic Works......Page 3258 Debugging Alarms......Page 3259 Android 7.0 and OnAlarmListener......Page 3262 Keeping the Screen On, UI-Style......Page 3266 The Role of the WakeLock......Page 3267 What WakefulIntentService Does......Page 3268 The Limitations of AlarmManager......Page 3270 Employing JobScheduler......Page 3271 Defining and Scheduling the Job......Page 3272 Implementing the Job......Page 3275 Wiring in the Job Service......Page 3278 The Rest of the Sample......Page 3279 Pondering Backoff Criteria......Page 3285 Idle Jobs......Page 3286 Other JobScheduler Features......Page 3287 Periodic Work, Across Device Versions......Page 3288 The Job......Page 3289 The JobCreator......Page 3290 The Application......Page 3291 Scheduling Jobs......Page 3292 Doze Mode......Page 3293 …AndAllowWhileIdle()......Page 3294 The Whitelist......Page 3295 setAlarmClock()......Page 3304 Scheduling Content Monitoring......Page 3305 Enqueuing the Work......Page 3310 Working Off the Queue......Page 3311 Testing the Service......Page 3314 Work Limits......Page 3316 Prerequisites......Page 3320 Finding Yourself......Page 3321 Getting Permission......Page 3323 Modelling the Weather......Page 3324 Requesting Updates......Page 3325 Implementing the Listener......Page 3328 Displaying the Results......Page 3329 Are We There Yet? Are We There Yet? Are We There Yet?......Page 3331 Testing… Testing…......Page 3332 Alternative Flavors of Updates......Page 3333 Locations and Features......Page 3334 Why Use the Fused Location Provider?......Page 3336 Adding Dependencies......Page 3337 Confirm Locations Are Available......Page 3338 Request the Location......Page 3343 Using the Location......Page 3344 Defining a Location Request......Page 3345 Requesting Location Updates......Page 3346 Working with the Clipboard......Page 3350 ClipData and Drag-and-Drop......Page 3355 Monitoring the Clipboard......Page 3356 The Android 4.3 Clipboard Bug......Page 3357 If Your App Pastes to the Clipboard…......Page 3358 Prerequisites......Page 3360 You Make the Call!......Page 3361 No, Really, You Make the Call!......Page 3364 Prerequisites......Page 3366 Sending Via the SMS Client......Page 3367 Inside the Sender Sample......Page 3368 SMS Sending Limitations......Page 3374 The Undocumented, Unsupported, Pre-Android 4.4 Way......Page 3375 The Android 4.4+ Way: Monitoring SMS......Page 3376 Receiving the Broadcasts......Page 3378 Other Expectations......Page 3379 The Undocumented, Unsupported, Pre-Android 4.4 Way......Page 3381 Asking to Change the Default......Page 3382 SMS and the Emulator......Page 3383 SMS Tokens......Page 3384 What Is NFC?......Page 3390 … Compared to QR Codes?......Page 3391 NDEF Modalities......Page 3392 NDEF Structure and Android’s Translation......Page 3393 Some Tags Need to be Formatted......Page 3394 Tag and Device Compatibility......Page 3395 Writing to a Tag......Page 3396 Detecting a Tag......Page 3397 Reacting to a Tag......Page 3399 Getting the Shared URL......Page 3400 Creating the Byte Array......Page 3401 Writing to a Tag......Page 3402 Responding to a Tag......Page 3405 Expected Pattern: Bootstrap......Page 3406 Android Beam......Page 3407 The Fragment......Page 3408 Requesting the Beam......Page 3410 Sending the Beam......Page 3411 Receiving the Beam......Page 3412 The Scenarios......Page 3414 Beaming Files......Page 3415 Another Sample: SecretAgentMan......Page 3416 Configuration and Initialization......Page 3417 Writing to the Tag......Page 3418 Reading from the Tag......Page 3423 Beaming the Text......Page 3424 Beaming the File......Page 3425 Additional Resources......Page 3426 Objectives and Scope......Page 3428 The Metadata......Page 3429 The Manifest......Page 3430 The Receiver......Page 3431 The Demand for Device Domination......Page 3432 Going Into Lockdown......Page 3435 Mandating Quality of Security......Page 3442 Establishing Password Requirements......Page 3443 Password-Related Events......Page 3445 Getting Along with Others......Page 3447 The Sensor Abstraction Model......Page 3448 Considering Rates......Page 3449 Obtaining a SensorManager......Page 3450 Identifying a Sensor of Interest......Page 3451 Getting Sensor Events......Page 3452 Interpreting Sensor Events......Page 3454 Wiring Together the Sample......Page 3456 The Results......Page 3461 Batching Sensor Readings......Page 3462 Printing and Document Generation......Page 3464 The Android Print System......Page 3465 About the Sample App......Page 3466 Printing a Bitmap......Page 3467 Printing and WebView......Page 3469 Printing a URL......Page 3470 Limitations and Concerns......Page 3473 The PrintDocumentAdapter Protocol......Page 3474 Introducing ThreadedPrintDocumentAdapter......Page 3475 A PdfDocumentAdapter......Page 3478 Printing Using a Canvas......Page 3482 Printing, Threads, and Services......Page 3485 HTML Generation......Page 3488 Adding jmustache To Your App......Page 3489 Creating a Report Context......Page 3490 Printing the Report......Page 3491 PDF Generation Options......Page 3492 A Quick Bit of Scope......Page 3494 The User Experience......Page 3495 The Code......Page 3500 Bluetooth and Permissions......Page 3501 The Rx for Your Bluetooth......Page 3502 I Can Haz Bluetooth?......Page 3503 Getting the Paired Devices......Page 3506 Listing the Devices......Page 3508 Enabling Discoverability......Page 3509 Discovering Other Devices......Page 3510 Reacting to Discovery Results......Page 3511 Service Scaffolding......Page 3512 A Quick Word About MutableLiveData......Page 3513 Keeping the UI in the Loop......Page 3514 Services with Services......Page 3516 Reach Out and Touch Someone......Page 3517 Finding Out When We Should Connect......Page 3518 Connecting and Disconnecting......Page 3520 Getting Our Client Streams......Page 3521 Sending the Message......Page 3522 Processing the Request......Page 3523 Receiving the Response......Page 3524 Differences with Android Things......Page 3525 Filtering Out Devices......Page 3528 uses-feature......Page 3529 uses-library......Page 3530 Features......Page 3531 Dealing with Device Bugs......Page 3532 The Role of Parcelable......Page 3536 By Annotations......Page 3537 By Code Generator Sites and Tools......Page 3538 The Parcelable Interface......Page 3539 The CREATOR......Page 3541 By Hand, With a Little Bit of Help......Page 3542 The 1MB Limit......Page 3543 Pass-By-Value......Page 3544 The ClassLoader Conundrum......Page 3545 Beware the PendingIntent......Page 3546 Manifest Modifications......Page 3552 Creating a Custom URL......Page 3554 Reacting to the Link......Page 3555 App Links......Page 3557 Setting Up the IntentFilter......Page 3558 Setting Up the JSON......Page 3559 Results......Page 3561 User Intervention......Page 3562 Testing Your Setup......Page 3565 Prerequisites......Page 3568 Ad-Hoc Requests......Page 3569 Pinning......Page 3570 Offering Manifest App Shortcuts......Page 3571 Identify the Destinations......Page 3572 Add Entry Points for Destination in Manifest......Page 3573 Write the XML......Page 3574 Results......Page 3575 Offering Dynamic App Shortcuts......Page 3577 Ponder the IDs......Page 3580 Craft the Intent......Page 3581 Define the Shortcuts......Page 3583 Remove the Shortcuts......Page 3585 Grok the Other Verbs......Page 3586 Contemplate Update vs. Replace......Page 3587 Deal with Reality......Page 3588 Privacy, Security, and App Shortcuts......Page 3589 Asking Around......Page 3590 Preferred Activities......Page 3594 Finding Applications and Packages......Page 3600 Finding Components......Page 3601 Prerequisites......Page 3604 What the Client Does......Page 3605 A Binding Sample......Page 3606 Write the AIDL......Page 3611 Service From Afar......Page 3613 Service Names......Page 3614 Remote Services and Implicit Intents......Page 3615 The Service......Page 3616 The Client......Page 3617 Tightening Up the Security......Page 3619 Adding the Dependency......Page 3620 Adding the Signature Check: Client......Page 3621 Adding the Signature Check: Service......Page 3622 Servicing the Service......Page 3624 Callbacks via AIDL......Page 3625 Revising the Client......Page 3626 Revising the Service......Page 3627 Thinking About Security......Page 3628 The “Everlasting Service” Anti-Pattern......Page 3629 Just Looking For Some Elbow Room......Page 3632 Configuring Your App to Reside on External Storage......Page 3633 What the User Sees......Page 3635 What Your App Sees… When External Storage is Inaccessible......Page 3636 Choosing Whether to Support External Storage......Page 3639 Android 6.0 and “Adoption” of Removable Storage......Page 3640 Using an Alias......Page 3642 Getting Meta (Data)......Page 3643 Direct Share......Page 3648 The ChooserTargetService......Page 3649 The Manifest Entries......Page 3652 The Results......Page 3653 But… I Got Nothin’!......Page 3656 Take the Shortcut......Page 3657 Implementing a Shortcut Provider......Page 3658 Using the Shortcuts......Page 3660 Integrating with Text Selection......Page 3664 Supporting ACTION_PROCESS_TEXT......Page 3667 The Extras......Page 3668 The Results (If Any)......Page 3670 Security......Page 3671 Blocking ACTION_PROCESS_TEXT......Page 3672 Quick Settings and TileService......Page 3675 The Manifest Entry......Page 3676 And, Of Course, Bugs......Page 3677 The Service......Page 3678 The User Experience......Page 3680 The Other Features and Limitations......Page 3683 Installing Packages......Page 3684 Detecting Changes in Packages......Page 3687 Project Structure......Page 3690 SDK Location......Page 3691 Developer Services......Page 3692 Properties......Page 3693 Signing......Page 3694 Flavors......Page 3695 Build Types......Page 3697 Dependencies......Page 3698 Translations Editor......Page 3701 Hardware Graphics Acceleration......Page 3708 Keyboard Behavior......Page 3709 Startup Settings......Page 3710 Camera Options......Page 3711 Frames and Skins......Page 3712 The Emulator Sidebar......Page 3713 Power and Navigation Controls......Page 3714 Screen Orientation and Zoom......Page 3718 Screenshots......Page 3719 Faking the Real World......Page 3720 Network Status......Page 3721 Battery......Page 3722 Telephony......Page 3723 Emulator Window Operations......Page 3724 Headless Operation......Page 3725 Prerequisites......Page 3726 Android Studio......Page 3727 What to Fix......Page 3728 Android Studio......Page 3729 Command Line......Page 3730 Support Annotations......Page 3733 Methods......Page 3734 ContentProviders......Page 3735 What Permissions Should I Annotate?......Page 3736 Type Roles, and the War on Enums......Page 3737 Resources......Page 3738 Custom Enum Replacement......Page 3739 Flags......Page 3741 Data Validation......Page 3742 Ranges......Page 3743 Thread Validation......Page 3744 Other Annotations......Page 3745 Viewing the View Hierarchy......Page 3746 Inspections and Captures......Page 3747 Collecting from Android Studio......Page 3748 Screenshots......Page 3749 Collecting from the Command Line......Page 3752 Screenshots......Page 3753 Collecting from Another App......Page 3754 Tips and Tricks......Page 3755 This is the Droid That You Are Looking For......Page 3756 Playing with Permissions......Page 3757 Starting and Stopping Components......Page 3758 Changing Display Metrics......Page 3759 Basic Stetho Integration......Page 3762 Adding the Stetho Dependency......Page 3763 The Main Application......Page 3764 The Debug Application......Page 3766 Overriding the Application......Page 3767 Connecting Chrome to Your App......Page 3769 Elements: View Hierarchy......Page 3770 Network: HTTP Requests......Page 3772 Screencast: Your UI, Mostly......Page 3774 Resources: In-Place Database CLI......Page 3775 Console: Example Environment via JavaScript......Page 3777 Getting Help with Stetho......Page 3778 Getting Things Done......Page 3782 Not Far Enough in the Background......Page 3783 Playing with Speed......Page 3784 Prerequisites......Page 3786 Opening the Profiler......Page 3787 Manipulating the Profiler......Page 3788 Method Tracing......Page 3789 Debug Class......Page 3790 Interpreting Trace Data......Page 3791 Logging......Page 3794 UI “Jank” Measurement......Page 3795 Enabling Developer Options......Page 3796 Toggling on GPU Profiling......Page 3797 Collecting Data......Page 3798 Analyzing the Results......Page 3803 Enabling and Collecting a Trace: Command-Line......Page 3804 Collecting Traces on Android P Devices......Page 3806 Choosing the Trace Tags......Page 3809 Augmenting the Trace from Java......Page 3810 Viewing and Interpreting the Results......Page 3811 Prerequisites......Page 3814 Dalvik: Secure, Yes; Speedy, Not So Much......Page 3815 Porting......Page 3816 Cross-Platform Compatibility......Page 3817 Installing the NDK......Page 3818 Your C/C++ Code......Page 3819 Your Makefile......Page 3820 Building Your Library......Page 3822 Your Java and JNI Code......Page 3824 libhoudini and the NDK......Page 3828 Reduce CPU Utilization......Page 3830 Avoid Floating-Point Math......Page 3831 Support Hardware-Accelerated Graphics......Page 3832 Remote Bound Service......Page 3833 Remote OS Operation......Page 3834 Reduce Time on the Main Application Thread......Page 3835 Generate Less Garbage......Page 3836 Background Threads......Page 3837 Asynchronous BroadcastReceiver Operations......Page 3838 Saving SharedPreferences......Page 3841 Improve Throughput and Responsiveness......Page 3843 Set Thread Priority......Page 3844 Do the Work Some Other Time......Page 3845 The Case: ThreePaneDemoBC......Page 3846 Traceview......Page 3847 Overdraw......Page 3849 Extraneous Views......Page 3855 Conclusion: Too Many layout() Calls?......Page 3857 Removing the Jank......Page 3858 Frame Metrics API......Page 3859 What Data You Get......Page 3860 How You Get That Data......Page 3861 Prerequisites......Page 3866 You’re Using Too Much of the Expensive Stuff......Page 3867 You’re Using Too Much of Somebody Else’s Stuff......Page 3868 You’re Using Too Much… And There Is None......Page 3869 Device Statistics......Page 3870 Interpreting the Results......Page 3871 TrafficRecord......Page 3872 TrafficSnapshot......Page 3873 TrafficMonitorActivity......Page 3874 Using TrafficMonitor......Page 3878 In Production......Page 3881 During Testing......Page 3882 On-Device Measurement......Page 3884 Data Usage Screen in Settings......Page 3885 Wireshark......Page 3888 Android Studio Profiler......Page 3890 Bandwidth Savings......Page 3892 If-Modified-Since / If-None-Match......Page 3893 Keep-Alive Semantics......Page 3894 Thumbnails and Tiles......Page 3895 Bandwidth Shaping......Page 3896 Budgets......Page 3897 Windows......Page 3898 Driven by Other Usage......Page 3899 Data Saver......Page 3900 Prerequisites......Page 3902 You Are in a Heap of Trouble......Page 3903 Fragments of Memory......Page 3904 onTrimMemory() Callbacks......Page 3905 Warning: Contains Graphic Images......Page 3906 Bitmap Caching......Page 3907 Bitmap Sizing......Page 3908 Bitmap Color Space......Page 3917 Cheating......Page 3918 The 1MB IPC Transaction Limit......Page 3919 Prerequisites......Page 3922 Android Studio Profiler......Page 3923 From Code......Page 3926 Class List......Page 3927 Package Tree View......Page 3929 Instance List......Page 3931 Identifying Leak Candidates......Page 3932 The Static Widget......Page 3933 Thread References......Page 3935 Retaining Too Much......Page 3937 A Canary in a Leaky Coal Mine......Page 3940 Adding the Dependencies......Page 3941 Adding the Application......Page 3942 Testing with LeakCanary......Page 3943 The Leak Toast......Page 3944 Logcat Output......Page 3945 Notification and Activity Output......Page 3946 Can’t We All Just Get Along?......Page 3950 Contributors to System RAM Consumption......Page 3951 Process Stats in Settings......Page 3952 The Summary......Page 3954 Refresh and Duration......Page 3955 Drilling Down Into an App......Page 3957 procstats......Page 3959 meminfo......Page 3963 getMemoryInfo()......Page 3968 Learn To Let Go (Of Your Heap)......Page 3969 Prerequisites......Page 3972 You’re Getting Blamed......Page 3973 Stretching Out the Last mWh......Page 3974 Prerequisites......Page 3976 Running a Test......Page 3977 Battery History......Page 3978 Per-PID Stats......Page 3979 Daily Stats......Page 3980 “Statistics since last charge” Summary......Page 3981 WakeLock Summary......Page 3982 Installing the Battery Historian......Page 3984 Interpreting the Historian Output......Page 3985 PowerTutor......Page 3988 Battery Screen in Settings Application......Page 3992 BatteryInfo Dump......Page 3994 Prerequisites......Page 3998 Screen......Page 3999 Disk I/O......Page 4000 Use What You Already Downloaded......Page 4001 Use In Batches......Page 4002 Use When Android Wants You To......Page 4003 GPS......Page 4004 Additional Sources......Page 4005 Sensors......Page 4006 Audio Input and Output......Page 4007 The APK Analyzer......Page 4008 What Is It?......Page 4011 Where Are The Methods Coming From?......Page 4012 Use Granular Libraries......Page 4013 Use ProGuard......Page 4014 Multidex......Page 4015 Mitigation via libhoudini......Page 4016 Mitigation via Resource Aliases......Page 4017 Mitigation via pngquant......Page 4018 APK Expansion Files......Page 4019 What Happens When Things Go “Boom”?......Page 4020 Introducing ACRA......Page 4021 Acralyzer......Page 4022 A Host for Testing......Page 4023 Adding the Dependencies......Page 4024 Build Types, Product Flavors, and ACRA......Page 4025 Creating a Custom Application......Page 4026 Configuring the Core......Page 4028 Initializing ACRA......Page 4029 What the User Sees......Page 4030 Dialog......Page 4031 Notification......Page 4034 What You See......Page 4036 ACRA and Processes......Page 4042 Prerequisites......Page 4046 The Diagnostic Activity......Page 4047 The Manifest......Page 4048 The Activity......Page 4049 The Results......Page 4056 The Limitations......Page 4057 The Diagnostic Overlay......Page 4058 Introducing RVAdapterWrapper......Page 4059 TimingWrapper (a.k.a., StrictMode for RecyclerView)......Page 4061 The RecyclerViewActivity......Page 4064 Being Stupid......Page 4065 Areas for Improvement......Page 4066 What Changed in Android 6.0......Page 4067 Leak Threads… Or Things Attached to Threads......Page 4074 The Counter-Arguments......Page 4075 Use Large Heap Unnecessarily......Page 4076 The Counter-Arguments......Page 4077 The Counter-Arguments......Page 4078 The Costs......Page 4079 The Counter-Arguments......Page 4080 The Costs......Page 4081 Implement a “Quit” Button......Page 4082 The Counter-Arguments......Page 4083 The Counter-Arguments......Page 4084 The Costs......Page 4085 Use Multiple Processes......Page 4086 The Counter-Arguments......Page 4087 The Counter-Arguments......Page 4088 Key Usage Tips......Page 4092 Visual Representation......Page 4093 Key Usage Tips......Page 4094 A Sample Usage......Page 4095 Visual Representation......Page 4096 Key Usage Tips......Page 4100 A Sample Usage......Page 4101 Visual Representation......Page 4103 Key Usage Tips......Page 4108 A Sample Usage......Page 4109 Visual Representation......Page 4115 A Sample Usage......Page 4118 Visual Representation......Page 4121 Declaring a SlidingPaneLayout......Page 4124 Visual Representation......Page 4125 Interacting with a SlidingPaneLayout......Page 4127 Key Usage Tips......Page 4128 A Sample Usage......Page 4129 Visual Representation......Page 4130 Key Usage Tips......Page 4132 A Sample Usage......Page 4133 Visual Representation......Page 4135 A Sample Usage......Page 4138 Visual Representation......Page 4140 Key Usage Tips......Page 4144 A Sample Usage......Page 4145 Visual Representation......Page 4146 Prerequisites......Page 4150 How This Works......Page 4151 Testing Your App on Chrome OS......Page 4152 Step #2: Enable Android Apps......Page 4153 Step #3: Switch the Device to the Dev Channel......Page 4155 Step #4: Enable Chrome OS Developer Mode......Page 4157 Step #5: Set Up the Android Environment......Page 4158 Step #7a: Configure the Chrome OS Device......Page 4159 Step #7b: Find Your Chrome OS IP Address......Page 4160 Be Prepared To Be Wiped Out......Page 4162 Trying to Stay Away From Chrome OS......Page 4163 Environment......Page 4164 System Features......Page 4167 Other Values......Page 4168 Lifecycle Events......Page 4169 Storage......Page 4170 Miscellaneous Oddities......Page 4171 Distribution Options......Page 4172 Getting Help......Page 4173 Device Catalog: BlackBerry......Page 4174 Hardware......Page 4175 BlackBerry OS 10.3......Page 4176 Package Name Length......Page 4177 Getting Your Development Environment Established......Page 4178 Android Studio Plugin......Page 4179 Developing on Hardware......Page 4180 Alternatives......Page 4181 Hey, Wait a Minute… I Thought the Name Was “Google TV”?......Page 4184 ADT-1......Page 4185 Nexus Player......Page 4186 Screen Size and Density......Page 4187 Ethernet......Page 4188 Media Keys......Page 4189 Getting Your Development Environment Established......Page 4190 How Does Distribution Work?......Page 4192 Avoiding Android TV......Page 4193 Introducing the Fire TV Devices......Page 4196 Fire TV......Page 4197 FIre TV Stick......Page 4201 Input Devices......Page 4202 What Is Really Different?......Page 4203 Casting and Fire TV......Page 4204 Getting Your Development Environment Established......Page 4205 Working with the Remote and Controller......Page 4206 Gaming Controller......Page 4207 Getting Help......Page 4208 Device Catalog: Samsung DeX......Page 4210 Screen Mirroring......Page 4212 DeX Mode......Page 4213 Configuration and State Changes......Page 4214 Moving In and Out of DeX......Page 4215 Debugging Interface......Page 4216 Screenshots......Page 4217 Detecting DeX......Page 4218 For More Information......Page 4219 cwac-colormixer......Page 4222 cwac-merge......Page 4223 cwac-saferoom......Page 4224 cwac-wakeful......Page 4225 Background Service Limitations......Page 4226 What Is Affected......Page 4227 Why This Ban Was Added......Page 4229 Workarounds for Senders......Page 4230 Workarounds for Receivers......Page 4232 JobScheduler Enhancements......Page 4233 Auto-Fill......Page 4234 Other Changes with Notifications......Page 4235 Storage Access Framework Changes......Page 4236 Fonts as Resources......Page 4237 Content Annotations......Page 4238 Seekable Streams......Page 4239 Implementing a ProxyFileDescriptorCallback......Page 4240 Using a ProxyFileDescriptorCallback......Page 4242 Foreground Heap Compaction......Page 4243 Shortcuts, App Widgets, and Pinning......Page 4244 FragmentLifecycleCallbacks......Page 4245 Permission Granularity......Page 4246 App Categories......Page 4247 Alert Windows......Page 4248 StorageStatsManager......Page 4249 TextClassificationManager......Page 4250 A Brief History of Developer Previews......Page 4252 Setting Up the Emulator......Page 4253 Flashing a Test Device......Page 4254 Native Fragment Deprecation......Page 4255 No Hidden API Access......Page 4256 A Minimum targetSdkVersion......Page 4258 “The War on Background Processing”, Continued......Page 4260 Device Administration Deprecations......Page 4261 Signature Changes and Deprecations......Page 4262 Notification Improvements......Page 4263 BiometricPrompt......Page 4264 ACTION_FINGERPRINT_ENROLL......Page 4268 Display Cutouts......Page 4269 ImageDecoder......Page 4271 AppComponentFactory......Page 4272 JobScheduler Additions......Page 4276 StrictMode Callbacks......Page 4277 Disabling It......Page 4280 Tracing It......Page 4281 Storage Volume Action......Page 4284 Mixed Case Buttons......Page 4285 Magnifier......Page 4286 Further Library Subdivision......Page 4288 New Design Widgets......Page 4289 Getting Help with P......Page 4290 Viewing the Appinar Roster......Page 4292 Managing Appinars......Page 4295 Viewing an Appinar......Page 4298 Navigating the Appinar......Page 4299 Manipulating the Content......Page 4300

Similar books