1220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown/* 2220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * Copyright (C) 2013 The Android Open Source Project 3220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * 4220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * you may not use this file except in compliance with the License. 6220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * You may obtain a copy of the License at 7220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * 8220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * 10220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * Unless required by applicable law or agreed to in writing, software 11220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * See the License for the specific language governing permissions and 14220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * limitations under the License. 15220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown */ 16220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown 17220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brownpackage android.support.v4.content; 18220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown 19b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikasimport static android.os.Build.VERSION.SDK_INT; 20b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas 21220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brownimport android.content.ContentResolver; 22220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brownimport android.database.Cursor; 23220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brownimport android.net.Uri; 24220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brownimport android.support.v4.os.CancellationSignal; 25220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brownimport android.support.v4.os.OperationCanceledException; 26220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown 27220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown/** 28b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas * Helper for accessing features in {@link android.content.ContentResolver} in a backwards 29b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas * compatible fashion. 30220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown */ 31c5847d13e40f5d52459f5c0dab32dc08f1a9a683Chris Banespublic final class ContentResolverCompat { 32220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown private ContentResolverCompat() { 33220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown /* Hide constructor */ 34220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown } 35220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown 36220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown /** 37220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * Query the given URI, returning a {@link Cursor} over the result set 38220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * with optional support for cancellation. 39220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * <p> 40220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * For best performance, the caller should follow these guidelines: 41220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * <ul> 42220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * <li>Provide an explicit projection, to prevent 43220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * reading data from storage that aren't going to be used.</li> 44220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * <li>Use question mark parameter markers such as 'phone=?' instead of 45220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * explicit values in the {@code selection} parameter, so that queries 46220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * that differ only by those values will be recognized as the same 47220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * for caching purposes.</li> 48220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * </ul> 49220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * </p> 50220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * 51220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * @param uri The URI, using the content:// scheme, for the content to 52220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * retrieve. 53220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * @param projection A list of which columns to return. Passing null will 54220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * return all columns, which is inefficient. 55220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * @param selection A filter declaring which rows to return, formatted as an 56220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * SQL WHERE clause (excluding the WHERE itself). Passing null will 57220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * return all rows for the given URI. 58220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * @param selectionArgs You may include ?s in selection, which will be 59220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * replaced by the values from selectionArgs, in the order that they 60220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * appear in the selection. The values will be bound as Strings. 61220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 62220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * clause (excluding the ORDER BY itself). Passing null will use the 63220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * default sort order, which may be unordered. 64220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * @param cancellationSignal A signal to cancel the operation in progress, or null if none. 65220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * If the operation is canceled, then {@link OperationCanceledException} will be thrown 66220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * when the query is executed. 67220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * @return A Cursor object, which is positioned before the first entry, or null 68220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown * @see Cursor 69220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown */ 70220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown public static Cursor query(ContentResolver resolver, 71220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown Uri uri, String[] projection, String selection, String[] selectionArgs, 72220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown String sortOrder, CancellationSignal cancellationSignal) { 73b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas if (SDK_INT >= 16) { 74b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas try { 75b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas final android.os.CancellationSignal cancellationSignalObj = 76b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas (android.os.CancellationSignal) 77b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas (cancellationSignal != null 78b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas ? cancellationSignal.getCancellationSignalObject() 79b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas : null); 80b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas return resolver.query(uri, projection, selection, selectionArgs, sortOrder, 81b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas cancellationSignalObj); 82b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas } catch (Exception e) { 83b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas if (e instanceof android.os.OperationCanceledException) { 84b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas // query() can throw a framework OperationCanceledException if it has been 85b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas // canceled. We catch that and throw the support version instead. 86b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas throw new OperationCanceledException(); 87b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas } else { 88b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas // If it's not a framework OperationCanceledException, re-throw the exception 89b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas throw e; 90b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas } 91b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas } 92b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas } else { 93b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas // Note that the cancellation signal cannot cancel the query in progress 94b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas // prior to Jellybean so we cancel it preemptively here if needed. 95b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas if (cancellationSignal != null) { 96b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas cancellationSignal.throwIfCanceled(); 97b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas } 98b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas return resolver.query(uri, projection, selection, selectionArgs, sortOrder); 99b9bc12cd1b9694ce7ef467f5b6156b7d8dc39f57Aurimas Liutikas } 100220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown } 101220dc21ab5a2a5b3f8b6532105121750770a69f4Jeff Brown} 102