| /* |
| * Copyright (C) 2013 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.support.v4.content; |
| |
| import android.content.ContentResolver; |
| import android.database.Cursor; |
| import android.net.Uri; |
| import android.os.Build; |
| import android.support.v4.os.CancellationSignal; |
| import android.support.v4.os.OperationCanceledException; |
| |
| /** |
| * Helper for accessing features in {@link android.content.ContentResolver} |
| * introduced after API level 4 in a backwards compatible fashion. |
| */ |
| public class ContentResolverCompat { |
| interface ContentResolverCompatImpl { |
| Cursor query(ContentResolver resolver, |
| Uri uri, String[] projection, String selection, String[] selectionArgs, |
| String sortOrder, CancellationSignal cancellationSignal); |
| } |
| |
| static class ContentResolverCompatImplBase implements ContentResolverCompatImpl { |
| @Override |
| public Cursor query(ContentResolver resolver, Uri uri, String[] projection, |
| String selection, String[] selectionArgs, String sortOrder, |
| CancellationSignal cancellationSignal) { |
| // Note that the cancellation signal cannot cancel the query in progress |
| // prior to Jellybean so we cancel it preemptively here if needed. |
| if (cancellationSignal != null) { |
| cancellationSignal.throwIfCanceled(); |
| } |
| return resolver.query(uri, projection, selection, selectionArgs, sortOrder); |
| } |
| } |
| |
| static class ContentResolverCompatImplJB extends ContentResolverCompatImplBase { |
| @Override |
| public Cursor query(ContentResolver resolver, Uri uri, String[] projection, |
| String selection, String[] selectionArgs, String sortOrder, |
| CancellationSignal cancellationSignal) { |
| try { |
| return ContentResolverCompatJellybean.query(resolver, |
| uri, projection, selection, selectionArgs, sortOrder, |
| cancellationSignal != null ? |
| cancellationSignal.getCancellationSignalObject() : null); |
| } catch (Exception e) { |
| if (ContentResolverCompatJellybean.isFrameworkOperationCanceledException(e)) { |
| // query() can throw a framework OperationCanceledException if it has been |
| // canceled. We catch that and throw the support version instead. |
| throw new OperationCanceledException(); |
| } else { |
| // If it's not a framework OperationCanceledException, re-throw the exception |
| throw e; |
| } |
| } |
| } |
| } |
| |
| private static final ContentResolverCompatImpl IMPL; |
| static { |
| final int version = Build.VERSION.SDK_INT; |
| if (version >= 16) { |
| IMPL = new ContentResolverCompatImplJB(); |
| } else { |
| IMPL = new ContentResolverCompatImplBase(); |
| } |
| } |
| |
| private ContentResolverCompat() { |
| /* Hide constructor */ |
| } |
| |
| /** |
| * Query the given URI, returning a {@link Cursor} over the result set |
| * with optional support for cancellation. |
| * <p> |
| * For best performance, the caller should follow these guidelines: |
| * <ul> |
| * <li>Provide an explicit projection, to prevent |
| * reading data from storage that aren't going to be used.</li> |
| * <li>Use question mark parameter markers such as 'phone=?' instead of |
| * explicit values in the {@code selection} parameter, so that queries |
| * that differ only by those values will be recognized as the same |
| * for caching purposes.</li> |
| * </ul> |
| * </p> |
| * |
| * @param uri The URI, using the content:// scheme, for the content to |
| * retrieve. |
| * @param projection A list of which columns to return. Passing null will |
| * return all columns, which is inefficient. |
| * @param selection A filter declaring which rows to return, formatted as an |
| * SQL WHERE clause (excluding the WHERE itself). Passing null will |
| * return all rows for the given URI. |
| * @param selectionArgs You may include ?s in selection, which will be |
| * replaced by the values from selectionArgs, in the order that they |
| * appear in the selection. The values will be bound as Strings. |
| * @param sortOrder How to order the rows, formatted as an SQL ORDER BY |
| * clause (excluding the ORDER BY itself). Passing null will use the |
| * default sort order, which may be unordered. |
| * @param cancellationSignal A signal to cancel the operation in progress, or null if none. |
| * If the operation is canceled, then {@link OperationCanceledException} will be thrown |
| * when the query is executed. |
| * @return A Cursor object, which is positioned before the first entry, or null |
| * @see Cursor |
| */ |
| public static Cursor query(ContentResolver resolver, |
| Uri uri, String[] projection, String selection, String[] selectionArgs, |
| String sortOrder, CancellationSignal cancellationSignal) { |
| return IMPL.query(resolver, uri, projection, selection, selectionArgs, |
| sortOrder, cancellationSignal); |
| } |
| } |