ContentResolver.java revision 03d9490758c9318cee6d14d3cc5007556dce92d0
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 { 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static String SYNC_EXTRAS_ACCOUNT = "account"; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_EXPEDITED = "expedited"; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_FORCE = "force"; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_UPLOAD = "upload"; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override"; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions"; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_CONTENT = "content"; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_ANDROID_RESOURCE = "android.resource"; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String SCHEME_FILE = "file"; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of a single item. Applications should use this 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a particular item. For example, hypothetical IMAP email 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox/1</code> for a particular 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * message in the inbox, whose MIME type would be reported as 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_ITEM_BASE_TYPE + "/vnd.company.imap-msg"</code> 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Compare with {@link #CURSOR_DIR_BASE_TYPE}. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the Android platform's base MIME type for a content: URI 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * containing a Cursor of zero or more items. Applications should use this 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the base type along with their own sub-type of their content: URIs 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that represent a directory of items. For example, hypothetical IMAP email 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client may have a URI 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>content://com.company.provider.imap/inbox</code> for all of the 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * messages in its inbox, whose MIME type would be reported as 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>CURSOR_DIR_BASE_TYPE + "/vnd.company.imap-msg"</code> 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Note how the base MIME type varies between this and 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #CURSOR_ITEM_BASE_TYPE} depending on whether there is 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one single item or multiple items in the data set, while the sub-type 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * remains the same because in either case the data structure contained 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the cursor is the same. 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 94231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public ContentResolver(Context context) { 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected abstract IContentProvider acquireProvider(Context c, String name); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract boolean releaseProvider(IContentProvider icp); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the MIME type of the given content URL. 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url A Uri identifying content (either a list or specific type), 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using the content:// scheme. 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A MIME type for the content, or null if the URL is invalid or the type is unknown 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final String getType(Uri url) 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return provider.getType(url); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (java.lang.Exception e) { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Query the given URI, returning a {@link Cursor} over the result set. 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI, using the content:// scheme, for the content to 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * retrieve. 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param projection A list of which columns to return. Passing null will 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all columns, which is discouraged to prevent reading data 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * from storage that isn't going to be used. 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selection A filter declaring which rows to return, formatted as an 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * SQL WHERE clause (excluding the WHERE itself). Passing null will 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * return all rows for the given URI. 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectionArgs You may include ?s in selection, which will be 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * replaced by the values from selectionArgs, in the order that they 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appear in the selection. The values will be bound as Strings. 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clause (excluding the ORDER BY itself). Passing null will use the 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * default sort order, which may be unordered. 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return A Cursor object, which is positioned before the first entry, or null 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Cursor 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Cursor query(Uri uri, String[] projection, 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String selection, String[] selectionArgs, String sortOrder) { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 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 Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(qCursor == null) { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Wrap the cursor object into CursorWrapperInner object 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new CursorWrapperInner(qCursor, provider); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch(RuntimeException e) { 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1708943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 1718943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * EntityIterator wrapper that releases the associated ContentProviderClient when the 1728943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * iterator is closed. 1738943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 1748943737692169f564cd34a9c8d471f3a5d438712Fred Quintana private class EntityIteratorWrapper implements EntityIterator { 1756a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana private final EntityIterator mInner; 1766a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana private final ContentProviderClient mClient; 1778943737692169f564cd34a9c8d471f3a5d438712Fred Quintana private volatile boolean mClientReleased; 1786a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 1796a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana EntityIteratorWrapper(EntityIterator inner, ContentProviderClient client) { 1806a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana mInner = inner; 1816a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana mClient = client; 1828943737692169f564cd34a9c8d471f3a5d438712Fred Quintana mClientReleased = false; 1836a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 1846a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 1856a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana public boolean hasNext() throws RemoteException { 1868943737692169f564cd34a9c8d471f3a5d438712Fred Quintana if (mClientReleased) { 1878943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalStateException("this iterator is already closed"); 1888943737692169f564cd34a9c8d471f3a5d438712Fred Quintana } 1896a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana return mInner.hasNext(); 1906a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 1916a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 1926a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana public Entity next() throws RemoteException { 1938943737692169f564cd34a9c8d471f3a5d438712Fred Quintana if (mClientReleased) { 1948943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalStateException("this iterator is already closed"); 1958943737692169f564cd34a9c8d471f3a5d438712Fred Quintana } 1966a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana return mInner.next(); 1976a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 1986a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 1996a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana public void close() { 2006a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana mClient.release(); 2016a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana mInner.close(); 2028943737692169f564cd34a9c8d471f3a5d438712Fred Quintana mClientReleased = true; 2036a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2046a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 2056a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana protected void finalize() throws Throwable { 2068943737692169f564cd34a9c8d471f3a5d438712Fred Quintana if (!mClientReleased) { 2078943737692169f564cd34a9c8d471f3a5d438712Fred Quintana mClient.release(); 2088943737692169f564cd34a9c8d471f3a5d438712Fred Quintana } 2096a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana super.finalize(); 2106a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2116a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2126a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 2138943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 2148943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * Query the given URI, returning an {@link EntityIterator} over the result set. 2158943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * 2168943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param uri The URI, using the content:// scheme, for the content to 2178943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * retrieve. 2188943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param selection A filter declaring which rows to return, formatted as an 2198943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * SQL WHERE clause (excluding the WHERE itself). Passing null will 2208943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * return all rows for the given URI. 2218943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param selectionArgs You may include ?s in selection, which will be 2228943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * replaced by the values from selectionArgs, in the order that they 2238943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * appear in the selection. The values will be bound as Strings. 2248943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param sortOrder How to order the rows, formatted as an SQL ORDER BY 2258943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * clause (excluding the ORDER BY itself). Passing null will use the 2268943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * default sort order, which may be unordered. 2278943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @return An EntityIterator object 2288943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws RemoteException thrown if a RemoteException is encountered while attempting 2298943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * to communicate with a remote provider. 2308943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws IllegalArgumentException thrown if there is no provider that matches the uri 2318943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 2328943737692169f564cd34a9c8d471f3a5d438712Fred Quintana public final EntityIterator queryEntities(Uri uri, 2336a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana String selection, String[] selectionArgs, String sortOrder) throws RemoteException { 2346a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana ContentProviderClient provider = acquireContentProviderClient(uri); 2356a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana if (provider == null) { 2366a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana throw new IllegalArgumentException("Unknown URL " + uri); 2376a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2386a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana try { 2396a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana EntityIterator entityIterator = 2406a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.queryEntities(uri, selection, selectionArgs, sortOrder); 2416a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana return new EntityIteratorWrapper(entityIterator, provider); 2426a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } catch(RuntimeException e) { 2436a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 2446a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana throw e; 2456a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } catch(RemoteException e) { 2466a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 2476a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana throw e; 2486a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2496a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 2506a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return InputStream 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final InputStream openInputStream(Uri uri) 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputStream stream = r.r.openRawResource(r.id); 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return stream; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: left here to avoid breaking compatibility. May be removed 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with sufficient testing. 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new FileInputStream(uri.getPath()); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r"); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createInputStream() : null; 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Synonym for {@link #openOutputStream(Uri, String) 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * openOutputStream(uri, "w")}. 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri) 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return openOutputStream(uri, "w"); 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a stream on to the content associated with a content URI. If there 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is no data associated with the URI, FileNotFoundException is thrown. 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI. 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode May be "w", "wa", "rw", or "rwt". 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return OutputStream 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException if the provided URI could not be opened. 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final OutputStream openOutputStream(Uri uri, String mode) 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws FileNotFoundException { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fd != null ? fd.createOutputStream() : null; 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Unable to create stream"); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a raw file descriptor to access data under a "content:" URI. This 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * underlying {@link ContentProvider#openFile} 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile()} method, so will <em>not</em> work with 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * providers that return sub-sections of files. If at all possible, 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you should use {@link #openAssetFileDescriptor(Uri, String)}. You 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will receive a FileNotFoundException exception if the provider returns a 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sub-section of a file. 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on these schemes. 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openFile 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openFile}. 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #openAssetFileDescriptor(Uri, String) 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final ParcelFileDescriptor openFileDescriptor(Uri uri, 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd == null) { 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (afd.getDeclaredLength() < 0) { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a full file! 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return afd.getParcelFileDescriptor(); 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Client can't handle a sub-section of a file, so close what 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we got and bail with an exception. 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project afd.close(); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Not a whole file"); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Open a raw file descriptor to access data under a "content:" URI. This 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interacts with the underlying {@link ContentProvider#openAssetFile} 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile()} method of the provider associated with the 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given URI, to retrieve any file stored there. 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>Accepts the following URI schemes:</h5> 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>content ({@link #SCHEME_CONTENT})</li> 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li> 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>file ({@link #SCHEME_FILE})</li> 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5> 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A Uri object can be used to reference a resource in an APK file. The 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Uri should be one of the following formats: 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/id_number</code><br/> 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>id_number</code> is the int form of the ID.<br/> 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre> 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><code>android.resource://package_name/type/name</code><br/> 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>package_name</code> is your package name as listed in your AndroidManifest.xml. 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For example <code>com.example.myapp</code><br/> 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>type</code> is the string form of the resource type. For example, <code>raw</code> 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or <code>drawable</code>. 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>name</code> is the string form of the resource name. That is, whatever the file 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * name was in your res directory, without the type extension. 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The easiest way to construct this form is 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre> 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </li> 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The desired URI to open. 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ContentProvider.openAssetFile}. 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a new ParcelFileDescriptor pointing to the file. You 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own this descriptor and are responsible for closing it when done. 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws FileNotFoundException Throws FileNotFoundException of no 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * file exists under the URI or the mode is invalid. 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final AssetFileDescriptor openAssetFileDescriptor(Uri uri, 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mode) throws FileNotFoundException { 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String scheme = uri.getScheme(); 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (SCHEME_ANDROID_RESOURCE.equals(scheme)) { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!"r".equals(mode)) { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Can't write resources: " + uri); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult r = getResourceId(uri); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return r.r.openRawResourceFd(r.id); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Resource does not exist: " + uri); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SCHEME_FILE.equals(scheme)) { 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = ParcelFileDescriptor.open( 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new File(uri.getPath()), modeToMode(uri, mode)); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, 0, -1); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No content provider: " + uri); 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AssetFileDescriptor fd = provider.openAssetFile(uri, mode); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(fd == null) { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptor pfd = new ParcelFileDescriptorInner( 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd.getParcelFileDescriptor(), provider); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new AssetFileDescriptor(pfd, fd.getStartOffset(), 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fd.getDeclaredLength()); 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Dead content provider: " + uri); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (FileNotFoundException e) { 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class OpenResourceIdResult { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r; 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id; 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException { 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String authority = uri.getAuthority(); 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources r; 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TextUtils.isEmpty(authority)) { 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No authority: " + uri); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = mContext.getPackageManager().getResourcesForApplication(authority); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NameNotFoundException ex) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No package found for authority: " + uri); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<String> path = uri.getPathSegments(); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (path == null) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No path: " + uri); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = path.size(); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id; 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len == 1) { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = Integer.parseInt(path.get(0)); 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Single path segment is not a resource ID: " + uri); 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (len == 2) { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id = r.getIdentifier(path.get(1), path.get(0), authority); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("More than two path segments: " + uri); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id == 0) { 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("No resource found for: " + uri); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OpenResourceIdResult res = new OpenResourceIdResult(); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.r = r; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project res.id = id; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public int modeToMode(Uri uri, String mode) throws FileNotFoundException { 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int modeBits; 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("r".equals(mode)) { 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_ONLY; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("w".equals(mode) || "wt".equals(mode)) { 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("wa".equals(mode)) { 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_APPEND; 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rw".equals(mode)) { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ("rwt".equals(mode)) { 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modeBits = ParcelFileDescriptor.MODE_READ_WRITE 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_CREATE 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | ParcelFileDescriptor.MODE_TRUNCATE; 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new FileNotFoundException("Bad mode for " + uri + ": " 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mode); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return modeBits; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts a row into a table at the given URL. 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the insertion will be atomic. 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted row. The key is the column name for 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing an empty ContentValues will create an empty row. 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the URL of the newly created row. 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Uri insert(Uri url, ContentValues values) 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return provider.insert(url, values); 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5708943737692169f564cd34a9c8d471f3a5d438712Fred Quintana /** 5718943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * Applies each of the {@link ContentProviderOperation} objects and returns an array 5728943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * of their results. Passes through OperationApplicationException, which may be thrown 5738943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * by the call to {@link ContentProviderOperation#apply}. 5748943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * If all the applications succeed then a {@link ContentProviderResult} array with the 5758943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * same number of elements as the operations will be returned. It is implementation-specific 5768943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * how many, if any, operations will have been successfully applied if a call to 5778943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * apply results in a {@link OperationApplicationException}. 5788943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param authority the authority of the ContentProvider to which this batch should be applied 5798943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @param operations the operations to apply 5808943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @return the results of the applications 5818943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws OperationApplicationException thrown if an application fails. 5828943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * See {@link ContentProviderOperation#apply} for more information. 5838943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * @throws RemoteException thrown if a RemoteException is encountered while attempting 5848943737692169f564cd34a9c8d471f3a5d438712Fred Quintana * to communicate with a remote provider. 5858943737692169f564cd34a9c8d471f3a5d438712Fred Quintana */ 5868943737692169f564cd34a9c8d471f3a5d438712Fred Quintana public ContentProviderResult[] applyBatch(String authority, 58703d9490758c9318cee6d14d3cc5007556dce92d0Fred Quintana ArrayList<ContentProviderOperation> operations) 5888943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throws RemoteException, OperationApplicationException { 5898943737692169f564cd34a9c8d471f3a5d438712Fred Quintana ContentProviderClient provider = acquireContentProviderClient(authority); 5906a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana if (provider == null) { 5918943737692169f564cd34a9c8d471f3a5d438712Fred Quintana throw new IllegalArgumentException("Unknown authority " + authority); 5926a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 5936a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana try { 5948943737692169f564cd34a9c8d471f3a5d438712Fred Quintana return provider.applyBatch(operations); 5956a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } finally { 5966a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana provider.release(); 5976a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 5986a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana } 5996a8d5332f00bdfade6674b312e7166940aa28348Fred Quintana 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inserts multiple rows into a table at the given URL. 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This function make no guarantees about the atomicity of the insertions. 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the table to insert into. 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The initial values for the newly inserted rows. The key is the column name for 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the field. Passing null will create an empty row. 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of newly created rows. 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int bulkInsert(Uri url, ContentValues[] values) 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return provider.bulkInsert(url, values); 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Deletes row(s) specified by a content URI. 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions, the deletion will be atomic. 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param url The URL of the row to delete. 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The number of rows deleted. 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int delete(Uri url, String where, String[] selectionArgs) 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(url); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URL " + url); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return provider.delete(url, where, selectionArgs); 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Update row(s) in a content URI. 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the content provider supports transactions the update will be atomic. 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to modify. 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param values The new field values. The key is the column name for the field. 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project A null value will remove an existing field value. 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (excluding the WHERE itself). 660b0c6dbd53b26b172fe8eb7d117550e4edf7a0c9cJeff Hamilton * @return The number of rows updated. 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws NullPointerException if uri or values are null 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final int update(Uri uri, ContentValues values, String where, 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] selectionArgs) { 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentProvider provider = acquireProvider(uri); 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider == null) { 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown URI " + uri); 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return provider.update(uri, values, where, selectionArgs); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project releaseProvider(provider); 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the content provider for the given content URI.. 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to a content provider 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The ContentProvider for the given URI, or null if no content provider is found. 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(Uri uri) 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!SCHEME_CONTENT.equals(uri.getScheme())) { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String auth = uri.getAuthority(); 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (auth != null) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, uri.getAuthority()); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final IContentProvider acquireProvider(String name) { 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(name == null) { 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return acquireProvider(mContext, name); 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 708718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 709718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri, starting the provider if necessary. Returns 710718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 711718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 712718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 713718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 714718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param uri specifies which provider should be acquired 715718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 716718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * that services the content at uri or null if there isn't one. 717718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 718718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(Uri uri) { 719718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(uri); 720718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 721718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return new ContentProviderClient(this, provider); 722718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 723718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 724718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 725718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 726718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 727718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 728718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * Returns a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 729718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name, starting the provider if necessary. Returns 730718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * null if there is no provider associated wih the uri. The caller must indicate that they are 731718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * done with the provider by calling {@link ContentProviderClient#release} which will allow 732718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * the system to release the provider it it determines that there is no other reason for 733718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * keeping it active. 734718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @param name specifies which provider should be acquired 735718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider} 736718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana * with the authority of name or null if there isn't one. 737718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana */ 738718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana public final ContentProviderClient acquireContentProviderClient(String name) { 739718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana IContentProvider provider = acquireProvider(name); 740718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana if (provider != null) { 741718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return new ContentProviderClient(this, provider); 742718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 743718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 744718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana return null; 745718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana } 746718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana 747718d8a2d7ff3e864a73879eb646f46c14ab74d07Fred Quintana /** 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Register an observer class that gets callbacks when data identified by a 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given content URI changes. 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for a whole class of content. 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param notifyForDescendents If <code>true</code> changes to URIs beginning with <code>uri</code> 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will also cause notifications to be sent. If <code>false</code> only changes to the exact URI 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified by <em>uri</em> will cause notifications to be sent. If true, than any URI values 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at or below the specified URI will also trigger a match. 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The object that receives callbacks when changes occur. 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #unregisterContentObserver 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void registerContentObserver(Uri uri, boolean notifyForDescendents, 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentObserver observer) 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 764231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().registerContentObserver(uri, notifyForDescendents, 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer.getContentObserver()); 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unregisters a change observer. 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The previously registered observer that is no longer needed. 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #registerContentObserver 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final void unregisterContentObserver(ContentObserver observer) { 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IContentObserver contentObserver = observer.releaseContentObserver(); 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (contentObserver != null) { 780231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().unregisterContentObserver( 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentObserver); 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The observer that originated the change, may be <code>null</null> 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer) { 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notifyChange(uri, observer, true /* sync to network */); 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notify registered observers that a row was updated. 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}. 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * By default, CursorAdapter objects will get this notification. 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param observer The observer that originated the change, may be <code>null</null> 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param syncToNetwork If true, attempt to sync the change to the network. 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 810231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().notifyChange( 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uri, observer == null ? null : observer.getContentObserver(), 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project observer != null && observer.deliverSelfNotifications(), syncToNetwork); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Start an asynchronous sync operation. If you want to monitor the progress 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the sync you may register a SyncObserver. Only values of the following 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * types may be used in the extras bundle: 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param uri the uri of the provider to sync or null to sync all providers. 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras any extras to pass to the SyncAdapter. 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startSync(Uri uri, Bundle extras) { 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project validateSyncExtrasBundle(extras); 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 836231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().startSync(uri, extras); 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Check that only values of the following types are in the Bundle: 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Integer</li> 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Long</li> 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Boolean</li> 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Float</li> 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Double</li> 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>String</li> 850d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana * <li>Account</li> 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>null</li> 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param extras the Bundle to check 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void validateSyncExtrasBundle(Bundle extras) { 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String key : extras.keySet()) { 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object value = extras.get(key); 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) continue; 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Long) continue; 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Integer) continue; 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Boolean) continue; 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Float) continue; 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof Double) continue; 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value instanceof String) continue; 866d9d2f1140b52fd0c014e9deac59f6000564b7e84Fred Quintana if (value instanceof Account) continue; 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("unexpected value type: " 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + value.getClass().getName()); 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException e) { 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException exc) { 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("error unparceling Bundle", exc); 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void cancelSync(Uri uri) { 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 879231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn getContentService().cancelSync(uri); 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class CursorWrapperInner extends CursorWrapper { 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private IContentProvider mContentProvider; 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="CursorWrapperInner"; 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mCloseFlag = false; 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CursorWrapperInner(Cursor cursor, IContentProvider icp) { 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(cursor); 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() { 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCloseFlag = true; 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(!mCloseFlag) { 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.finalize(); 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class ParcelFileDescriptorInner extends ParcelFileDescriptor { 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private IContentProvider mContentProvider; 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String TAG="ParcelFileDescriptorInner"; 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mReleaseProviderFlag = false; 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) { 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(pfd); 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContentProvider = icp; 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void close() throws IOException { 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(!mReleaseProviderFlag) { 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.close(); 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver.this.releaseProvider(mContentProvider); 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReleaseProviderFlag = true; 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() throws Throwable { 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mReleaseProviderFlag) { 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(); 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 940231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 941231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static final String CONTENT_SERVICE_NAME = "content"; 942231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 943231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn /** @hide */ 944231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn public static IContentService getContentService() { 945231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (sContentService != null) { 946231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 947231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 948231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME); 949231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (Config.LOGV) Log.v("ContentService", "default service binder = " + b); 950231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn sContentService = IContentService.Stub.asInterface(b); 951231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn if (Config.LOGV) Log.v("ContentService", "default service = " + sContentService); 952231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn return sContentService; 953231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn } 954231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn 955231cc608d06ffc31c24bf8aa8c8275bdd2636581Dianne Hackborn private static IContentService sContentService; 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "ContentResolver"; 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 959