ContentResolver.java revision 5e787c42f2a6b3afc8ec8320a08d51b2d44b8614
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.content; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager.NameNotFoundException; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.Cursor; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.CursorWrapper; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.IContentObserver; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 28231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.IBinder; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ParcelFileDescriptor; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 31231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.os.ServiceManager; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 33d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintanaimport android.accounts.Account; 34231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.Config; 35231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackbornimport android.util.Log; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileNotFoundException; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.OutputStream; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 4403d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintanaimport java.util.ArrayList; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class provides applications access to the content model. 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ContentResolver { 51ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 52ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 53ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 54ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 55ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_ACCOUNT = "account"; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_EXPEDITED = "expedited"; 57ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 58ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 59ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #SYNC_EXTRAS_MANUAL} 60ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_FORCE = "force"; 62ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final String SYNC_EXTRAS_MANUAL = "force"; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_UPLOAD = "upload"; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override"; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions"; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_CONTENT = "content"; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_ANDROID_RESOURCE = "android.resource"; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_FILE = "file"; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of a single item. Applications should use this 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a particular item. For example, hypothetical IMAP email 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox/1</code> for a particular 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * message in the inbox, whose MIME type would be reported as 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_ITEM_BASE_TYPE + "/vnd.company.imap-msg"</code> 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Compare with {@link #CURSOR_DIR_BASE_TYPE}. 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of zero or more items. Applications should use this 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a directory of items. For example, hypothetical IMAP email 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox</code> for all of the 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * messages in its inbox, whose MIME type would be reported as 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_DIR_BASE_TYPE + "/vnd.company.imap-msg"</code> 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Note how the base MIME type varies between this and 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #CURSOR_ITEM_BASE_TYPE} depending on whether there is 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one single item or multiple items in the data set, while the sub-type 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * remains the same because in either case the data structure contained 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the cursor is the same. 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; 102ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 103ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 104ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS = 1; 105ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 106ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_AUTHENTICATION = 2; 107ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 108ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_IO = 3; 109ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 110ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_PARSE = 4; 111ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 112ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_CONFLICT = 5; 113ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 114ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_DELETIONS = 6; 115ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 116ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_TOO_MANY_RETRIES = 7; 117ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 118ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_ERROR_INTERNAL = 8; 119ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 120ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 121ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_SETTINGS = 1<<0; 122ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 123ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_PENDING = 1<<1; 124ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 125ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ACTIVE = 1<<2; 126ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 127ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_STATUS = 1<<3; 128ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** @hide */ 129ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff; 130ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 131231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ContentResolver(Context context) { 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected abstract IContentProvider acquireProvider(Context c, String name); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean releaseProvider(IContentProvider icp); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the MIME type of the given content URL. 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url A Uri identifying content (either a list or specific type), 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the content:// scheme. 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A MIME type for the content, or null if the URL is invalid or the type is unknown 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final String getType(Uri url) 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return provider.getType(url); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (java.lang.Exception e) { 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given URI, returning a {@link Cursor} over the result set. 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI, using the content:// scheme, for the content to 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * retrieve. 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param projection A list of which columns to return. Passing null will 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all columns, which is discouraged to prevent reading data 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * from storage that isn't going to be used. 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null will 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all rows for the given URI. 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in the order that they 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the ORDER BY itself). Passing null will use the 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A Cursor object, which is positioned before the first entry, or null 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Cursor query(Uri uri, String[] projection, 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String selection, String[] selectionArgs, String sortOrder) { 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(qCursor == null) { 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Wrap the cursor object into CursorWrapperInner object 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new CursorWrapperInner(qCursor, provider); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch(RuntimeException e) { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2078943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 2088943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * EntityIterator wrapper that releases the associated ContentProviderClient when the 2098943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * iterator is closed. 2108943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 2118943737692169f564cd34a9c8d471f3a5d438712Fred Quintana private class EntityIteratorWrapper implements EntityIterator { 2126a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana private final EntityIterator mInner; 2136a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana private final ContentProviderClient mClient; 2148943737692169f564cd34a9c8d471f3a5d438712Fred Quintana private volatile boolean mClientReleased; 2156a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 2166a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana EntityIteratorWrapper(EntityIterator inner, ContentProviderClient client) { 2176a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana mInner = inner; 2186a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana mClient = client; 2198943737692169f564cd34a9c8d471f3a5d438712Fred Quintana mClientReleased = false; 2206a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2216a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 2226a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana public boolean hasNext() throws RemoteException { 2238943737692169f564cd34a9c8d471f3a5d438712Fred Quintana if (mClientReleased) { 2248943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalStateException("this iterator is already closed"); 2258943737692169f564cd34a9c8d471f3a5d438712Fred Quintana } 2266a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana return mInner.hasNext(); 2276a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2286a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 2296a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana public Entity next() throws RemoteException { 2308943737692169f564cd34a9c8d471f3a5d438712Fred Quintana if (mClientReleased) { 2318943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalStateException("this iterator is already closed"); 2328943737692169f564cd34a9c8d471f3a5d438712Fred Quintana } 2336a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana return mInner.next(); 2346a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2356a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 2366a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana public void close() { 2376a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana mClient.release(); 2386a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana mInner.close(); 2398943737692169f564cd34a9c8d471f3a5d438712Fred Quintana mClientReleased = true; 2406a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2416a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 2426a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana protected void finalize() throws Throwable { 2438943737692169f564cd34a9c8d471f3a5d438712Fred Quintana if (!mClientReleased) { 2448943737692169f564cd34a9c8d471f3a5d438712Fred Quintana mClient.release(); 2458943737692169f564cd34a9c8d471f3a5d438712Fred Quintana } 2466a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana super.finalize(); 2476a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2486a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2496a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 2508943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 2518943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * Query the given URI, returning an {@link EntityIterator} over the result set. 2528943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * 2538943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param uri The URI, using the content:// scheme, for the content to 2548943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * retrieve. 2558943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param selection A filter declaring which rows to return, formatted as an 2568943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * SQL WHERE clause (excluding the WHERE itself). Passing null will 2578943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * return all rows for the given URI. 2588943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param selectionArgs You may include ?s in selection, which will be 2598943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * replaced by the values from selectionArgs, in the order that they 2608943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * appear in the selection. The values will be bound as Strings. 2618943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 2628943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * clause (excluding the ORDER BY itself). Passing null will use the 2638943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * default sort order, which may be unordered. 2648943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @return An EntityIterator object 2658943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws RemoteException thrown if a RemoteException is encountered while attempting 2668943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * to communicate with a remote provider. 2678943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws IllegalArgumentException thrown if there is no provider that matches the uri 2688943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 2698943737692169f564cd34a9c8d471f3a5d438712Fred Quintana public final EntityIterator queryEntities(Uri uri, 2706a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana String selection, String[] selectionArgs, String sortOrder) throws RemoteException { 2716a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana ContentProviderClient provider = acquireContentProviderClient(uri); 2726a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana if (provider == null) { 2736a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana throw new IllegalArgumentException("Unknown URL " + uri); 2746a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2756a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana try { 2766a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana EntityIterator entityIterator = 2776a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.queryEntities(uri, selection, selectionArgs, sortOrder); 2786a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana return new EntityIteratorWrapper(entityIterator, provider); 2796a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } catch(RuntimeException e) { 2806a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 2816a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana throw e; 2826a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } catch(RemoteException e) { 2836a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 2846a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana throw e; 2856a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2866a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2876a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return InputStream 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final InputStream openInputStream(Uri uri) 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream stream = r.r.openRawResource(r.id); 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return stream; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new FileInputStream(uri.getPath()); 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r"); 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createInputStream() : null; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Synonym for {@link #openOutputStream(Uri, String) 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * openOutputStream(uri, "w")}. 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri) 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return openOutputStream(uri, "w"); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode May be "w", "wa", "rw", or "rwt". 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return OutputStream 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri, String mode) 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createOutputStream() : null; 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a raw file descriptor to access data under a "content:" URI. This 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * underlying {@link ContentProvider#openFile} 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile()} method, so will <em>not</em> work with 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * providers that return sub-sections of files. If at all possible, 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you should use {@link #openAssetFileDescriptor(Uri, String)}. You 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will receive a FileNotFoundException exception if the provider returns a 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sub-section of a file. 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openFile 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile}. 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final ParcelFileDescriptor openFileDescriptor(Uri uri, 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd == null) { 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd.getDeclaredLength() < 0) { 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a full file! 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return afd.getParcelFileDescriptor(); 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Client can't handle a sub-section of a file, so close what 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we got and bail with an exception. 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project afd.close(); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Not a whole file"); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a raw file descriptor to access data under a "content:" URI. This 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interacts with the underlying {@link ContentProvider#openAssetFile} 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile()} method of the provider associated with the 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given URI, to retrieve any file stored there. 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5> 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Uri object can be used to reference a resource in an APK file. The 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Uri should be one of the following formats: 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/id_number</code><br/> 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>id_number</code> is the int form of the ID.<br/> 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre> 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/type/name</code><br/> 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>type</code> is the string form of the resource type. For example, <code>raw</code> 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or <code>drawable</code>. 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>name</code> is the string form of the resource name. That is, whatever the file 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * name was in your res directory, without the type extension. 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre> 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile}. 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final AssetFileDescriptor openAssetFileDescriptor(Uri uri, 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!"r".equals(mode)) { 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Can't write resources: " + uri); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r.r.openRawResourceFd(r.id); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = ParcelFileDescriptor.open( 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new File(uri.getPath()), modeToMode(uri, mode)); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, 0, -1); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No content provider: " + uri); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = provider.openAssetFile(uri, mode); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(fd == null) { 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd.getParcelFileDescriptor(), provider); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, fd.getStartOffset(), 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd.getDeclaredLength()); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Dead content provider: " + uri); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (FileNotFoundException e) { 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class OpenResourceIdResult { 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String authority = uri.getAuthority(); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(authority)) { 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No authority: " + uri); 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = mContext.getPackageManager().getResourcesForApplication(authority); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NameNotFoundException ex) { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No package found for authority: " + uri); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> path = uri.getPathSegments(); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (path == null) { 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No path: " + uri); 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = path.size(); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id; 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 1) { 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = Integer.parseInt(path.get(0)); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 2) { 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = r.getIdentifier(path.get(1), path.get(0), authority); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("More than two path segments: " + uri); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No resource found for: " + uri); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult res = new OpenResourceIdResult(); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.r = r; 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.id = id; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public int modeToMode(Uri uri, String mode) throws FileNotFoundException { 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int modeBits; 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("r".equals(mode)) { 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_ONLY; 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("w".equals(mode) || "wt".equals(mode)) { 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("wa".equals(mode)) { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_APPEND; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rw".equals(mode)) { 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rwt".equals(mode)) { 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Bad mode for " + uri + ": " 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mode); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return modeBits; 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts a row into a table at the given URL. 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the insertion will be atomic. 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted row. The key is the column name for 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing an empty ContentValues will create an empty row. 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the URL of the newly created row. 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Uri insert(Uri url, ContentValues values) 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return provider.insert(url, values); 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6078943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 6088943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * Applies each of the {@link ContentProviderOperation} objects and returns an array 6098943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * of their results. Passes through OperationApplicationException, which may be thrown 6108943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * by the call to {@link ContentProviderOperation#apply}. 6118943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * If all the applications succeed then a {@link ContentProviderResult} array with the 6128943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * same number of elements as the operations will be returned. It is implementation-specific 6138943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * how many, if any, operations will have been successfully applied if a call to 6148943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * apply results in a {@link OperationApplicationException}. 6158943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param authority the authority of the ContentProvider to which this batch should be applied 6168943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param operations the operations to apply 6178943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @return the results of the applications 6188943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws OperationApplicationException thrown if an application fails. 6198943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * See {@link ContentProviderOperation#apply} for more information. 6208943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws RemoteException thrown if a RemoteException is encountered while attempting 6218943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * to communicate with a remote provider. 6228943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 6238943737692169f564cd34a9c8d471f3a5d438712Fred Quintana public ContentProviderResult[] applyBatch(String authority, 62403d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana ArrayList<ContentProviderOperation> operations) 6258943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throws RemoteException, OperationApplicationException { 6268943737692169f564cd34a9c8d471f3a5d438712Fred Quintana ContentProviderClient provider = acquireContentProviderClient(authority); 6276a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana if (provider == null) { 6288943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalArgumentException("Unknown authority " + authority); 6296a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 6306a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana try { 6318943737692169f564cd34a9c8d471f3a5d438712Fred Quintana return provider.applyBatch(operations); 6326a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } finally { 6336a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 6346a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 6356a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 6366a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts multiple rows into a table at the given URL. 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function make no guarantees about the atomicity of the insertions. 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted rows. The key is the column name for 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing null will create an empty row. 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of newly created rows. 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int bulkInsert(Uri url, ContentValues[] values) 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return provider.bulkInsert(url, values); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Deletes row(s) specified by a content URI. 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions, the deletion will be atomic. 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the row to delete. 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of rows deleted. 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int delete(Uri url, String where, String[] selectionArgs) 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return provider.delete(url, where, selectionArgs); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update row(s) in a content URI. 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the update will be atomic. 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to modify. 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The new field values. The key is the column name for the field. 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A null value will remove an existing field value. 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 697b0c6dbd53b26b172fe8eb7d117550e4edf7a0c9cJeff Hamilton * @return The number of rows updated. 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if uri or values are null 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int update(Uri uri, ContentValues values, String where, 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] selectionArgs) { 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URI " + uri); 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return provider.update(uri, values, where, selectionArgs); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the content provider for the given content URI.. 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to a content provider 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The ContentProvider for the given URI, or null if no content provider is found. 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(Uri uri) 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!SCHEME_CONTENT.equals(uri.getScheme())) { 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String auth = uri.getAuthority(); 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (auth != null) { 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, uri.getAuthority()); 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(String name) { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(name == null) { 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, name); 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 745718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 746718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri, starting the provider if necessary. Returns 747718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 748718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 749718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 750718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 751718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param uri specifies which provider should be acquired 752718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 753718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri or null if there isn't one. 754718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 755718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(Uri uri) { 756718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(uri); 757718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 758718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return new ContentProviderClient(this, provider); 759718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 760718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 761718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 762718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 763718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 764718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 765718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 766718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name, starting the provider if necessary. Returns 767718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 768718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 769718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 770718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 771718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param name specifies which provider should be acquired 772718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 773718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name or null if there isn't one. 774718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 775718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(String name) { 776718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(name); 777718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 778718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return new ContentProviderClient(this, provider); 779718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 780718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 781718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 782718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 783718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 784718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register an observer class that gets callbacks when data identified by a 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given content URI changes. 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for a whole class of content. 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param notifyForDescendents If <code>true</code> changes to URIs beginning with <code>uri</code> 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will also cause notifications to be sent. If <code>false</code> only changes to the exact URI 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified by <em>uri</em> will cause notifications to be sent. If true, than any URI values 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at or below the specified URI will also trigger a match. 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The object that receives callbacks when changes occur. 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #unregisterContentObserver 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentObserver observer) 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 801231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().registerContentObserver(uri, notifyForDescendents, 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer.getContentObserver()); 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a change observer. 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The previously registered observer that is no longer needed. 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #registerContentObserver 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void unregisterContentObserver(ContentObserver observer) { 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentObserver contentObserver = observer.releaseContentObserver(); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentObserver != null) { 817231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().unregisterContentObserver( 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentObserver); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The observer that originated the change, may be <code>null</null> 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer) { 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyChange(uri, observer, true /* sync to network */); 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The observer that originated the change, may be <code>null</null> 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncToNetwork If true, attempt to sync the change to the network. 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 847231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().notifyChange( 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uri, observer == null ? null : observer.getContentObserver(), 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer != null && observer.deliverSelfNotifications(), syncToNetwork); 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Start an asynchronous sync operation. If you want to monitor the progress 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the sync you may register a SyncObserver. Only values of the following 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * types may be used in the extras bundle: 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the uri of the provider to sync or null to sync all providers. 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras any extras to pass to the SyncAdapter. 869ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use 870ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * {@link #requestSync(android.accounts.Account, String, android.os.Bundle)} 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startSync(Uri uri, Bundle extras) { 873ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana Account account = null; 874ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (extras != null) { 875ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana String accountName = extras.getString(SYNC_EXTRAS_ACCOUNT); 876ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana if (!TextUtils.isEmpty(accountName)) { 877ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana account = new Account(accountName, "com.google.GAIA"); 878ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 879ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana extras.remove(SYNC_EXTRAS_ACCOUNT); 880ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 881ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana requestSync(account, uri != null ? uri.getAuthority() : null, extras); 882ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 883ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 884ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 885ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Start an asynchronous sync operation. If you want to monitor the progress 886ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * of the sync you may register a SyncObserver. Only values of the following 887ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * types may be used in the extras bundle: 888ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <ul> 889ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Integer</li> 890ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Long</li> 891ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Boolean</li> 892ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Float</li> 893ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>Double</li> 894ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * <li>String</li> 895ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * </ul> 896ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 897ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account which account should be synced 898ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority which authority should be synced 899ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param extras any extras to pass to the SyncAdapter. 900ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 901ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void requestSync(Account account, String authority, Bundle extras) { 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project validateSyncExtrasBundle(extras); 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 904ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().requestSync(account, authority, extras); 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Check that only values of the following types are in the Bundle: 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 918d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana * <li>Account</li> 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>null</li> 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras the Bundle to check 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void validateSyncExtrasBundle(Bundle extras) { 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String key : extras.keySet()) { 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object value = extras.get(key); 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) continue; 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Long) continue; 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Integer) continue; 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Boolean) continue; 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Float) continue; 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Double) continue; 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof String) continue; 934d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana if (value instanceof Account) continue; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("unexpected value type: " 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + value.getClass().getName()); 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException e) { 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException exc) { 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("error unparceling Bundle", exc); 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 945ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 946ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match the Uri. If the uri is null then 947ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * all syncs will be canceled. 948ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 949ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param uri the uri of the provider to sync or null to sync all providers. 950ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @deprecated instead use {@link #cancelSync(android.accounts.Account, String)} 951ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void cancelSync(Uri uri) { 953ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana cancelSync(null /* all accounts */, uri != null ? uri.getAuthority() : null); 954ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 955ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 956ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 957ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Cancel any active or pending syncs that match account and authority. The account and 958ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * authority can each independently be set to null, which means that syncs with any account 959ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * or authority, respectively, will match. 960ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 961ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account filters the syncs that match by this account 962ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority filters the syncs that match by this authority 963ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 964ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void cancelSync(Account account, String authority) { 965ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 966ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().cancelSync(account, authority); 967ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 968ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 969ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 970ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 971ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 972ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Get information about the SyncAdapters that are known to the system. 973ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return an array of SyncAdapters that have registered with the system 974ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 975ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncAdapterType[] getSyncAdapterTypes() { 976ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 977ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAdapterTypes(); 978ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 979ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 980ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 981ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 982ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 983ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 984ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Check if the provider should be synced when a network tickle is received 985ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 986ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 987ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose setting we are querying 988ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if the provider should be synced when a network tickle is received 989ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 990ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getSyncAutomatically(Account account, String authority) { 991ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 992ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncAutomatically(account, authority); 993ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 994ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 995ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 996ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 997ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 998ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 999ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Set whether or not the provider is synced when it receives a network tickle. 1000ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1001ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1002ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being controlled 1003ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync true if the provider should be synced when tickles are received for it 1004ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1005ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setSyncAutomatically(Account account, String authority, boolean sync) { 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1007ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setSyncAutomatically(account, authority, sync); 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1009ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 10105e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // being restarted 10115e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 10125e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 10135e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 10145e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 10155e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Check if this account/provider is syncable. 10165e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * @return >0 if it is syncable, 0 if not, and <0 if the state isn't known yet. 10175e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 10185e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana public int getIsSyncable(Account account, String authority) { 10195e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 10205e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana return getContentService().getIsSyncable(account, authority); 10215e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 10225e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 10235e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 10245e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } 10255e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana 10265e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana /** 10275e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * Set whether this account/provider is syncable. 10285e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana * @param syncable, >0 denotes syncable, 0 means not syncable, <0 means unknown 10295e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana */ 10305e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana public void setIsSyncable(Account account, String authority, int syncable) { 10315e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana try { 10325e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana getContentService().setIsSyncable(account, authority, syncable); 10335e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana } catch (RemoteException e) { 10345e787c42f2a6b3afc8ec8320a08d51b2d44b8614Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1035ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1040ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Gets the master auto-sync setting that applies to all the providers and accounts. 1041ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 1042ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1043ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the master auto-sync setting that applies to all the providers and accounts 1044ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1045ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean getMasterSyncAutomatically() { 1046ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1047ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getMasterSyncAutomatically(); 1048ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1049ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1050ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1051ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1052ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1053ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1054ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Sets the master auto-sync setting that applies to all the providers and accounts. 1055ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If this is false then the per-provider auto-sync setting is ignored. 1056ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * 1057ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param sync the master auto-sync setting that applies to all the providers and accounts 1058ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1059ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void setMasterSyncAutomatically(boolean sync) { 1060ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1061ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().setMasterSyncAutomatically(sync); 1062ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1063ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1064ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1065ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1066ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1067ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1068ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1069ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Returns true if there is currently a sync operation for the given 1070ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * account or authority in the pending list, or actively being processed. 1071ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1072ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1073ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if a sync is active for the given account or authority. 1074ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1075ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncActive(Account account, String authority) { 1076ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1077ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncActive(account, authority); 1078ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1079ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1080ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1081ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1082ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1083ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1084ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * If a sync is active returns the information about it, otherwise returns false. 1085ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the ActiveSyncInfo for the currently active sync or null if one is not active. 1086ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @hide 1087ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1088ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static ActiveSyncInfo getActiveSync() { 1089ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1090ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getActiveSync(); 1091ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1092ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1093ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1094ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1095ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1096ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1097ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Returns the status that matches the authority. If there are multiples accounts for 1098ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * the authority, the one with the latest "lastSuccessTime" status is returned. 1099ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1100ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1101ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return the SyncStatusInfo for the authority, or null if none exists 1102ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @hide 1103ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1104ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static SyncStatusInfo getSyncStatus(Account account, String authority) { 1105ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1106ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().getSyncStatus(account, authority); 1107ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1108ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1109ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1110ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1111ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1112ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana /** 1113ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * Return true if the pending status is true of any matching authorities. 1114ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param account the account whose setting we are querying 1115ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @param authority the provider whose behavior is being queried 1116ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana * @return true if there is a pending sync with the matching account and authority 1117ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana */ 1118ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static boolean isSyncPending(Account account, String authority) { 1119ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1120ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return getContentService().isSyncPending(account, authority); 1121ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1122ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1123ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1124ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1125ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1126ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static Object addStatusChangeListener(int mask, final SyncStatusObserver callback) { 1127ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1128ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana ISyncStatusObserver.Stub observer = new ISyncStatusObserver.Stub() { 1129ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public void onStatusChanged(int which) throws RemoteException { 1130ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana callback.onStatusChanged(which); 1131ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1132ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana }; 1133ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().addStatusChangeListener(mask, observer); 1134ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana return observer; 1135ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1136ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana throw new RuntimeException("the ContentService should always be reachable", e); 1137ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1138ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1139ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1140ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana public static void removeStatusChangeListener(Object handle) { 1141ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana try { 1142ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle); 1143ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } catch (RemoteException e) { 1144ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // exception ignored; if this is thrown then it means the runtime is in the midst of 1145ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana // being restarted 1146ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1147ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana } 1148ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 1149ac9385ef3105fb7464e1f46049c62755a8b7f0e9Fred Quintana 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class CursorWrapperInner extends CursorWrapper { 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private IContentProvider mContentProvider; 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="CursorWrapperInner"; 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mCloseFlag = false; 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorWrapperInner(Cursor cursor, IContentProvider icp) { 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(cursor); 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCloseFlag = true; 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(!mCloseFlag) { 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class ParcelFileDescriptorInner extends ParcelFileDescriptor { 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private IContentProvider mContentProvider; 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="ParcelFileDescriptorInner"; 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mReleaseProviderFlag = false; 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) { 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(pfd); 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(!mReleaseProviderFlag) { 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReleaseProviderFlag = true; 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mReleaseProviderFlag) { 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1206231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1207231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String CONTENT_SERVICE_NAME = "content"; 1208231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 1209231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 1210231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static IContentService getContentService() { 1211231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (sContentService != null) { 1212231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1213231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1214231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME); 1215231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (Config.LOGV) Log.v("ContentService", "default service binder = " + b); 1216231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sContentService = IContentService.Stub.asInterface(b); 1217231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (Config.LOGV) Log.v("ContentService", "default service = " + sContentService); 1218231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 1219231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 1220231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 1221231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static IContentService sContentService; 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ContentResolver"; 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1225