Statistics
7
Views
0
Downloads
0
Donations
Support
Share
Uploader

高宏飞

Shared on 2026-02-17

AuthorMark L. Murphy

No description

Tags
No tags
Publish Year: 2020
Language: 英文
File Format: PDF
File Size: 2.8 MB
Support Statistics
¥.00 · 0times
Text Preview (First 20 pages)
Registered users can read the full content for free

Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.

(This page has no text content)
Elements of Android R by Mark L. Murphy
Elements of Android R by Mark L. Murphy Copyright © 2020 CommonsWare, LLC. All Rights Reserved. Printed in the United States of America. Printing History: November 2020: FINAL Version The CommonsWare name and logo, “Busy Coder's Guide”, and related trade dress are trademarks of CommonsWare, LLC. All other trademarks referenced in this book are trademarks of their respective firms. The publisher and author(s) assume no responsibility for errors or omissions or for damages resulting from the use of the information contained herein.
Table of Contents Headings formatted in bold-italic have changed since the last version. • Preface ◦ The Book’s Prerequisites ..................................................................... iii ◦ What’s New in the Final Version? ............................................. iii ◦ Warescription ....................................................................................... iv ◦ Source Code and Its License ................................................................. v ◦ Creative Commons and the Four-to-Free (42F) Guarantee ........ v ◦ Acknowledgments ................................................................................. v • Storage Shifts ◦ Recapping What Happened in Android 10 .......................................... 1 ◦ Let’s Do the Time Warp ........................................................................ 2 ◦ Extending the Opt-Out ......................................................................... 3 ◦ Raw Paths Support ................................................................................ 3 ◦ Hey, What About Writing? .................................................................. 8 ◦ SAF Restrictions .................................................................................... 8 ◦ “All Files Access” ................................................................................... 13 • MediaStore Modifications ◦ Recapping What We Got in Android 10 .............................................. 17 ◦ Getting the Right Uri ........................................................................... 19 ◦ Batched Access ..................................................................................... 19 • Permission Permutations ◦ One-Time Permissions ........................................................................ 28 ◦ Multiple Rejections = Denial .............................................................. 30 ◦ Background Location Changes ........................................................... 32 ◦ Automatic Permission Removal ......................................................... 38 • Auditing Alternatives ◦ Data Access Auditing ........................................................................... 41 ◦ Application Exits ................................................................................. 46 • Package Visibility ◦ The Way Things Were ......................................................................... 53 ◦ Social Distancing for Apps .................................................................. 54 ◦ Whitelisting ......................................................................................... 54 ◦ Escaping the Sandbox ......................................................................... 57 ◦ Effects and Ramifications .................................................................... 58 ◦ So… Why Bother? ................................................................................ 61 ◦ Logging What Was Filtered ................................................................ 61 i
• Sharing UIs ◦ UI Embedding: The Classic Approaches ............................................ 63 ◦ What Android 11 Offers ...................................................................... 64 ◦ How to Share ....................................................................................... 64 ◦ Enabling Input ..................................................................................... 74 • Conversations and Bubbles ◦ From “Chat Heads” to Bubbles ........................................................... 76 ◦ The Basics of Conversations ............................................................... 77 ◦ The Basics of Bubbles ......................................................................... 80 • Security Stuff ◦ New Foreground Service Types ........................................................... 87 ◦ BiometricPrompt and Weak Biometrics ........................................... 88 ◦ Toast Restrictions ................................................................................ 91 ◦ Further CA Certificate Restrictions .................................................... 91 • Device Controls ◦ The High-Level View ........................................................................... 93 ◦ Elements of a Control Tile .................................................................. 97 ◦ Flow… But Not That Flow ................................................................... 99 ◦ Taking Control of the Situation ........................................................ 100 ◦ Other APIs ........................................................................................... 114 • Other Changes of Note ◦ Stuff That Might Break You ............................................................... 117 ◦ Stuff That Might Interest You .................................................. 122 ii
Preface Thanks! Thanks for your continued interest in Android! Android advances year after year, and 2020’s Android 11 (R) continues that pattern. Many developers ignore new Android versions until some concrete problem causes them grief. Hopefully, you are reading this in advance of when Android 11 ships to lots of devices, so you can head off any problems before they turn into customer complaints. (on the other hand, if you are reading this in response to Android 11 customer complaints… sorry!) And thanks for your interest in this book and CommonsWare’s overall line of Android books! The Book’s Prerequisites This book is designed for developers with 1+ years of Android app development experience. If you are fairly new to Android, please consider reading Elements of Android Jetpack, Exploring Android, or both, before continuing with this book. Also note that this book’s examples are written in Kotlin. What’s New in the Final Version? This book is almost unchanged from the previous version. iii
Warescription If you purchased the Warescription, read on! If you obtained this book from other channels, feel free to jump ahead. The Warescription entitles you, for the duration of your subscription, to digital editions of this book and its updates, in PDF, EPUB, and Kindle (MOBI/KF8) formats, plus the ability to read the book online at the Warescription Web site. You also have access to other books that CommonsWare publishes during that subscription period. Each subscriber gets personalized editions of all editions of each title. That way, your books are never out of date for long, and you can take advantage of new material as it is made available. However, you can only download the books while you have an active Warescription. There is a grace period after your Warescription ends: you can still download the book until the next book update comes out after your Warescription ends. After that, you can no longer download the book. Hence, please download your updates as they come out. You can find out when new releases of this book are available via: 1. The CommonsBlog 2. The CommonsWare Twitter feed 3. Opting into emails announcing each book release — log into the Warescription site and choose Configure from the nav bar 4. Just check back on the Warescription site every month or two Subscribers also have access to other benefits, including: • “Office hours” — online chats to help you get answers to your Android application development questions. You will find a calendar for these on your Warescription page. • A Stack Overflow “bump” service, to get additional attention for a question that you have posted there that does not have an adequate answer. • A discussion board for asking arbitrary questions about Android app development. PREFACE iv
Source Code and Its License The source code in this book is licensed under the Apache 2.0 License, in case you have the desire to reuse any of it. Copying source code directly from the book, in the PDF editions, works best with Adobe Reader, though it may also work with other PDF viewers. Some PDF viewers, for reasons that remain unclear, foul up copying the source code to the clipboard when it is selected. Creative Commons and the Four-to-Free (42F) Guarantee Each CommonsWare book edition will be available for use under the Creative Commons Attribution-Noncommercial-ShareAlike 3.0 license as of the fourth anniversary of its publication date, or when 4,000 copies of the edition have been sold, whichever comes first. That means that, once four years have elapsed (perhaps sooner!), you can use this prose for non-commercial purposes. That is our Four-to- Free Guarantee to our readers and the broader community. For the purposes of this guarantee, new Warescriptions and renewals will be counted as sales of this edition, starting from the time the edition is published. This edition of this book will be available under the aforementioned Creative Commons license on 1 November 2024. Of course, watch the CommonsWare Web site, as this edition might be relicensed sooner based on sales. For more details on the Creative Commons Attribution-Noncommercial-ShareAlike 3.0 license, visit the Creative Commons Web site Note that future editions of this book will become free on later dates, each four years from the publication of that edition or based on sales of that specific edition. Releasing one edition under the Creative Commons license does not automatically release all editions under that license. Acknowledgments The author would like to thank the Google team responsible for Android 11. PREFACE v
(This page has no text content)
Storage Shifts Android 10 introduced what Google calls “scoped storage” and what the author of this book called “the death of external storage”. Android 11 tweaks scoped storage some more, improving things in some areas and causing new and exciting challenges in others. Recapping What Happened in Android 10 Before we dive into the Android 11 changes to scoped storage, let’s quickly review what happened in Android 10. You can learn more about scoped storage in Android 10 in the "The Death of External Storage" chapter of Elements of Android Q! Limited Filesystem Access While apps can still use getExternalFilesDir() and other methods on Context to work with external and removable storage, everything else has been blocked. Notably, the methods on Environment like getExternalStorageDirectory() and getExternalStoragePublicDirectory() are deprecated. And, if you try to use those directories, you will find that your app lacks access, even if you hold READ_EXTERNAL_STORAGE and/or WRITE_EXTERNAL_STORAGE. Roughly speaking, there are three alternatives for addressing this limitation. 1
Alternative #1: Storage Access Framework For general-purpose content, Google expects you to use the Storage Access Framework: • ACTION_OPEN_DOCUMENT to have the user choose a piece of content • ACTION_CREATE_DOCUMENT to create a new piece of content in a user-chosen location • ACTION_OPEN_DOCUMENT_TREE to have the user choose a “document tree” (e.g., a directory) that you can then use for reading and writing The actual mechanics of the Storage Access Framework did not change in Android 10, merely its importance. Alternative #2: MediaStore For apps that work with media and wish to place content in common media locations, MediaStore is still an option. However, the behavior of MediaStore changed some in Android 10 and again in Android 11 — we will explore that more in the next chapter. Alternative #3: Opt Out of the Change You could add android:requestLegacyExternalStorage="true" to the <application> element in the manifest to say that you want the “legacy” storage model. In other words, android:requestLegacyExternalStorage="true" has your app running on Android 10 behave much as it would on Android 9. Alternatively, simply having a targetSdkVersion below 29 would give you the same effect. Let’s Do the Time Warp Back when Android 10 was still Android Q, we were told that android:requestLegacyExternalStorage="true" would no longer work once we raised targetSdkVersion to 29. Somewhere along the line, Google rescinded that, and the author of this book missed that change. STORAGE SHIFTS 2
It appears that in the final release of Android 10, Google allowed android:requestLegacyExternalStorage="true" regardless of targetSdkVersion. Since Android 11 also honors it — at least until you reach targetSdkVersion 30 — this gives you a bit more time to adapt to scoped storage. Extending the Opt-Out Android 11 also offers android:preserveLegacyExternalStorage="true". This says: • For users who upgrade the app, opt out of scoped storage • For users who freshly install the app, use scoped storage as normal There is no timetable given for if and when android:preserveLegacyExternalStorage might no longer be honored, though the documentation states: Note that this may not always be respected due to policy or backwards compatibility reasons. Also, it means that different users of the same app version will get different storage behavior, depending on how the user got that app version (fresh install vs. upgrade). And, of course, since this is new to Android 11, this should have no effect on Android 10 devices. Given all of that, this seems like an attribute to avoid. Raw Paths Support However, even without the opt-out, READ_EXTERNAL_STORAGE works again, more or less as it did from Android 4.4 through Android 9. If you request it, and the user grants it, you can traverse external storage as you were used to. However, there are major caveats: • You still do not have access to Android/ and its subdirectories. We will see this limitation again with the Storage Access Framework. Google now considers those per-app external storage directories to be private. • You still do not have read access to certain other locations, such as STORAGE SHIFTS 3
Documents/ and Downloads/. Basically, if it is controlled by MediaStore, and you lack read access through MediaStore, you also lack read access through raw paths. • Removable storage does not appear to be supported by this “raw paths” feature. • The documentation mentions reduced performance. This does not appear to be severe, but it may pose issues for performance-sensitive apps. Note that while the documentation emphasizes native libraries, read access works fine from Java/Kotlin. Also, methods like getExternalStorageDirectory() and getExternalStoragePublicDirectory() on Environment are still deprecated. Instead, we are supposed to use getDirectory() on StorageVolume, which is new to Android 11. As the names suggest, this gives us the root directory for a particular storage volume, whether that is external storage or some removable storage device. The RawPaths sample module in the book’s sample project is designed to demonstrate the behavior of READ_EXTERNAL_STORAGE across a variety of build scenarios. There are five product flavors, with varying configurations: Flavor targetSdkVersion requestLegacyExternalStorage alfa 28 true bravo 29 true charlie 29 false delta 30 true echo 30 false STORAGE SHIFTS 4
The UI is a crude file explorer. It shows you a list of files and directories for a particular location, starting with some root: Figure 1: RawPaths, Echo Build, Running on Android 11 DP2 STORAGE SHIFTS 5
The “SD card” toolbar button will display a checkable submenu with the available storage volumes: Figure 2: RawPaths, Echo Build, Showing Storage Volume Submenu If you switch to a different storage volume, that volume’s root directory will be loaded into the list. Tapping on a file, by default, will bring up a Toast showing the CRC32 checksum of the file, used to prove that we have read access to the file’s contents. Tapping on a directory will load that directory’s contents into the list. However, this is a fairly simplistic file explorer, so there is no way to traverse up the directory tree to get back to a root. Before loading any of this content, though, MainActivity will request the READ_EXTERNAL_STORAGE permission. Our viewmodel, MainMotor, gets the roster of StorageVolume objects from the StorageManager system service: val volumes: List<StorageVolume> = context.getSystemService(StorageManager::class.java)!!.storageVolumes STORAGE SHIFTS 6
(from RawPaths/src/main/java/com/commonsware/android/r/rawpaths/MainMotor.kt) MainActivity uses that list to build up the submenu contents. If the user taps on one, MainActivity calls a loadRoot() function on MainMotor. If the app is running on Android 11, that in turn gets the selected StorageVolume out of that list and retrieves its directory. On older devices, we just use the deprecated Environment.getExternalStorageDirectory() option instead: fun loadRoot(volumeIndex: Int = 0) { if (Build.VERSION.SDK_INT < 30) { load(Environment.getExternalStorageDirectory()) } else { load(volumes[volumeIndex].directory!!) } } (from RawPaths/src/main/java/com/commonsware/android/r/rawpaths/MainMotor.kt) That directory is then used by the load() function to get the directory’s contents and calculate the CRC32 checksums for all files in the directory: fun load(dir: File) { _states.postValue(MainViewState.Loading) viewModelScope.launch(Dispatchers.IO) { try { val items = dir.listFiles().orEmpty() .sortedBy { it.name } .map { file -> if (file.isDirectory) { FileItem(file, isDirectory = true) } else { FileItem(file, crc32 = CRC32().let { crc -> crc.update(file.readBytes()) crc.value }) } } _states.postValue(MainViewState.Content(items)) } catch (t: Throwable) { Log.e("RawPaths", "Exception loading $dir", t) _states.postValue(MainViewState.Error) } } } STORAGE SHIFTS 7
(from RawPaths/src/main/java/com/commonsware/android/r/rawpaths/MainMotor.kt) What you will find is: • On Android 11, both delta and echo behave the same. delta requests the scoped storage opt-out (android:requestLegacyExternalStorage="true"), while echo does not. Yet, with READ_EXTERNAL_STORAGE, we can still access the contents of external storage, though apparently not removable storage and the other restricted locations noted above. • On Android 10, android:requestLegacyExternalStorage has a clear effect. If you use it (bravo), READ_EXTERNAL_STORAGE works, even though we have targetSdkVersion set to 29. If you do not use it (charlie), even if the user grants READ_EXTERNAL_STORAGE, you do not have filesystem access to external storage. • On Android 9, before all of these changes took effect, READ_EXTERNAL_STORAGE works normally. Hey, What About Writing? You have write access to certain raw paths… even without WRITE_EXTERNAL_STORAGE. However, the exact list of these locations is undocumented. As such, these locations are unreliable — device manufacturers might elect to change the behavior here. But, based on experiments and some Google comments you should be able to write to: • Download/ • DCIM/ • Movies/ • Music/ …and perhaps others. SAF Restrictions Since the beginning, the Storage Access Framework has been billed as the way for the app to get access to whatever content the user wants to work with. In Android 11, that is no longer the case, as the OS will prevent the user from STORAGE SHIFTS 8
accessing the user’s content in scenarios that Google does not like. ACTION_OPEN_DOCUMENT_TREE In the Android 11 version of this UI, the user can navigate into a directory and click a “Use this folder” button at the bottom to choose it: Figure 3: SAF UI, Showing “Use this folder” Button However, that button will be grayed out in some situations. STORAGE SHIFTS 9
Overall External Storage Root The user cannot grant an app rights to work with the root of external storage, precluding apps from placing new directories there: Figure 4: SAF UI, Showing Disabled “Use this folder” Button for External Storage Root STORAGE SHIFTS 10
Download/ The same holds true for Download/: Figure 5: SAF UI, Showing Disabled “Use this folder” Button for Download/ However, if the user creates a subdirectory of Download/, such as via their USB cable or the stock Files app, they can choose that subdirectory. STORAGE SHIFTS 11