Loading api/current.txt +6 −6 Original line number Diff line number Diff line Loading @@ -7400,6 +7400,7 @@ package android.content { field public static final java.lang.String ACTION_MY_PACKAGE_REPLACED = "android.intent.action.MY_PACKAGE_REPLACED"; field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL"; field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT"; field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE"; field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED"; field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED"; field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED"; Loading @@ -7414,7 +7415,6 @@ package android.content { field public static final java.lang.String ACTION_PASTE = "android.intent.action.PASTE"; field public static final java.lang.String ACTION_PICK = "android.intent.action.PICK"; field public static final java.lang.String ACTION_PICK_ACTIVITY = "android.intent.action.PICK_ACTIVITY"; field public static final java.lang.String ACTION_PICK_DIRECTORY = "android.intent.action.PICK_DIRECTORY"; field public static final java.lang.String ACTION_POWER_CONNECTED = "android.intent.action.ACTION_POWER_CONNECTED"; field public static final java.lang.String ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED"; field public static final java.lang.String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY"; Loading Loading @@ -23824,21 +23824,21 @@ package android.provider { public final class DocumentsContract { method public static android.net.Uri buildChildDocumentsUri(java.lang.String, java.lang.String); method public static android.net.Uri buildChildDocumentsViaUri(android.net.Uri, java.lang.String); method public static android.net.Uri buildChildDocumentsUriUsingTree(android.net.Uri, java.lang.String); method public static android.net.Uri buildDocumentUri(java.lang.String, java.lang.String); method public static android.net.Uri buildDocumentViaUri(android.net.Uri, java.lang.String); method public static android.net.Uri buildDocumentUriUsingTree(android.net.Uri, java.lang.String); method public static android.net.Uri buildRecentDocumentsUri(java.lang.String, java.lang.String); method public static android.net.Uri buildRootUri(java.lang.String, java.lang.String); method public static android.net.Uri buildRootsUri(java.lang.String); method public static android.net.Uri buildSearchDocumentsUri(java.lang.String, java.lang.String, java.lang.String); method public static android.net.Uri buildViaUri(java.lang.String, java.lang.String); method public static android.net.Uri buildTreeDocumentUri(java.lang.String, java.lang.String); method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String); method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri); method public static java.lang.String getDocumentId(android.net.Uri); method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal); method public static java.lang.String getRootId(android.net.Uri); method public static java.lang.String getSearchDocumentsQuery(android.net.Uri); method public static java.lang.String getViaDocumentId(android.net.Uri); method public static java.lang.String getTreeDocumentId(android.net.Uri); method public static boolean isDocumentUri(android.content.Context, android.net.Uri); method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String); field public static final java.lang.String EXTRA_ERROR = "error"; Loading Loading @@ -23877,7 +23877,7 @@ package android.provider { field public static final java.lang.String COLUMN_TITLE = "title"; field public static final int FLAG_LOCAL_ONLY = 2; // 0x2 field public static final int FLAG_SUPPORTS_CREATE = 1; // 0x1 field public static final int FLAG_SUPPORTS_DIR_SELECTION = 16; // 0x10 field public static final int FLAG_SUPPORTS_IS_CHILD = 16; // 0x10 field public static final int FLAG_SUPPORTS_RECENTS = 4; // 0x4 field public static final int FLAG_SUPPORTS_SEARCH = 8; // 0x8 } core/java/android/content/Intent.java +13 −10 Original line number Diff line number Diff line Loading @@ -2731,6 +2731,7 @@ public class Intent implements Parcelable, Cloneable { * returned in {@link #getClipData()}. * * @see DocumentsContract * @see #ACTION_OPEN_DOCUMENT_TREE * @see #ACTION_CREATE_DOCUMENT * @see #FLAG_GRANT_PERSISTABLE_URI_PERMISSION */ Loading Loading @@ -2765,28 +2766,30 @@ public class Intent implements Parcelable, Cloneable { * * @see DocumentsContract * @see #ACTION_OPEN_DOCUMENT * @see #ACTION_OPEN_DOCUMENT_TREE * @see #FLAG_GRANT_PERSISTABLE_URI_PERMISSION */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_CREATE_DOCUMENT = "android.intent.action.CREATE_DOCUMENT"; /** * Activity Action: Allow the user to pick a directory. When invoked, the * system will display the various {@link DocumentsProvider} instances * installed on the device, letting the user navigate through them. Apps can * fully manage documents within the returned directory. * Activity Action: Allow the user to pick a directory subtree. When * invoked, the system will display the various {@link DocumentsProvider} * instances installed on the device, letting the user navigate through * them. Apps can fully manage documents within the returned directory. * <p> * To gain access to descendant (child, grandchild, etc) documents, use * {@link DocumentsContract#buildDocumentViaUri(Uri, String)} and * {@link DocumentsContract#buildChildDocumentsViaUri(Uri, String)} using * the returned directory URI. * {@link DocumentsContract#buildDocumentUriUsingTree(Uri, String)} and * {@link DocumentsContract#buildChildDocumentsUriUsingTree(Uri, String)} * with the returned URI. * <p> * Output: The URI representing the selected directory. * Output: The URI representing the selected directory tree. * * @see DocumentsContract */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_PICK_DIRECTORY = "android.intent.action.PICK_DIRECTORY"; public static final String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE"; // --------------------------------------------------------------------- // --------------------------------------------------------------------- Loading Loading @@ -3365,8 +3368,8 @@ public class Intent implements Parcelable, Cloneable { * * @see #ACTION_GET_CONTENT * @see #ACTION_OPEN_DOCUMENT * @see #ACTION_OPEN_DOCUMENT_TREE * @see #ACTION_CREATE_DOCUMENT * @see #ACTION_PICK_DIRECTORY */ public static final String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY"; Loading core/java/android/provider/DocumentsContract.java +66 −54 Original line number Diff line number Diff line Loading @@ -60,7 +60,8 @@ import java.util.List; * <p> * All client apps must hold a valid URI permission grant to access documents, * typically issued when a user makes a selection through * {@link Intent#ACTION_OPEN_DOCUMENT} or {@link Intent#ACTION_CREATE_DOCUMENT}. * {@link Intent#ACTION_OPEN_DOCUMENT}, {@link Intent#ACTION_CREATE_DOCUMENT}, * or {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. * * @see DocumentsProvider */ Loading @@ -73,8 +74,8 @@ public final class DocumentsContract { // content://com.example/root/sdcard/search/?query=pony // content://com.example/document/12/ // content://com.example/document/12/children/ // content://com.example/via/12/document/24/ // content://com.example/via/12/document/24/children/ // content://com.example/tree/12/document/24/ // content://com.example/tree/12/document/24/children/ private DocumentsContract() { } Loading Loading @@ -441,12 +442,13 @@ public final class DocumentsContract { public static final int FLAG_SUPPORTS_SEARCH = 1 << 3; /** * Flag indicating that this root supports directory selection. * Flag indicating that this root supports testing parent child * relationships. * * @see #COLUMN_FLAGS * @see DocumentsProvider#isChildDocument(String, String) */ public static final int FLAG_SUPPORTS_DIR_SELECTION = 1 << 4; public static final int FLAG_SUPPORTS_IS_CHILD = 1 << 4; /** * Flag indicating that this root is currently empty. This may be used Loading Loading @@ -518,7 +520,7 @@ public final class DocumentsContract { private static final String PATH_DOCUMENT = "document"; private static final String PATH_CHILDREN = "children"; private static final String PATH_SEARCH = "search"; private static final String PATH_VIA = "via"; private static final String PATH_TREE = "tree"; private static final String PARAM_QUERY = "query"; private static final String PARAM_MANAGE = "manage"; Loading Loading @@ -564,17 +566,17 @@ public final class DocumentsContract { * Build URI representing access to descendant documents of the given * {@link Document#COLUMN_DOCUMENT_ID}. * * @see #getViaDocumentId(Uri) * @see #getTreeDocumentId(Uri) */ public static Uri buildViaUri(String authority, String documentId) { public static Uri buildTreeDocumentUri(String authority, String documentId) { return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority) .appendPath(PATH_VIA).appendPath(documentId).build(); .appendPath(PATH_TREE).appendPath(documentId).build(); } /** * Build URI representing the given {@link Document#COLUMN_DOCUMENT_ID} in a * document provider. When queried, a provider will return a single row with * columns defined by {@link Document}. * Build URI representing the target {@link Document#COLUMN_DOCUMENT_ID} in * a document provider. When queried, a provider will return a single row * with columns defined by {@link Document}. * * @see DocumentsProvider#queryDocument(String, String[]) * @see #getDocumentId(Uri) Loading @@ -585,42 +587,46 @@ public final class DocumentsContract { } /** * Build URI representing the given {@link Document#COLUMN_DOCUMENT_ID} in a * document provider. Instead of directly accessing the target document, * gain access via another document. The target document must be a * descendant (child, grandchild, etc) of the via document. * Build URI representing the target {@link Document#COLUMN_DOCUMENT_ID} in * a document provider. When queried, a provider will return a single row * with columns defined by {@link Document}. * <p> * However, instead of directly accessing the target document, the returned * URI will leverage access granted through a subtree URI, typically * returned by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. The target document * must be a descendant (child, grandchild, etc) of the subtree. * <p> * This is typically used to access documents under a user-selected * directory, since it doesn't require the user to separately confirm each * new document access. * directory tree, since it doesn't require the user to separately confirm * each new document access. * * @param viaUri a related document (directory) that the caller is * leveraging to gain access to the target document. The target * document must be a descendant of this directory. * @param treeUri the subtree to leverage to gain access to the target * document. The target directory must be a descendant of this * subtree. * @param documentId the target document, which the caller may not have * direct access to. * @see Intent#ACTION_PICK_DIRECTORY * @see Intent#ACTION_OPEN_DOCUMENT_TREE * @see DocumentsProvider#isChildDocument(String, String) * @see #buildDocumentUri(String, String) */ public static Uri buildDocumentViaUri(Uri viaUri, String documentId) { public static Uri buildDocumentUriUsingTree(Uri treeUri, String documentId) { return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) .authority(viaUri.getAuthority()).appendPath(PATH_VIA) .appendPath(getViaDocumentId(viaUri)).appendPath(PATH_DOCUMENT) .authority(treeUri.getAuthority()).appendPath(PATH_TREE) .appendPath(getTreeDocumentId(treeUri)).appendPath(PATH_DOCUMENT) .appendPath(documentId).build(); } /** {@hide} */ public static Uri buildDocumentMaybeViaUri(Uri baseUri, String documentId) { if (isViaUri(baseUri)) { return buildDocumentViaUri(baseUri, documentId); public static Uri buildDocumentUriMaybeUsingTree(Uri baseUri, String documentId) { if (isTreeUri(baseUri)) { return buildDocumentUriUsingTree(baseUri, documentId); } else { return buildDocumentUri(baseUri.getAuthority(), documentId); } } /** * Build URI representing the children of the given directory in a document * Build URI representing the children of the target directory in a document * provider. When queried, a provider will return zero or more rows with * columns defined by {@link Document}. * Loading @@ -637,28 +643,33 @@ public final class DocumentsContract { } /** * Build URI representing the children of the given directory in a document * provider. Instead of directly accessing the target document, gain access * via another document. The target document must be a descendant (child, * grandchild, etc) of the via document. * Build URI representing the children of the target directory in a document * provider. When queried, a provider will return zero or more rows with * columns defined by {@link Document}. * <p> * However, instead of directly accessing the target directory, the returned * URI will leverage access granted through a subtree URI, typically * returned by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. The target * directory must be a descendant (child, grandchild, etc) of the subtree. * <p> * This is typically used to access documents under a user-selected * directory, since it doesn't require the user to separately confirm each * new document access. * * @param viaUri a related document (directory) that the caller is * leveraging to gain access to the target document. The target * document must be a descendant of this directory. * @param parentDocumentId the target document, which the caller may not * have direct access to. * @see Intent#ACTION_PICK_DIRECTORY * directory tree, since it doesn't require the user to separately confirm * each new document access. * * @param treeUri the subtree to leverage to gain access to the target * document. The target directory must be a descendant of this * subtree. * @param parentDocumentId the document to return children for, which the * caller may not have direct access to, and which must be a * directory with MIME type of {@link Document#MIME_TYPE_DIR}. * @see Intent#ACTION_OPEN_DOCUMENT_TREE * @see DocumentsProvider#isChildDocument(String, String) * @see #buildChildDocumentsUri(String, String) */ public static Uri buildChildDocumentsViaUri(Uri viaUri, String parentDocumentId) { public static Uri buildChildDocumentsUriUsingTree(Uri treeUri, String parentDocumentId) { return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) .authority(viaUri.getAuthority()).appendPath(PATH_VIA) .appendPath(getViaDocumentId(viaUri)).appendPath(PATH_DOCUMENT) .authority(treeUri.getAuthority()).appendPath(PATH_TREE) .appendPath(getTreeDocumentId(treeUri)).appendPath(PATH_DOCUMENT) .appendPath(parentDocumentId).appendPath(PATH_CHILDREN).build(); } Loading @@ -683,21 +694,24 @@ public final class DocumentsContract { * {@link DocumentsProvider}. * * @see #buildDocumentUri(String, String) * @see #buildDocumentViaUri(Uri, String) * @see #buildDocumentUriUsingTree(Uri, String) */ public static boolean isDocumentUri(Context context, Uri uri) { final List<String> paths = uri.getPathSegments(); if (paths.size() >= 2 && (PATH_DOCUMENT.equals(paths.get(0)) || PATH_VIA.equals(paths.get(0)))) { if (paths.size() == 2 && PATH_DOCUMENT.equals(paths.get(0))) { return isDocumentsProvider(context, uri.getAuthority()); } if (paths.size() == 4 && PATH_TREE.equals(paths.get(0)) && PATH_DOCUMENT.equals(paths.get(2))) { return isDocumentsProvider(context, uri.getAuthority()); } return false; } /** {@hide} */ public static boolean isViaUri(Uri uri) { public static boolean isTreeUri(Uri uri) { final List<String> paths = uri.getPathSegments(); return (paths.size() >= 2 && PATH_VIA.equals(paths.get(0))); return (paths.size() >= 2 && PATH_TREE.equals(paths.get(0))); } private static boolean isDocumentsProvider(Context context, String authority) { Loading Loading @@ -733,7 +747,7 @@ public final class DocumentsContract { if (paths.size() >= 2 && PATH_DOCUMENT.equals(paths.get(0))) { return paths.get(1); } if (paths.size() >= 4 && PATH_VIA.equals(paths.get(0)) if (paths.size() >= 4 && PATH_TREE.equals(paths.get(0)) && PATH_DOCUMENT.equals(paths.get(2))) { return paths.get(3); } Loading @@ -742,12 +756,10 @@ public final class DocumentsContract { /** * Extract the via {@link Document#COLUMN_DOCUMENT_ID} from the given URI. * * @see #isViaUri(Uri) */ public static String getViaDocumentId(Uri documentUri) { public static String getTreeDocumentId(Uri documentUri) { final List<String> paths = documentUri.getPathSegments(); if (paths.size() >= 2 && PATH_VIA.equals(paths.get(0))) { if (paths.size() >= 2 && PATH_TREE.equals(paths.get(0))) { return paths.get(1); } throw new IllegalArgumentException("Invalid URI: " + documentUri); Loading core/java/android/provider/DocumentsProvider.java +43 −38 File changed.Preview size limit exceeded, changes collapsed. Show changes packages/DocumentsUI/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ <data android:mimeType="*/*" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.PICK_DIRECTORY" /> <action android:name="android.intent.action.OPEN_DOCUMENT_TREE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> Loading Loading
api/current.txt +6 −6 Original line number Diff line number Diff line Loading @@ -7400,6 +7400,7 @@ package android.content { field public static final java.lang.String ACTION_MY_PACKAGE_REPLACED = "android.intent.action.MY_PACKAGE_REPLACED"; field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL"; field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT"; field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE"; field public static final java.lang.String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED"; field public static final java.lang.String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED"; field public static final java.lang.String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED"; Loading @@ -7414,7 +7415,6 @@ package android.content { field public static final java.lang.String ACTION_PASTE = "android.intent.action.PASTE"; field public static final java.lang.String ACTION_PICK = "android.intent.action.PICK"; field public static final java.lang.String ACTION_PICK_ACTIVITY = "android.intent.action.PICK_ACTIVITY"; field public static final java.lang.String ACTION_PICK_DIRECTORY = "android.intent.action.PICK_DIRECTORY"; field public static final java.lang.String ACTION_POWER_CONNECTED = "android.intent.action.ACTION_POWER_CONNECTED"; field public static final java.lang.String ACTION_POWER_DISCONNECTED = "android.intent.action.ACTION_POWER_DISCONNECTED"; field public static final java.lang.String ACTION_POWER_USAGE_SUMMARY = "android.intent.action.POWER_USAGE_SUMMARY"; Loading Loading @@ -23824,21 +23824,21 @@ package android.provider { public final class DocumentsContract { method public static android.net.Uri buildChildDocumentsUri(java.lang.String, java.lang.String); method public static android.net.Uri buildChildDocumentsViaUri(android.net.Uri, java.lang.String); method public static android.net.Uri buildChildDocumentsUriUsingTree(android.net.Uri, java.lang.String); method public static android.net.Uri buildDocumentUri(java.lang.String, java.lang.String); method public static android.net.Uri buildDocumentViaUri(android.net.Uri, java.lang.String); method public static android.net.Uri buildDocumentUriUsingTree(android.net.Uri, java.lang.String); method public static android.net.Uri buildRecentDocumentsUri(java.lang.String, java.lang.String); method public static android.net.Uri buildRootUri(java.lang.String, java.lang.String); method public static android.net.Uri buildRootsUri(java.lang.String); method public static android.net.Uri buildSearchDocumentsUri(java.lang.String, java.lang.String, java.lang.String); method public static android.net.Uri buildViaUri(java.lang.String, java.lang.String); method public static android.net.Uri buildTreeDocumentUri(java.lang.String, java.lang.String); method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String); method public static boolean deleteDocument(android.content.ContentResolver, android.net.Uri); method public static java.lang.String getDocumentId(android.net.Uri); method public static android.graphics.Bitmap getDocumentThumbnail(android.content.ContentResolver, android.net.Uri, android.graphics.Point, android.os.CancellationSignal); method public static java.lang.String getRootId(android.net.Uri); method public static java.lang.String getSearchDocumentsQuery(android.net.Uri); method public static java.lang.String getViaDocumentId(android.net.Uri); method public static java.lang.String getTreeDocumentId(android.net.Uri); method public static boolean isDocumentUri(android.content.Context, android.net.Uri); method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String); field public static final java.lang.String EXTRA_ERROR = "error"; Loading Loading @@ -23877,7 +23877,7 @@ package android.provider { field public static final java.lang.String COLUMN_TITLE = "title"; field public static final int FLAG_LOCAL_ONLY = 2; // 0x2 field public static final int FLAG_SUPPORTS_CREATE = 1; // 0x1 field public static final int FLAG_SUPPORTS_DIR_SELECTION = 16; // 0x10 field public static final int FLAG_SUPPORTS_IS_CHILD = 16; // 0x10 field public static final int FLAG_SUPPORTS_RECENTS = 4; // 0x4 field public static final int FLAG_SUPPORTS_SEARCH = 8; // 0x8 }
core/java/android/content/Intent.java +13 −10 Original line number Diff line number Diff line Loading @@ -2731,6 +2731,7 @@ public class Intent implements Parcelable, Cloneable { * returned in {@link #getClipData()}. * * @see DocumentsContract * @see #ACTION_OPEN_DOCUMENT_TREE * @see #ACTION_CREATE_DOCUMENT * @see #FLAG_GRANT_PERSISTABLE_URI_PERMISSION */ Loading Loading @@ -2765,28 +2766,30 @@ public class Intent implements Parcelable, Cloneable { * * @see DocumentsContract * @see #ACTION_OPEN_DOCUMENT * @see #ACTION_OPEN_DOCUMENT_TREE * @see #FLAG_GRANT_PERSISTABLE_URI_PERMISSION */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_CREATE_DOCUMENT = "android.intent.action.CREATE_DOCUMENT"; /** * Activity Action: Allow the user to pick a directory. When invoked, the * system will display the various {@link DocumentsProvider} instances * installed on the device, letting the user navigate through them. Apps can * fully manage documents within the returned directory. * Activity Action: Allow the user to pick a directory subtree. When * invoked, the system will display the various {@link DocumentsProvider} * instances installed on the device, letting the user navigate through * them. Apps can fully manage documents within the returned directory. * <p> * To gain access to descendant (child, grandchild, etc) documents, use * {@link DocumentsContract#buildDocumentViaUri(Uri, String)} and * {@link DocumentsContract#buildChildDocumentsViaUri(Uri, String)} using * the returned directory URI. * {@link DocumentsContract#buildDocumentUriUsingTree(Uri, String)} and * {@link DocumentsContract#buildChildDocumentsUriUsingTree(Uri, String)} * with the returned URI. * <p> * Output: The URI representing the selected directory. * Output: The URI representing the selected directory tree. * * @see DocumentsContract */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_PICK_DIRECTORY = "android.intent.action.PICK_DIRECTORY"; public static final String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE"; // --------------------------------------------------------------------- // --------------------------------------------------------------------- Loading Loading @@ -3365,8 +3368,8 @@ public class Intent implements Parcelable, Cloneable { * * @see #ACTION_GET_CONTENT * @see #ACTION_OPEN_DOCUMENT * @see #ACTION_OPEN_DOCUMENT_TREE * @see #ACTION_CREATE_DOCUMENT * @see #ACTION_PICK_DIRECTORY */ public static final String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY"; Loading
core/java/android/provider/DocumentsContract.java +66 −54 Original line number Diff line number Diff line Loading @@ -60,7 +60,8 @@ import java.util.List; * <p> * All client apps must hold a valid URI permission grant to access documents, * typically issued when a user makes a selection through * {@link Intent#ACTION_OPEN_DOCUMENT} or {@link Intent#ACTION_CREATE_DOCUMENT}. * {@link Intent#ACTION_OPEN_DOCUMENT}, {@link Intent#ACTION_CREATE_DOCUMENT}, * or {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. * * @see DocumentsProvider */ Loading @@ -73,8 +74,8 @@ public final class DocumentsContract { // content://com.example/root/sdcard/search/?query=pony // content://com.example/document/12/ // content://com.example/document/12/children/ // content://com.example/via/12/document/24/ // content://com.example/via/12/document/24/children/ // content://com.example/tree/12/document/24/ // content://com.example/tree/12/document/24/children/ private DocumentsContract() { } Loading Loading @@ -441,12 +442,13 @@ public final class DocumentsContract { public static final int FLAG_SUPPORTS_SEARCH = 1 << 3; /** * Flag indicating that this root supports directory selection. * Flag indicating that this root supports testing parent child * relationships. * * @see #COLUMN_FLAGS * @see DocumentsProvider#isChildDocument(String, String) */ public static final int FLAG_SUPPORTS_DIR_SELECTION = 1 << 4; public static final int FLAG_SUPPORTS_IS_CHILD = 1 << 4; /** * Flag indicating that this root is currently empty. This may be used Loading Loading @@ -518,7 +520,7 @@ public final class DocumentsContract { private static final String PATH_DOCUMENT = "document"; private static final String PATH_CHILDREN = "children"; private static final String PATH_SEARCH = "search"; private static final String PATH_VIA = "via"; private static final String PATH_TREE = "tree"; private static final String PARAM_QUERY = "query"; private static final String PARAM_MANAGE = "manage"; Loading Loading @@ -564,17 +566,17 @@ public final class DocumentsContract { * Build URI representing access to descendant documents of the given * {@link Document#COLUMN_DOCUMENT_ID}. * * @see #getViaDocumentId(Uri) * @see #getTreeDocumentId(Uri) */ public static Uri buildViaUri(String authority, String documentId) { public static Uri buildTreeDocumentUri(String authority, String documentId) { return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority) .appendPath(PATH_VIA).appendPath(documentId).build(); .appendPath(PATH_TREE).appendPath(documentId).build(); } /** * Build URI representing the given {@link Document#COLUMN_DOCUMENT_ID} in a * document provider. When queried, a provider will return a single row with * columns defined by {@link Document}. * Build URI representing the target {@link Document#COLUMN_DOCUMENT_ID} in * a document provider. When queried, a provider will return a single row * with columns defined by {@link Document}. * * @see DocumentsProvider#queryDocument(String, String[]) * @see #getDocumentId(Uri) Loading @@ -585,42 +587,46 @@ public final class DocumentsContract { } /** * Build URI representing the given {@link Document#COLUMN_DOCUMENT_ID} in a * document provider. Instead of directly accessing the target document, * gain access via another document. The target document must be a * descendant (child, grandchild, etc) of the via document. * Build URI representing the target {@link Document#COLUMN_DOCUMENT_ID} in * a document provider. When queried, a provider will return a single row * with columns defined by {@link Document}. * <p> * However, instead of directly accessing the target document, the returned * URI will leverage access granted through a subtree URI, typically * returned by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. The target document * must be a descendant (child, grandchild, etc) of the subtree. * <p> * This is typically used to access documents under a user-selected * directory, since it doesn't require the user to separately confirm each * new document access. * directory tree, since it doesn't require the user to separately confirm * each new document access. * * @param viaUri a related document (directory) that the caller is * leveraging to gain access to the target document. The target * document must be a descendant of this directory. * @param treeUri the subtree to leverage to gain access to the target * document. The target directory must be a descendant of this * subtree. * @param documentId the target document, which the caller may not have * direct access to. * @see Intent#ACTION_PICK_DIRECTORY * @see Intent#ACTION_OPEN_DOCUMENT_TREE * @see DocumentsProvider#isChildDocument(String, String) * @see #buildDocumentUri(String, String) */ public static Uri buildDocumentViaUri(Uri viaUri, String documentId) { public static Uri buildDocumentUriUsingTree(Uri treeUri, String documentId) { return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) .authority(viaUri.getAuthority()).appendPath(PATH_VIA) .appendPath(getViaDocumentId(viaUri)).appendPath(PATH_DOCUMENT) .authority(treeUri.getAuthority()).appendPath(PATH_TREE) .appendPath(getTreeDocumentId(treeUri)).appendPath(PATH_DOCUMENT) .appendPath(documentId).build(); } /** {@hide} */ public static Uri buildDocumentMaybeViaUri(Uri baseUri, String documentId) { if (isViaUri(baseUri)) { return buildDocumentViaUri(baseUri, documentId); public static Uri buildDocumentUriMaybeUsingTree(Uri baseUri, String documentId) { if (isTreeUri(baseUri)) { return buildDocumentUriUsingTree(baseUri, documentId); } else { return buildDocumentUri(baseUri.getAuthority(), documentId); } } /** * Build URI representing the children of the given directory in a document * Build URI representing the children of the target directory in a document * provider. When queried, a provider will return zero or more rows with * columns defined by {@link Document}. * Loading @@ -637,28 +643,33 @@ public final class DocumentsContract { } /** * Build URI representing the children of the given directory in a document * provider. Instead of directly accessing the target document, gain access * via another document. The target document must be a descendant (child, * grandchild, etc) of the via document. * Build URI representing the children of the target directory in a document * provider. When queried, a provider will return zero or more rows with * columns defined by {@link Document}. * <p> * However, instead of directly accessing the target directory, the returned * URI will leverage access granted through a subtree URI, typically * returned by {@link Intent#ACTION_OPEN_DOCUMENT_TREE}. The target * directory must be a descendant (child, grandchild, etc) of the subtree. * <p> * This is typically used to access documents under a user-selected * directory, since it doesn't require the user to separately confirm each * new document access. * * @param viaUri a related document (directory) that the caller is * leveraging to gain access to the target document. The target * document must be a descendant of this directory. * @param parentDocumentId the target document, which the caller may not * have direct access to. * @see Intent#ACTION_PICK_DIRECTORY * directory tree, since it doesn't require the user to separately confirm * each new document access. * * @param treeUri the subtree to leverage to gain access to the target * document. The target directory must be a descendant of this * subtree. * @param parentDocumentId the document to return children for, which the * caller may not have direct access to, and which must be a * directory with MIME type of {@link Document#MIME_TYPE_DIR}. * @see Intent#ACTION_OPEN_DOCUMENT_TREE * @see DocumentsProvider#isChildDocument(String, String) * @see #buildChildDocumentsUri(String, String) */ public static Uri buildChildDocumentsViaUri(Uri viaUri, String parentDocumentId) { public static Uri buildChildDocumentsUriUsingTree(Uri treeUri, String parentDocumentId) { return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) .authority(viaUri.getAuthority()).appendPath(PATH_VIA) .appendPath(getViaDocumentId(viaUri)).appendPath(PATH_DOCUMENT) .authority(treeUri.getAuthority()).appendPath(PATH_TREE) .appendPath(getTreeDocumentId(treeUri)).appendPath(PATH_DOCUMENT) .appendPath(parentDocumentId).appendPath(PATH_CHILDREN).build(); } Loading @@ -683,21 +694,24 @@ public final class DocumentsContract { * {@link DocumentsProvider}. * * @see #buildDocumentUri(String, String) * @see #buildDocumentViaUri(Uri, String) * @see #buildDocumentUriUsingTree(Uri, String) */ public static boolean isDocumentUri(Context context, Uri uri) { final List<String> paths = uri.getPathSegments(); if (paths.size() >= 2 && (PATH_DOCUMENT.equals(paths.get(0)) || PATH_VIA.equals(paths.get(0)))) { if (paths.size() == 2 && PATH_DOCUMENT.equals(paths.get(0))) { return isDocumentsProvider(context, uri.getAuthority()); } if (paths.size() == 4 && PATH_TREE.equals(paths.get(0)) && PATH_DOCUMENT.equals(paths.get(2))) { return isDocumentsProvider(context, uri.getAuthority()); } return false; } /** {@hide} */ public static boolean isViaUri(Uri uri) { public static boolean isTreeUri(Uri uri) { final List<String> paths = uri.getPathSegments(); return (paths.size() >= 2 && PATH_VIA.equals(paths.get(0))); return (paths.size() >= 2 && PATH_TREE.equals(paths.get(0))); } private static boolean isDocumentsProvider(Context context, String authority) { Loading Loading @@ -733,7 +747,7 @@ public final class DocumentsContract { if (paths.size() >= 2 && PATH_DOCUMENT.equals(paths.get(0))) { return paths.get(1); } if (paths.size() >= 4 && PATH_VIA.equals(paths.get(0)) if (paths.size() >= 4 && PATH_TREE.equals(paths.get(0)) && PATH_DOCUMENT.equals(paths.get(2))) { return paths.get(3); } Loading @@ -742,12 +756,10 @@ public final class DocumentsContract { /** * Extract the via {@link Document#COLUMN_DOCUMENT_ID} from the given URI. * * @see #isViaUri(Uri) */ public static String getViaDocumentId(Uri documentUri) { public static String getTreeDocumentId(Uri documentUri) { final List<String> paths = documentUri.getPathSegments(); if (paths.size() >= 2 && PATH_VIA.equals(paths.get(0))) { if (paths.size() >= 2 && PATH_TREE.equals(paths.get(0))) { return paths.get(1); } throw new IllegalArgumentException("Invalid URI: " + documentUri); Loading
core/java/android/provider/DocumentsProvider.java +43 −38 File changed.Preview size limit exceeded, changes collapsed. Show changes
packages/DocumentsUI/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ <data android:mimeType="*/*" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.PICK_DIRECTORY" /> <action android:name="android.intent.action.OPEN_DOCUMENT_TREE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> Loading