Home | History | Annotate | Download | only in content
      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 
     17 package androidx.core.content;
     18 
     19 import static android.os.Build.VERSION.SDK_INT;
     20 
     21 import android.content.ContentResolver;
     22 import android.database.Cursor;
     23 import android.net.Uri;
     24 
     25 import androidx.core.os.CancellationSignal;
     26 import androidx.core.os.OperationCanceledException;
     27 
     28 /**
     29  * Helper for accessing features in {@link android.content.ContentResolver} in a backwards
     30  * compatible fashion.
     31  */
     32 public final class ContentResolverCompat {
     33     private ContentResolverCompat() {
     34         /* Hide constructor */
     35     }
     36 
     37     /**
     38      * Query the given URI, returning a {@link Cursor} over the result set
     39      * with optional support for cancellation.
     40      * <p>
     41      * For best performance, the caller should follow these guidelines:
     42      * <ul>
     43      * <li>Provide an explicit projection, to prevent
     44      * reading data from storage that aren't going to be used.</li>
     45      * <li>Use question mark parameter markers such as 'phone=?' instead of
     46      * explicit values in the {@code selection} parameter, so that queries
     47      * that differ only by those values will be recognized as the same
     48      * for caching purposes.</li>
     49      * </ul>
     50      * </p>
     51      *
     52      * @param uri The URI, using the content:// scheme, for the content to
     53      *         retrieve.
     54      * @param projection A list of which columns to return. Passing null will
     55      *         return all columns, which is inefficient.
     56      * @param selection A filter declaring which rows to return, formatted as an
     57      *         SQL WHERE clause (excluding the WHERE itself). Passing null will
     58      *         return all rows for the given URI.
     59      * @param selectionArgs You may include ?s in selection, which will be
     60      *         replaced by the values from selectionArgs, in the order that they
     61      *         appear in the selection. The values will be bound as Strings.
     62      * @param sortOrder How to order the rows, formatted as an SQL ORDER BY
     63      *         clause (excluding the ORDER BY itself). Passing null will use the
     64      *         default sort order, which may be unordered.
     65      * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
     66      * If the operation is canceled, then {@link OperationCanceledException} will be thrown
     67      * when the query is executed.
     68      * @return A Cursor object, which is positioned before the first entry, or null
     69      * @see Cursor
     70      */
     71     public static Cursor query(ContentResolver resolver,
     72             Uri uri, String[] projection, String selection, String[] selectionArgs,
     73             String sortOrder, CancellationSignal cancellationSignal) {
     74         if (SDK_INT >= 16) {
     75             try {
     76                 final android.os.CancellationSignal cancellationSignalObj =
     77                         (android.os.CancellationSignal)
     78                                 (cancellationSignal != null
     79                                         ? cancellationSignal.getCancellationSignalObject()
     80                                         : null);
     81                 return resolver.query(uri, projection, selection, selectionArgs, sortOrder,
     82                         cancellationSignalObj);
     83             } catch (Exception e) {
     84                 if (e instanceof android.os.OperationCanceledException) {
     85                     // query() can throw a framework OperationCanceledException if it has been
     86                     // canceled. We catch that and throw the support version instead.
     87                     throw new OperationCanceledException();
     88                 } else {
     89                     // If it's not a framework OperationCanceledException, re-throw the exception
     90                     throw e;
     91                 }
     92             }
     93         } else {
     94             // Note that the cancellation signal cannot cancel the query in progress
     95             // prior to Jellybean so we cancel it preemptively here if needed.
     96             if (cancellationSignal != null) {
     97                 cancellationSignal.throwIfCanceled();
     98             }
     99             return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
    100         }
    101     }
    102 }
    103