Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Document-centric Android

19f33af017093834caecee97856322e6?s=47 cketti
June 04, 2015

Document-centric Android

This talk shows how to use the Storage Access Framework and also how to make use of the option to have multiple entries per app in the Overview Screen (previously: Recents Screen).

http://droidcon.de/session/be-part-document-centric-android
https://www.youtube.com/watch?v=sMlsBAXMXok

19f33af017093834caecee97856322e6?s=128

cketti

June 04, 2015
Tweet

Transcript

  1. Document-centric Android Droidcon Berlin 2015

  2. Overview • Storage Access Framework • Document-centric Overview Screen

  3. Storage Access Framework • framework to browse and open documents,

    images, and other files across preferred document storage providers • standard, easy-to-use UI to let users access documents in a consistent way across apps
  4. Getting content the hard way Custom file picker

  5. Getting content the hard way Custom file picker

  6. Getting content the hard way Custom file picker

  7. Getting content the old way ACTION_GET_CONTENT before the introduction of

    the Storage Access Framework
  8. Getting content the “new” way Android 4.4+ • Document Providers

    at the top • “Legacy” providers at the bottom
  9. SAF User Interface

  10. SAF User Interface

  11. SAF User Interface

  12. SAF User Interface

  13. Getting content Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); Intent

    chooserIntent = Intent.createChooser(i, null); startActivityForResult(chooserIntent, requestCode);
  14. Getting content Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE,

    true); Intent chooserIntent = Intent.createChooser(i, null); startActivityForResult(chooserIntent, requestCode); intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
  15. Getting content - onActivityResult if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { ClipData

    clipData = data.getClipData(); if (clipData != null) { // read URIs from ClipData return; } } // read URI from Intent.getData()
  16. Options for saving content • Download Manager • Share Intent

    • Write to hardcoded directories • …
  17. Picking a directory Use third-party app to select directory

  18. Picking a directory Use third-party app to select directory private

    static final String[][] PICK_DIRECTORY_INTENTS = { { "org.openintents.action.PICK_DIRECTORY", "file://" }, { "com.estrongs.action.PICK_DIRECTORY", "file://" }, { Intent.ACTION_PICK, "folder://" }, { "com.androidworkz.action.PICK_DIRECTORY", "file://" } };
  19. Saving content the hard way Custom UI • Cloud providers

    need to be supported by the app
  20. Saving content the new way ACTION_CREATE_DOCUMENT

  21. Saving content the new way Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);

    intent.setType("image/jpeg"); intent.putExtra(Intent.EXTRA_TITLE, "corgi.jpg"); intent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(intent, requestCode);
  22. Picking a directory the new way Intent intent = new

    Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); startActivityForResult(intent, requestCode); // in onActivityResult - receive URI for document tree String rootDocumentId = DocumentsContract.getTreeDocumentId(treeUri); Uri rootDocumentUri = DocumentsContract.buildDocumentUriUsingTree( treeUri, rootDocumentId); Uri newDocumentUri = DocumentsContract.createDocument( contentResolver, rootDocumentUri, "image/png", "new.png");
  23. Picking a directory the new way ACTION_OPEN_DOCUMENT_TREE Not even implemented

    by the Google Drive app :(
  24. Overview Screen • Introduced with Android 5.0 • Previously app-centric

    Recent Apps Screen
  25. App-centric world Recent Apps one entry per app

  26. Document-centric world Overview Screen one entry per document

  27. How to create a new document task? Ideally, it just

    works Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("mailto:bob@example.com")); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); startActivity(intent);
  28. How to create a new document task? Ideally, it just

    works Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("mailto:bob@example.com")); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); startActivity(intent); Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
  29. How to create a new document task? Ideally, it just

    works Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse("mailto:bob@example.com")); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); startActivity(intent); Intent.FLAG_ACTIVITY_NEW_DOCUMENT
  30. When to use FLAG_ACTIVITY_NEW_DOCUMENT? • Potentially whenever starting an external

    activity • When multiple entries for your app in the Overview Screen are desirable
  31. More Activity Flags • With FLAG_ACTIVITY_NEW_DOCUMENT existing tasks will be

    brought to the front • Use FLAG_ACTIVITY_MULTIPLE_TASK to force creation of a new task
  32. documentLaunchMode • always • intoExisting • never • none Use

    this rather than the Intent flag! <activity> attribute in manifest
  33. TaskDescription

  34. TaskDescription TaskDescription taskDescription = new TaskDescription(title, icon, Color.DKGRAY); setTaskDescription(taskDescription);

  35. Manage document tasks • Activity.finishAndRemoveTask() • ActivityManager.getAppTasks() ◦ finishAndRemoveTask() ◦

    moveToFront() ◦ startActivity(…) ◦ getTaskInfo().baseIntent ◦ …
  36. makeTaskLaunchBehind Document tasks are grouped when makeTaskLaunchBehind is used

  37. makeTaskLaunchBehind Intent newDocumentIntent = …; ActivityOptions options = ActivityOptions.makeTaskLaunchBehind(); startActivity(newDocumentIntent,

    options.toBundle());
  38. persistableMode <activity> attribute in manifest • persistRootOnly (default) • persistNever

    • persistAcrossReboots ◦ PeristableBundle
  39. Summary • SAF makes many things easier ◦ Not a

    solution for pre-KitKat devices ◦ Support isn’t great right now :( • Document tasks solve many small issues • It’s easy to get started. Do it now!
  40. Thank you! Questions?

  41. Bonus slide: Corgis CC BY-SA 2.0 Source: https://flic.kr/p/dZrnNm

  42. Further questions? Email: cketti@gmail.com Google+: +cketti