DocumentsContract.java revision 9e0036ed7d3260d79cc5f9ffd8e3bbe760699924
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.provider; 18 19import android.content.ContentResolver; 20import android.content.ContentValues; 21import android.content.Intent; 22import android.content.res.AssetFileDescriptor; 23import android.graphics.Bitmap; 24import android.graphics.BitmapFactory; 25import android.graphics.Point; 26import android.net.Uri; 27import android.os.Bundle; 28import android.util.Log; 29 30import libcore.io.IoUtils; 31 32import java.io.IOException; 33import java.io.InputStream; 34 35/** 36 * The contract between a storage backend and the platform. Contains definitions 37 * for the supported URIs and columns. 38 */ 39public final class DocumentsContract { 40 private static final String TAG = "Documents"; 41 42 // content://com.example/docs/0/ 43 // content://com.example/docs/0/contents/ 44 // content://com.example/search/?query=pony 45 46 /** 47 * MIME type of a document which is a directory that may contain additional 48 * documents. 49 * 50 * @see #buildContentsUri(Uri) 51 */ 52 public static final String MIME_TYPE_DIRECTORY = "vnd.android.cursor.dir/doc"; 53 54 /** {@hide} */ 55 public static final String META_DATA_DOCUMENT_PROVIDER = "android.content.DOCUMENT_PROVIDER"; 56 57 /** 58 * {@link DocumentColumns#GUID} value representing the root directory of a 59 * storage backend. 60 */ 61 public static final String ROOT_GUID = "0"; 62 63 /** 64 * Flag indicating that a document is a directory that supports creation of 65 * new files within it. 66 * 67 * @see DocumentColumns#FLAGS 68 * @see #buildContentsUri(Uri) 69 */ 70 public static final int FLAG_SUPPORTS_CREATE = 1; 71 72 /** 73 * Flag indicating that a document is renamable. 74 * 75 * @see DocumentColumns#FLAGS 76 * @see #renameDocument(ContentResolver, Uri, String) 77 */ 78 public static final int FLAG_SUPPORTS_RENAME = 1 << 1; 79 80 /** 81 * Flag indicating that a document can be represented as a thumbnail. 82 * 83 * @see DocumentColumns#FLAGS 84 * @see #getThumbnail(ContentResolver, Uri, Point) 85 */ 86 public static final int FLAG_SUPPORTS_THUMBNAIL = 1 << 2; 87 88 /** 89 * Optimal dimensions for a document thumbnail request, stored as a 90 * {@link Point} object. This is only a hint, and the returned thumbnail may 91 * have different dimensions. 92 */ 93 public static final String EXTRA_THUMBNAIL_SIZE = "thumbnail_size"; 94 95 private static final String PATH_DOCS = "docs"; 96 private static final String PATH_CONTENTS = "contents"; 97 private static final String PATH_SEARCH = "search"; 98 99 private static final String PARAM_QUERY = "query"; 100 101 /** 102 * Build URI representing the given {@link DocumentColumns#GUID} in a 103 * storage backend. 104 */ 105 public static Uri buildDocumentUri(String authority, String guid) { 106 return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) 107 .authority(authority).appendPath(PATH_DOCS).appendPath(guid).build(); 108 } 109 110 /** 111 * Build URI representing a search for matching documents in a storage 112 * backend. 113 */ 114 public static Uri buildSearchUri(String authority, String query) { 115 return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(authority) 116 .appendPath(PATH_SEARCH).appendQueryParameter(PARAM_QUERY, query).build(); 117 } 118 119 /** 120 * Build URI representing the contents of the given directory in a storage 121 * backend. The given document must be {@link #MIME_TYPE_DIRECTORY}. 122 */ 123 public static Uri buildContentsUri(Uri documentUri) { 124 return documentUri.buildUpon().appendPath(PATH_CONTENTS).build(); 125 } 126 127 /** 128 * These are standard columns for document URIs. Storage backend providers 129 * <em>must</em> support at least these columns when queried. 130 * 131 * @see Intent#ACTION_OPEN_DOCUMENT 132 * @see Intent#ACTION_CREATE_DOCUMENT 133 */ 134 public interface DocumentColumns extends OpenableColumns { 135 /** 136 * The globally unique ID for a document within a storage backend. 137 * Values <em>must</em> never change once returned. 138 * <p> 139 * Type: STRING 140 * 141 * @see DocumentsContract#ROOT_GUID 142 */ 143 public static final String GUID = "guid"; 144 145 /** 146 * MIME type of a document, matching the value returned by 147 * {@link ContentResolver#getType(android.net.Uri)}. 148 * <p> 149 * Type: STRING 150 * 151 * @see DocumentsContract#MIME_TYPE_DIRECTORY 152 */ 153 public static final String MIME_TYPE = "mime_type"; 154 155 /** 156 * Timestamp when a document was last modified, in milliseconds since 157 * January 1, 1970 00:00:00.0 UTC. 158 * <p> 159 * Type: INTEGER (long) 160 * 161 * @see System#currentTimeMillis() 162 */ 163 public static final String LAST_MODIFIED = "last_modified"; 164 165 /** 166 * Flags that apply to a specific document. 167 * <p> 168 * Type: INTEGER (int) 169 */ 170 public static final String FLAGS = "flags"; 171 } 172 173 /** 174 * Return thumbnail representing the document at the given URI. Callers are 175 * responsible for their own caching. Given document must have 176 * {@link #FLAG_SUPPORTS_THUMBNAIL} set. 177 * 178 * @return decoded thumbnail, or {@code null} if problem was encountered. 179 */ 180 public static Bitmap getThumbnail(ContentResolver resolver, Uri documentUri, Point size) { 181 final Bundle opts = new Bundle(); 182 opts.putParcelable(EXTRA_THUMBNAIL_SIZE, size); 183 184 InputStream is = null; 185 try { 186 is = new AssetFileDescriptor.AutoCloseInputStream( 187 resolver.openTypedAssetFileDescriptor(documentUri, "image/*", opts)); 188 return BitmapFactory.decodeStream(is); 189 } catch (IOException e) { 190 Log.w(TAG, "Failed to load thumbnail for " + documentUri + ": " + e); 191 return null; 192 } finally { 193 IoUtils.closeQuietly(is); 194 } 195 } 196 197 /** 198 * Rename the document at the given URI. Given document must have 199 * {@link #FLAG_SUPPORTS_RENAME} set. 200 * 201 * @return if rename was successful. 202 */ 203 public static boolean renameDocument( 204 ContentResolver resolver, Uri documentUri, String displayName) { 205 final ContentValues values = new ContentValues(); 206 values.put(DocumentColumns.DISPLAY_NAME, displayName); 207 return (resolver.update(documentUri, values, null, null) == 1); 208 } 209} 210