I. Overview
ContentProvider: Provides a unified interface for storing and retrieving data that can be shared between different applications.
Many of the data built into Android are used in the form of contentprovider for developers to invoke (such as video, audio, images, contacts, etc.).
1. Organize your data using a table Form
-regardless of the source of the data, ContentProvider will be considered a table. (Organize the data into a form)
2. Methods of delivery
-Query: Inquiry
-Insert: Insert
-Update: Updates
-Delete: Delete
-GetType: Get Data type
-OnCreate: callback function to invoke when creating data
3. Public URI
-Each contentprovider has a common URI, which is used to represent the data provided by this contentprovider.
-The ContentProvider provided by Android are stored in the Android.provider package.
4. Comparative analysis
Although other methods can be used to share data externally, the way data is accessed varies depending on how the data is stored.
-File sharing data, need to file operation read and write data;
-sharing data with sharedpreferences requires the use of the Sharedpreferences API to read and write data.
-the benefit of using ContentProvider to share data is to unify the way data is accessed.
Second, the implementation of ContentProvider step 1. Define a Content_uri constant
The Content_uri string must be a unique public static final URI Content_uri = Uri.parse ("content://com. Wangweida.mycontentprovider "); If there is a child table, the URI is: public static final URI Content_uri = Uri.parse ("content://com. Wangweida.mycontentprovider/users ");
2. Define a class that inherits from ContentProvider
public class Mycontentprovider extends ContentProvider {...}
3. All the ways to implement ContentProvider
Provides a constant class for ContentProvider Mycontentprovidermetadata.java
public class Mycontentprovidermetadata {//uri, where the string must be consistent with the declared authorities public static final string authorities = " Com.zhuanghongji.app.MyContentProvider "; Database name public static final String database_name = "MYCONTENTPROVIDER.DB"; The version of the database public static final int database_version = 1; Table name public static final String users_table_name = "user"; public static final class Usertablemetadata implements basecolumns{//table name public static final String table_name = "User"; The URI for accessing the ContentProvider public static final URI Content_uri = uri.parse ("content://" + authorities + "/user"); The definition of the data type returned by the ContentProvider public static final String Content_Type = "vnd.android.cursor.dir/vnd.myprovider.us ER "; public static final String Content_type_item = "Vnd.android.cursor.item/vnd.myprovider.user"; Column name public static final String user_name = "NAME"; Default Sort method public static final String Default_sort_order = "_id desc"; } }
public class Mycontentprovider extends ContentProvider {//Access all columns of table public static final int incoming_user_collection = 1; Access a separate column public static final int incoming_user_single = 2; Operation URI class public static final Urimatcher Urimatcher; Add a custom URI for urimatcher static{urimatcher = new Urimatcher (urimatcher.no_match); Urimatcher.adduri (mycontentprovidermetadata.authorities, "/user", incoming_user_collection); Urimatcher.adduri (mycontentprovidermetadata.authorities, "/user/#", Incoming_user_single); } private Databasehelper dh; Alias public static HASHMAP userprojectionmap for database table fields; static {Userprojectionmap = new HashMap (); Userprojectionmap.put (usertablemetadata._id,usertablemetadata._id); Userprojectionmap.put (Usertablemetadata.user_name, usertablemetadata.user_name); /** * Delete table data */@Override public int Delete (URI Uri, String selection, string[] selectionargs) {SYSTEM.O Ut.println ("DeletE "); Get a writable database sqlitedatabase db = Dh.getwritabledatabase (); Execute Delete, get deleted number of rows int count = Db.delete (Usertablemetadata.table_name, Selection, Selectionargs); return count; /** * Database access type */@Override public String getType (Uri uri) {System.out.println ("GetType"); Based on user request, Get data type switch (Urimatcher.match (URI)) {case Incoming_user_collection:return Mycon TentProviderMetaData.UserTableMetaData.CONTENT_TYPE; Case Incoming_user_single:return MyContentProviderMetaData.UserTableMetaData.CONTENT_TYPE_ITEM; Default:throw new IllegalArgumentException ("UnKnown URI" +uri); }}/** * Insert data * * @Override public uri insert (URI uri, contentvalues values) {//Get a writable database SQL Itedatabase db = Dh.getwritabledatabase (); Inserts data into the specified table to get the returned ID long rowId = db.insert (usertablemetadata.table_name, null, values); if (RowId &Gt 0) {//Determine if the insert succeeds//If added successfully, take advantage of the newly added ID and Uri Inserteduseruri = Contenturis.withappendedid (usertablemetadat A.content_uri, rowId); Notifies the listener that the data has changed GetContext (). Getcontentresolver (). Notifychange (Inserteduseruri, NULL); return Inserteduseruri; } return URI; }/** * Callback function called when creating ContentProvider */@Override public boolean onCreate () {System.out.println ("onCreate "); Get database Help class DH = new Databasehelper (GetContext (), mycontentprovidermetadata.database_name); return false; /** * Query Database */@Override public Cursor query (URI uri, string[] projection, String selection, string[] Sel Ectionargs, String SortOrder) {//Create a sqlite sqlitequerybuilder QB = new Sqlitequerybuilder () that executes the query; Determine user request, query all or single switch (Urimatcher.match (URI)) {case incoming_user_collection://Set table name to query Qb.settables (Usertablemetadata.table_name); Sets the alias Qb.setprojectionmap (USERPROJECTIONMAP) of the table field; Break Case INCOMING_USER_SINGLE:qb.setTables (Usertablemetadata.table_name); Qb.setprojectionmap (USERPROJECTIONMAP); Append condition, getpathsegments () gets the array that the user requests the URI address intercept,//Get (1) Get rid of the address in/after the second element Qb.appendwhere (usertable metadata._id + "=" + uri.getpathsegments (). Get (1)); Break }//Set sort String by order; if (Textutils.isempty (SortOrder)) {by = Usertablemetadata.default_sort_order; } else {by = SortOrder; }//Get a readable database sqlitedatabase db = Dh.getreadabledatabase (); Executes the query, puts the input into the Cursor C = qb.query (db, Projection, selection, Selectionargs, NULL, NULL, by-pass); Set the Listener C.setnotificationuri (GetContext (). Getcontentresolver (), URI); return C; }/** * Update database */@Override public int update (URI Uri, ContentvaLues values, String selection, string[] Selectionargs) {System.out.println ("Update"); Get a writable database sqlitedatabase db = Dh.getwritabledatabase (); Execute UPDATE statement, get updated number of bars int count = Db.update (Usertablemetadata.table_name, values, selection, Selectionargs); return count; } }4. Declaration in Androidminifest.xml
<provider android:name= ". Mycontentprovider "android:authorities=" Com.zhuanghongji.app.MyContentProvider "/>
Third, another example illustrates 1. Introduction to URI Classes
Uri uri = uri.parse ("Content://com.changcheng.provider.contactprovider/contact")
The query strings used in content provider are different from standard SQL queries.
Operations such as SELECT, add, delete, modify we all use a special URI that consists of 3 parts:
- "content://"
- Represents the path to the data,
- An optional ID for the identity data
Content://media/internal/images This URI will return all the pictures stored on the device content://contacts/people/ This URI will return all contact information on the device content://contacts/people/45 This URI returns a single result (contact record with ID 45 in the contact information)
Although this query string format is common, it still seems a bit confusing.
To do this, Android provides a series of helper classes ( android.provider包 below) that contain a lot of query strings given in the form of class variables, which makes it easier for us to understand a bit, so the above content://contacts/people/45 URI can be written as follows:
Uri person = Contenturis.withappendedid (People.content_uri, 45);
Then execute the data query:
cursor cursor = managedquery (person, NULL, NULL, NULL);
This query returns a cursor that contains all the data fields, and we can iterate over the cursor to get all the data.
2. Example
How to read the specified data column name and number in the contact information table in turn.
public class Contentproviderdemo extends Activity {@Override public void onCreate (Bundle savedinstancestate) { Super.oncreate (savedinstancestate); Setcontentview (R.layout.main); Displayrecords (); private void Displayrecords () {///the array contains all fields to be returned String columns[] = new string[] {people.name, people . Number}; Uri mcontacts = People.content_uri; Cursor cur = managedquery (mcontacts, columns,//data field to return NULL,//WHERE clause NULL,//The argument of the WHERE clause NULL//ORDER-BY clause); if (Cur.movetofirst ()) {String name = null; String Phoneno = null; Do {//Get the value of the field name = Cur.getstring (Cur.getcolumnindex (people.name)); Phoneno = cur.getstring (Cur.getcolumnindex (People.number)); Toast.maketext (This, name + "" + Phoneno, Toast.length_long). Show (); } while (Cur.movetonexT ()); } }}3. Modify the Record
You can use the Contentresolver.update () method to modify the data:
private void UpdateRecord (int recNo, String name) { uri uri = Contenturis.withappendedid (People.content_uri, recNo); contentvalues values = new Contentvalues (); Values.put (People.name, NAME); Getcontentresolver (). Update (URI, values, NULL, NULL);}
Now you can call the above method to update the specified record:
UpdateRecord ("XYZ"); Change the Name field value of the 10th record to "XYZ"
4. Add a record
You can call the Contentresolver.insert () method:
- The method accepts a target URI for the record to be added, and a map object that contains the new record value.
- The return value after the call is the URI of the new record, including the record number.
In the example above, we are all based on the standard content Provider of the contact information book.
Create insertRecords(name, phoneNo) The following method to add a contact name and phone number to your contact information book.
private void Insertrecords (string name, String Phoneno) { contentvalues values = new Contentvalues (); Values.put (People.name, NAME); Uri uri = Getcontentresolver (). Insert (People.content_uri, values); LOG.D ("ANDROID", uri.tostring ()); Uri Numberuri = Uri.withappendedpath (URI, People.Phones.CONTENT_DIRECTORY); Values.clear (); Values.put (Contacts.Phones.TYPE, People.Phones.TYPE_MOBILE); Values.put (People.number, Phoneno); Getcontentresolver (). Insert (Numberuri, values);
5. Deleting records
private void Deleterecords () { uri uri = People.content_uri; Getcontentresolver (). Delete (URI, NULL, NULL);}
You can also specify a WHERE condition statement to delete a specific record:
Getcontentresolver (). Delete (URI, "name=" + "' xyz xyz '", null);
This will delete the record with name ' XYZ XYZ '.
6. Create a ContentProvider1. Create a Class 2 that inherits the ContentProvider parent class. Defines a class variable named Content_uri, which is the URI type of public static final
- You must specify a unique string value for it, and the best scenario is to use the full name of the class, such as:
public static final Uri Content_uri = Uri.parse ("Content://com.google.android.mycontentprovider");
3. Define the data column name you want to return to the client
- If you are using an Android database, you must define a column called _id, which is used to represent the uniqueness of each record.
4. Create your data storage System
- Most content provider use
Android文件系统 or SQLite数据库 keep data, but you can also store it in any way you want.
- If you want to store byte-type data, such as bitmap files.
A. The data column is actually a URI string that represents the actual saved file, through which to read the corresponding file data.
B. The content provider that handles this data type needs to implement a field named _data, and the _data field lists the exact path to the file Android文件系统 .
C. This field is not only for use by clients, but also for ContentResolver use.
D. The client can call the ContentResolver.openOutputStream() method to process the file resource that the URI points to.
E. If it is in ContentResolver itself, it can access the data file directly because it has a higher privilege than the client.
5. Declare a variable of public static string type
- Used to specify the data column to be returned from the cursor.
6. Query returns an object of type cursor
- All methods that perform write operations, such as insert (), update (), and delete (), are monitored.
7. Use the < provider/> tag in Androidmenifest.xml to set the ContentProvider8. If the type of data you want to work with is a relatively new type
- You must first define a new MIME type for the Contentprovider.getype (URL) to return.
- There are two forms of MIME types:
- A single record that is specified for the
- The other is for more than one record.
A common format is given here:
Vnd.android.cursor.item/vnd.yourcompanyname.contenttype//MIME type for a single record for example, a uricontent://to request train information COM.EXAMPLE.TRANSPORTATIONPROVIDER/TRAINS/122 may return a MIME type such as Typevnd.android.cursor.item/vnd.example.rail
Vnd.android.cursor.dir/vnd.yourcompanyname.contenttype//MIME type for multiple records for example, a uricontent://that requests all train information Com.example.transportationprovider/trains may return a MIME type such as Vnd.android.cursor.dir/vnd.example.rail
9. Create ContentProvider
The following code creates one ContentProvider , which simply stores the user name and displays all user names.
(Use the Sqllite database to store this data):
(1) The following is defined in this ContentProvider class CONTENT_URI as well 数据列 :
public class Myusers {public static final String authority = "Com.zhuanghongji.MyContentProvider"; The Basecolumn class already contains the _id field public static final class User implements Basecolumns {public static final Uri CONTENT _uri = Uri.parse ("Content://com.zhuanghongji.mycontentprovider"); Table data column public static final String user_name = "user_name"; }}
(2) Then define the actual content provider class based on the class above:
public class Mycontentprovider extends ContentProvider {private sqlitedatabase SqlDB; Private Databasehelper DBHelper; private static final String database_name = "USERS.DB"; private static final int database_version= 1; private static final String table_name= "User"; private static final String TAG = "Mycontentprovider"; private static class Databasehelper extends Sqliteopenhelper {databasehelper (context context) {Super (C Ontext, database_name, NULL, database_version); } @Override public void OnCreate (Sqlitedatabase db) {//Create a table for storing data db.execsql ("Create Table "+ table_name +" (_id INTEGER PRIMARY KEY autoincrement, user_name TEXT); "); @Override public void Onupgrade (sqlitedatabase db, int oldversion, int newversion) {db.execsql ("DROP TA BLE IF EXISTS "+ table_name); OnCreate (DB); Call OnCreate () to create}} @Override public int deleTe (Uri Uri, String s, string[] as) {return 0; } @Override public String getType (Uri uri) {return null; } @Override public uri insert (URI Uri, contentvalues contentvalues) {SqlDB = Dbhelper.getwritabledatabase (); Long rowId = Sqldb.insert (table_name, "", contentvalues); if (RowId > 0) {Uri Rowuri = Contenturis.appendid (MyUsers.User.CONTENT_URI.buildUpon (), rowId). Build (); GetContext (). Getcontentresolver (). Notifychange (Rowuri, NULL); return Rowuri; } throw new SQLException ("Failed to insert row into" + URI); } @Override public Boolean onCreate () {dbhelper = new Databasehelper (GetContext ()); return (DBHelper = = null)? False:true; @Override public Cursor query (URI uri, string[] projection, string selection, string[] Selectionargs, String Sorto Rder) {Sqlitequerybuilder QB = new Sqlitequerybuilder (); Sqlitedatabase db = Dbhelper.getreaDabledatabase (); Qb.settables (table_name); Cursor C = qb.query (db, projection, selection, NULL, NULL, NULL, sortOrder); C.setnotificationuri (GetContext (). Getcontentresolver (), URI); return C; } @Override public int update (URI Uri, Contentvalues contentvalues, String S, string[] as) {return 0; }}
A named MyContentProvider Create is Content Provider completed, which is used to add and read records from the SQLite database.
10. Configure in Androidmanifest.xml:
<provider android:name= "Mycontentprovider" android:authorities= "Com.zhuanghongji.MyContentProvider" />
11. Use the contentprovider you just defined
- Add ContentProvider access to the application.
- The
getContentResolver() Contentresolver object is obtained by means of the method.
- Call the method of the Contentresolver class to
query() query the data, and the method returns a Cursor object.
- The resulting cursor object is analyzed to obtain the required data.
- Call the cursor class's
close() method to close the cursor object.
public class Mycontentproviderdemo extends Activity {@Override protected void onCreate (Bundle savedinstancestate) { Super.oncreate (savedinstancestate); Insertrecord ("MyUser"); Displayrecords (); } private void Insertrecord (String userName) {contentvalues values = new Contentvalues (); Values.put (MyUsers.User.USER_NAME, userName); Getcontentresolver (). Insert (MyUsers.User.CONTENT_URI, values); } private void Displayrecords () {String columns[] = new string[] {myusers.user._id, MyUsers.User.USER_NAME}; Uri Myuri = MyUsers.User.CONTENT_URI; Cursor cur = managedquery (Myuri, columns,null, NULL, NULL); if (Cur.movetofirst ()) {String id = null; String userName = null; do {id = cur.getstring (cur.getcolumnindex (myusers.user._id)); UserName = cur.getstring (Cur.getcolumnindex (MyUsers.User.USER_NAME)); Toast.maketext (this, id + ""+ UserName, Toast.length_long). Show (); } while (Cur.movetonext ()); } }}
Android Summary: Use of ContentProvider