Slide 1

Slide 1 text

Scoping Your Storage GDGMAD 1

Slide 2

Slide 2 text

What is Scoped Storage ? — Restricted Access to system wide files — Unlimited Access to own files GDGMAD 2

Slide 3

Slide 3 text

Why Scoped Storage ? — Limit Access — Reduce File Clutter ! — Better User Experience " — Clear separation between Private vs Shared Storage — Protect User Data/Privacy GDGMAD 3

Slide 4

Slide 4 text

What's Changing ? GDGMAD 4

Slide 5

Slide 5 text

Access To Files Limited access to files you don't own Unrestricted Access to create files GDGMAD 5

Slide 6

Slide 6 text

Organised Media/Downloads Collection — Unrestricted write access to Media collections & Downloads Collection — Only Media Collections access using READ_EXTERNAL_STORAGE permission — System Picker for other files (SAF) (Read or Write) GDGMAD 6

Slide 7

Slide 7 text

Modify/Delete Media Files — Explicit User Consent Required — Bulk Edit/Delete Option — Copy & Edit data GDGMAD 7

Slide 8

Slide 8 text

User Consent fun editImage(uri:Uri) { try { contentResolver.openFileDescriptor(uri, "w")?.use { //Edit Media } } catch(ex: SecurityException) { val intentSender = ex.userAction.actionIntent.intentSender intentSender?.let { startIntentSenderForResult(intentSender,..., ..., ...) } } } GDGMAD 8

Slide 9

Slide 9 text

Working With SAF GDGMAD 9

Slide 10

Slide 10 text

Open A Document - ACTION_OPEN_DOCUMENT val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) .setType("text/*") .addCategory(Intent.CATEGORY_OPENABLE) startActivityForResult(intent, REQUEST_SAF) GDGMAD 10

Slide 11

Slide 11 text

Create A Document - ACTION_CREATE_DOCUMENT val intent = Intent(Intent.ACTION_CREATE_DOCUMENT) .setType("text/plain") .addCategory(Intent.CATEGORY_OPENABLE) startActivityForResult(intent, REQUEST_SAF) GDGMAD 11

Slide 12

Slide 12 text

Open Document Tree(Directories/sub-dir) - ACTION_OPEN_DOCUMENT_TREE val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) startActivityForResult(intent, REQUEST_TREE) GDGMAD 12

Slide 13

Slide 13 text

SAF Restrictions — No Access to android/data folder — OPEN_DOCUMENT_TREE won't allow choosing root directory or Downloads directory — Special App Access Declaration Form for accessing entire shared storage GDGMAD 13

Slide 14

Slide 14 text

Caveats — Access rights for URI tied to Activity — Cloud Providers break the SAF contract — ACTION_CREATE_DOCUMENT can't overwrite content — OEMS break the SAF Intent Actions GDGMAD 14

Slide 15

Slide 15 text

What do I do ? GDGMAD 15

Slide 16

Slide 16 text

Write/Create Access — Write files to app directories - No permission needed — Write files to Media/Download Collection - No permission needed — Write files to other non media collections - Use SAF GDGMAD 16

Slide 17

Slide 17 text

Read Access — Read files from app directories - No permission needed — Read own files from Media Collection - No permission needed — Read other app files from Media Collection - READ_EXTERNAL_STORAGE needed — Read files from other non media collections - Use SAF GDGMAD 17

Slide 18

Slide 18 text

Edit/Delete Access — Edit/Delete files from app directories - No permission needed — Edit/Delete own files from Media Collection - No permission needed — Edit/Delete other app files from Media Collection - User Consent Needed — Edit/Delete files from other non media collections - Use SAF GDGMAD 18

Slide 19

Slide 19 text

Migration — Move files from shared storage space to App Directory or lose them — requestLegacyExternalStorage="true" will stop working if you target Android 11 — Needs External Media files - READ_EXTERNAL_STORAGE permission — Access external non media files via SAF GDGMAD 19

Slide 20

Slide 20 text

References — Working with Scoped Storage - Fernando García Álvarez — Scoped Storage Stories - CommonsWare GDGMAD 20

Slide 21

Slide 21 text

Thank You ! Twitter - @AdnanM0123 GDGMAD 21