问题
I was reading the doc, but I am still not too sure. Its says to use getContentResolver(), but then that really isn't using CursorLoader. So is there a way to do it through CursorLoader? I know how to do it with query(). Are the steps very similar? Even just a link that explains exactly this would be helpful.
Please note, do not link me to the Google doc as they do not have an example that ever uses the insert() method from ContentProvider using a CursorLoader.
Thanks in advance!!
Edit: I should probably mention the reason I am confused with this is because calling a new CursorLoader automatically calls ContentProviders query() method. But how can I do the same for insert?
回答1:
Check out my blog post on the subject:
Content Resolvers and Content Providers
The CursorLoader has nothing to do with it.
Insertion is a totally different concept... it has absolutely nothing to do with the CursorLoader. When coupled with the LoaderManager, the CursorLoader automatically queries your database and updates itself when the ContentObserver is notified of a datastore change. It has nothing to do with the actual process of inserting data into your database.
How requests to the ContentResolver are resolved
When you insert (or query or update or delete) data into your database via the content provider, you don't communicate with the provider directly. Instead, you use the ContentResolver object to communicate with the provider (note that the ContentResolver is a private instance variable in your application's global Context) . More specifically, the sequence of steps performed is:
You call
getContentResolver().insert(Uri, ContentValues);The
ContentResolverobject determines the authority of the Uri.The
ContentResolverrelays the request to the content provider registered with the authority (this is why you need to specify the authority in theAndroidManifest.xml).The content provider receives the request and performs the specified operation (in this case
insert). How and where the data is inserted depends on how you implemented theinsertmethod (ContentProvideris an abstract class that requires the user to implementinsert,query,delete,update, andgetType).
Hopefully you were able to wrap your head around that at least a little. The reason why there are so many steps involved is because Android (1) allows applications to have more than one content provider, and (2) needs to ensure that apps can securely share data with other third-party apps. (It wasn't because it wanted to confuse you, I promise).
Inserting data via the ContentProvider
Now that you (hopefully) have a better idea of how the ContentResolver is able to relay these requests to the content provider, inserting the data is fairly straight forward:
First, decide which uri you want to have matched by your content provider. This depends on how you decided to match your uris with the
UriMatcher. Each uri you have represents a different means of inserting data into your internal database (i.e. if your app has two tables, you will probably have two uris, one for each table).Create a new
ContentValuesobject and use it to package the data you wish to send to the content provider. TheContentValuesobject maps column names to data values. In the below example, the column name is "column_1" and the value being inserted under that column is "value_1":ContentValues values = new ContentValues(); values.put("column_1", "value_1");Once received, the content provider will (in your case) pass the
valuesobject to yourSQLiteDatabase(via theSQLiteDatabase.insert(String table, String nullColumnHack, ContentValues values)method). Unlike theContentProvider, this method is implemented for you... theSQLiteDatabaseknows how to handle thevaluesobject and will insert the row into the database, returning the row id of the inserted row, or-1if the insertion failed.
... and that's how you insert data into your database.
TL;DR
Use getContentResolver().insert(Uri, ContentValues);
回答2:
Convert Cursor to ContentValues for easy database insertion.
Its says to use getContentResolver(), but then that really isn't using CursorLoader
Besides what Alex said, there's nothing preventing you from iterating through the Cursor returned, putting them into ContentValues and then inserting that (say, to a different DB).
Just an example from the top of my head (a simple Cursor of two String columns):
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
if (cursor.moveToFirst()) {
ArrayList<ContentValues> values = new ArrayList<ContentValues>();
do {
ContentValues row = new ContentValues();
DatabaseUtils.cursorStringToContentValues(cursor, fieldFirstName, row);
DatabaseUtils.cursorStringToContentValues(cursor, fieldLastName, row);
values.add(row);
} while (cursor.moveToNext());
ContentValues[] cv = new ContentValues[values.size()];
values.toArray(cv);
getContentResolver().bulkInsert(CONTENT_NAMES, cv);
}
}
There are probably more efficient ways to do that (and definitely some integrity checks), but that was my first thought...
来源:https://stackoverflow.com/questions/11131058/how-to-properly-insert-values-into-the-sqlite-database-using-contentproviders-i