15fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey/* 25fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Copyright (C) 2014 The Android Open Source Project 35fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 45fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 55fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * you may not use this file except in compliance with the License. 65fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * You may obtain a copy of the License at 75fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 85fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 95fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 105fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 115fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 125fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * See the License for the specific language governing permissions and 145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * limitations under the License. 155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeypackage android.support.v4.provider; 185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.content.ContentResolver; 205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.content.Context; 215fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.content.Intent; 225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.net.Uri; 235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport android.os.Build; 245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 255fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeyimport java.io.File; 265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey/** 285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Representation of a document backed by either a 295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link android.provider.DocumentsProvider} or a raw file on disk. This is a 305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * utility class designed to emulate the traditional {@link File} interface. It 315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * offers a simplified view of a tree of documents, but it has substantial 325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * overhead. For optimal performance and a richer feature set, use the 335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link android.provider.DocumentsContract} methods and constants directly. 345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <p> 355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * There are several differences between documents and traditional files: 365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <ul> 375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <li>Documents express their display name and MIME type as separate fields, 385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * instead of relying on file extensions. Some documents providers may still 395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * choose to append extensions to their display names, but that's an 405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * implementation detail. 415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <li>A single document may appear as the child of multiple directories, so it 425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * doesn't inherently know who its parent is. That is, documents don't have a 435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * strong notion of path. You can easily traverse a tree of documents from 445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * parent to child, but not from child to parent. 455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <li>Each document has a unique identifier within that provider. This 465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * identifier is an <em>opaque</em> implementation detail of the provider, and 475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * as such it must not be parsed. 485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * </ul> 495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <p> 505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Before using this class, first consider if you really need access to an 515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * entire subtree of documents. The principle of least privilege dictates that 525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * you should only ask for access to documents you really need. If you only need 535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * the user to pick a single file, use {@link Intent#ACTION_OPEN_DOCUMENT} or 545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link Intent#ACTION_GET_CONTENT}. If you want to let the user pick multiple 555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * files, add {@link Intent#EXTRA_ALLOW_MULTIPLE}. If you only need the user to 565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * save a single file, use {@link Intent#ACTION_CREATE_DOCUMENT}. If you use 575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * these APIs, you can pass the resulting {@link Intent#getData()} into 585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link #fromSingleUri(Context, Uri)} to work with that document. 595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <p> 605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * If you really do need full access to an entire subtree of documents, start by 615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * launching {@link Intent#ACTION_OPEN_DOCUMENT_TREE} to let the user pick a 625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * directory. Then pass the resulting {@link Intent#getData()} into 635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link #fromTreeUri(Context, Uri)} to start working with the user selected 645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * tree. 655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <p> 665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * As you navigate the tree of DocumentFile instances, you can always use 675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link #getUri()} to obtain the Uri representing the underlying document for 685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * that object, for use with {@link ContentResolver#openInputStream(Uri)}, etc. 695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <p> 705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * To simplify your code on devices running 715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link android.os.Build.VERSION_CODES#KITKAT} or earlier, you can use 725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link #fromFile(File)} which emulates the behavior of a 735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link android.provider.DocumentsProvider}. 745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 755fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsProvider 765fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract 775fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 785fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkeypublic abstract class DocumentFile { 795fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey static final String TAG = "DocumentFile"; 805fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 815fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey private final DocumentFile mParent; 825fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 835fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey DocumentFile(DocumentFile parent) { 845fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey mParent = parent; 855fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 865fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 875fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 885fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Create a {@link DocumentFile} representing the filesystem tree rooted at 898b977168147ee1135c39de1ac3c1b45aa83376c8Jeff Sharkey * the given {@link File}. This doesn't give you any additional access to the 905fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * underlying files beyond what your app already has. 915fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <p> 925fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link #getUri()} will return {@code file://} Uris for files explored 935fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * through this tree. 945fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 955fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public static DocumentFile fromFile(File file) { 965fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return new RawDocumentFile(null, file); 975fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 985fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 995fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 1005fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Create a {@link DocumentFile} representing the single document at the 1015fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * given {@link Uri}. This is only useful on devices running 1025fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link android.os.Build.VERSION_CODES#KITKAT} or later, and will return 1035fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@code null} when called on earlier platform versions. 1045fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 1055fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @param singleUri the {@link Intent#getData()} from a successful 1065fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link Intent#ACTION_OPEN_DOCUMENT} or 1075fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link Intent#ACTION_CREATE_DOCUMENT} request. 1085fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 1095fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public static DocumentFile fromSingleUri(Context context, Uri singleUri) { 1105fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final int version = Build.VERSION.SDK_INT; 1115fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (version >= 19) { 1125fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return new SingleDocumentFile(null, context, singleUri); 1135fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } else { 1145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return null; 1155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 1195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Create a {@link DocumentFile} representing the document tree rooted at 1205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * the given {@link Uri}. This is only useful on devices running 12195a62c18174e92eb2bf90b808cef5fd6f36ad944Dianne Hackborn * {@link android.os.Build.VERSION_CODES#LOLLIPOP} or later, and will return 1225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@code null} when called on earlier platform versions. 1235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 1245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @param treeUri the {@link Intent#getData()} from a successful 1255fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link Intent#ACTION_OPEN_DOCUMENT_TREE} request. 1265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 1275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public static DocumentFile fromTreeUri(Context context, Uri treeUri) { 1285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final int version = Build.VERSION.SDK_INT; 1295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (version >= 21) { 1305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return new TreeDocumentFile(null, context, 1315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey DocumentsContractApi21.prepareTreeUri(treeUri)); 1325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } else { 1335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return null; 1345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 1385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Test if given Uri is backed by a 1395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link android.provider.DocumentsProvider}. 1405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 1415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public static boolean isDocumentUri(Context context, Uri uri) { 1425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey final int version = Build.VERSION.SDK_INT; 1435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (version >= 19) { 1445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return DocumentsContractApi19.isDocumentUri(context, uri); 1455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } else { 1465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return false; 1475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 1495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 1515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Create a new document as a direct child of this directory. 1525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 1535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @param mimeType MIME type of new document, such as {@code image/png} or 1545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@code audio/flac} 1555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @param displayName name of new document, without any file extension 1565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * appended; the underlying provider may choose to append the 1575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * extension 1585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @return file representing newly created document, or null if failed 1595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @throws UnsupportedOperationException when working with a single document 1605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * created from {@link #fromSingleUri(Context, Uri)}. 1615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract#createDocument(ContentResolver, 1625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Uri, String, String) 1635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 1645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract DocumentFile createFile(String mimeType, String displayName); 1655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 1675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Create a new directory as a direct child of this directory. 1685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 1695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @param displayName name of new directory 1705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @return file representing newly created directory, or null if failed 1715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @throws UnsupportedOperationException when working with a single document 1725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * created from {@link #fromSingleUri(Context, Uri)}. 1735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract#createDocument(ContentResolver, 1745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Uri, String, String) 1755fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 1765fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract DocumentFile createDirectory(String displayName); 1775fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1785fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 1795fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Return a Uri for the underlying document represented by this file. This 1805fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * can be used with other platform APIs to manipulate or share the 1815fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * underlying content. You can use {@link #isDocumentUri(Context, Uri)} to 1825fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * test if the returned Uri is backed by a 1835fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link android.provider.DocumentsProvider}. 1845fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 1855fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see Intent#setData(Uri) 1865fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see Intent#setClipData(android.content.ClipData) 1875fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see ContentResolver#openInputStream(Uri) 1885fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see ContentResolver#openOutputStream(Uri) 1895fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see ContentResolver#openFileDescriptor(Uri, String) 1905fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 1915fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract Uri getUri(); 1925fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 1935fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 1945fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Return the display name of this document. 1955fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 1965fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract.Document#COLUMN_DISPLAY_NAME 1975fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 1985fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract String getName(); 1995fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2005fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 2015fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Return the MIME type of this document. 2025fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 2035fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract.Document#COLUMN_MIME_TYPE 2045fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 2055fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract String getType(); 2065fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2075fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 2085fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Return the parent file of this document. Only defined inside of the 2095fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * user-selected tree; you can never escape above the top of the tree. 2105fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <p> 2115fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * The underlying {@link android.provider.DocumentsProvider} only defines a 2125fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * forward mapping from parent to child, so the reverse mapping of child to 2135fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * parent offered here is purely a convenience method, and it may be 2145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * incorrect if the underlying tree structure changes. 2155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 2165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public DocumentFile getParentFile() { 2175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return mParent; 2185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 2195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 2215fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Indicates if this file represents a <em>directory</em>. 2225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 2235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @return {@code true} if this file is a directory, {@code false} 2245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * otherwise. 2255fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract.Document#MIME_TYPE_DIR 2265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 2275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract boolean isDirectory(); 2285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 2305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Indicates if this file represents a <em>file</em>. 2315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 2325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @return {@code true} if this file is a file, {@code false} otherwise. 2335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract.Document#COLUMN_MIME_TYPE 2345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 2355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract boolean isFile(); 2365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 2385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Returns the time when this file was last modified, measured in 2395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * milliseconds since January 1st, 1970, midnight. Returns 0 if the file 2405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * does not exist, or if the modified time is unknown. 2415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 2425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @return the time when this file was last modified. 2435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract.Document#COLUMN_LAST_MODIFIED 2445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 2455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract long lastModified(); 2465fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2475fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 2485fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Returns the length of this file in bytes. Returns 0 if the file does not 2495fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * exist, or if the length is unknown. The result for a directory is not 2505fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * defined. 2515fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 2525fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @return the number of bytes in this file. 2535fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract.Document#COLUMN_SIZE 2545fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 2555fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract long length(); 2565fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2575fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 2585fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Indicates whether the current context is allowed to read from this file. 2595fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 2605fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @return {@code true} if this file can be read, {@code false} otherwise. 2615fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 2625fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract boolean canRead(); 2635fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2645fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 2655fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Indicates whether the current context is allowed to write to this file. 2665fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 2675fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @return {@code true} if this file can be written, {@code false} 2685fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * otherwise. 2695fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract.Document#COLUMN_FLAGS 2705fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract.Document#FLAG_SUPPORTS_DELETE 2715fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract.Document#FLAG_SUPPORTS_WRITE 2725fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract.Document#FLAG_DIR_SUPPORTS_CREATE 2735fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 2745fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract boolean canWrite(); 2755fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2765fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 2775fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Deletes this file. 2785fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <p> 2795fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Note that this method does <i>not</i> throw {@code IOException} on 2805fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * failure. Callers must check the return value. 2815fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 2825fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @return {@code true} if this file was deleted, {@code false} otherwise. 2835fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract#deleteDocument(ContentResolver, 2845fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Uri) 2855fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 2865fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract boolean delete(); 2875fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2885fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 2895fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Returns a boolean indicating whether this file can be found. 2905fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 2915fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @return {@code true} if this file exists, {@code false} otherwise. 2925fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 2935fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract boolean exists(); 2945fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 2955fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 2965fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Returns an array of files contained in the directory represented by this 2975fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * file. 2985fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 2995fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @return an array of files or {@code null}. 3005fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @throws UnsupportedOperationException when working with a single document 3015fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * created from {@link #fromSingleUri(Context, Uri)}. 3025fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract#buildChildDocumentsUriUsingTree(Uri, 3035fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * String) 3045fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 3055fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract DocumentFile[] listFiles(); 3065fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3075fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 3085fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Search through {@link #listFiles()} for the first document matching the 3095fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * given display name. Returns {@code null} when no matching document is 3105fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * found. 3115fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 3125fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @throws UnsupportedOperationException when working with a single document 3135fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * created from {@link #fromSingleUri(Context, Uri)}. 3145fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 3155fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public DocumentFile findFile(String displayName) { 3165fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey for (DocumentFile doc : listFiles()) { 3175fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey if (displayName.equals(doc.getName())) { 3185fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return doc; 3195fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3205fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3215fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey return null; 3225fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey } 3235fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey 3245fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey /** 3255fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Renames this file to {@code displayName}. 3265fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <p> 3275fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Note that this method does <i>not</i> throw {@code IOException} on 3285fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * failure. Callers must check the return value. 3295fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <p> 3305fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Some providers may need to create a new document to reflect the rename, 3315fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * potentially with a different MIME type, so {@link #getUri()} and 3325fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link #getType()} may change to reflect the rename. 3335fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * <p> 3345fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * When renaming a directory, children previously enumerated through 3355fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * {@link #listFiles()} may no longer be valid. 3365fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * 3375fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @param displayName the new display name. 3385fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @return true on success. 3395fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @throws UnsupportedOperationException when working with a single document 3405fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * created from {@link #fromSingleUri(Context, Uri)}. 3415fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * @see android.provider.DocumentsContract#renameDocument(ContentResolver, 3425fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey * Uri, String) 3435fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey */ 3445fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey public abstract boolean renameTo(String displayName); 3455fdfbc2e02f46509474057e4366585f6a6062cb9Jeff Sharkey} 346