Android applications can use files or sqllite databases to store data. Contentprovider provides a way to share data among multiple applications. For example, contact information can be accessed by multiple applications. Contentprovider is a class that implements a set of standard methods used to provide data access for other applications.
The application can perform the following operations in content provider:
Query data
Modify data
Add data
Delete data
Standard content provider:
Android provides some standard content providers that have been implemented in the system, such as contact information and image libraries. You can use these contentproviders to access the contact information and images stored on devices.
Query records:
The query strings used in content providers are different from standard SQL queries. We use a special URI for many operations such as select, add, delete, and modify. This URI consists of three parts: "content ://", indicates the data path and an optional ID. The following is an example URI:
Content: // media/Internal/images this URI will return all images stored on the device
Content: // contacts/people/This URI will return all contacts on the device.
Content: // contacts/people/45 This URI returns a single result (the contact record with ID 45 in the contact information)
Although this query string format is common, it looks a bit confusing. Therefore, Android provides a series of help classes (in Android. under the provider package), which contains a lot of query strings in the form of class variables, this method is easier for us to understand, see the following example:
Mediastore. Images. Media. internal_content_uri
Contacts. People. content_uri
Therefore, the URI content: // contacts/people/45 can be written as follows:
Uri person = contenturis. withappendedid (people. content_uri, 45 );
Then execute the Data Query:
Cursor cur = managedquery (person, null );
This query returns a cursor containing all data fields. We can use this cursor to retrieve all data:
Package com. wissen. testapp;
Public class contentproviderdemo extends activity {
@ Override
Public voidoncreate (bundle savedinstancestate ){
Super. oncreate (savedinstancestate );
Setcontentview (R. layout. Main );
Displayrecords ();
}
Private void displayrecords (){
// This array contains all the 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 be returned
Null, // where clause
Null, // where clause Parameters
Null // order-by clause
);
If (cur. movetofirst ()){
String name = NULL;
String phoneno = NULL;
Do {
// Obtain the field value
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 ());
}
}
}
The preceding example shows how to read the specified data column name and number in the contact information table in sequence.
Modification record:
We can use the contentresolver. Update () method to modify the data. Let's write a 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 (10, "xyz"); // change the name field value of the first record to "xyz"
Add record:
To add records, we can call contentresolver. insert () method. This method accepts the target URI of the record to be added and a map object containing the value of the new record. The returned value after the call is the URI of the new record, including the record number.
In the above example, we are all based on the standard content provider of the contact information book. Now we will create an insertrecord () method to add data to the contact information book:
Private void insertrecords (string name, stringphoneno ){
Contentvalues values = new contentvalues ();
Values. Put (people. Name, name );
Uri uri = getcontentresolver (). insert (people. content_uri, values );
Log. D ("android", Uri. tostring ());
Urinumberuri = 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 );
}
In this way, you can call insertrecords (name, phoneno) to add the contact name and phone number to the contact information book.
Delete record:
The getcontextresolver. Delete () method in contentprovider can be used to delete a record. The following record is used to delete all contact information on the device:
Private void deleterecords (){
Uri uri = people. content_uri;
Getcontentresolver (). Delete (Uri, null, null );
}
You can also specify the where Condition Statement to delete a specific record:
Getcontentresolver (). Delete (Uri, "name =" + "'xyz XYZ '", null );
This will delete the record whose name is 'xyz xyz.
Create content provider:
Now we know how to use content provider. Now let's take a look at how to create a contentprovider.
To create our own content provider, follow these steps:
1. Create a class that inherits the contentprovider parent class
2. Define a class variable named content_uri and public staticfinal URI. You must specify a unique string value for it. The best solution is to use the full name of the class, for example:
Public static final URI content_uri = URI. parse ("content: // com. Google. Android. mycontentprovider ");
3. Create your data storage system. Most contentproviders use the android file system or SQLite database to maintain data, but you can also store data in any way you want.
4. Define the data column name you want to return to the client. If you are using an android database, the data column is used in the same way as other databases you are familiar. However, you must define a column named _ id for it to indicate the uniqueness of each record.
5. if you want to store byte data, such as bitmap files, the data column that stores the data is actually a URI string that represents the actually saved file, the client uses it to read the corresponding file data. to process this data type, the contentprovider needs to implement a field named _ data, the _ data field lists the exact paths of the file on the android file system. This field is not only used by the client, but also for contentresolver. The client can call contentresolver. openoutputstream () method to process the file Resources pointed to by the URI. If it is contentresolver itself, it can directly access the data file because it has higher permissions than the client.
6. Declare a public static string variable to specify the data column to be returned from the cursor.
7. the query returns a cursor type object. All write operations, such as insert (), update (), and delete (), will be monitored. We can use the contentresover (). policychange () method to notify the listener about data updates.
8. Use tags in androidmenifest. XML to set contentprovider.
9. If the data type you want to process is a relatively new type, you must first define a new MIME type for contentprovider. getype (URL) to return. The MIME type can be either specified for a single record or multiple records. A common format is provided here:
Vnd. Android. cursor. Item/vnd. yourcompanyname. contenttype (MIME type of a single record)
For example, a request for train information URI such as content: // COM. example. transportationprovider/TRAINS/122 may return typevnd. android. cursor. item/vnd. example. a mime type such as rail.
Vnd. Android. cursor. DIR/vnd. yourcompanyname. contenttype (MIME type of multiple Records)
For example, a URI that requests all train information, such as content: // COM. example. transportationprovider/trains may return vnd. android. cursor. DIR/vnd. example. a mime type such as rail.
The following code creates a content provider that only stores the user name and displays all the user names (using the sqllite database to store the data ):
Package com. wissen. testapp;
Public class myusers {
Publicstatic final string authority = "com. wissen. mycontentprovider ";
// The basecolumn class already contains the _ id field
Public static final class userimplements basecolumns {
Public static final URI content_uri = URI. parse ("content: // com. wissen. mycontentprovider ");
// Table data column
Public static final string user_name = "user_name ";
}
}
The class above defines the content_uri of contentprovider and the data column. The following defines the actual contentprovider class based on the above class:
Packagecom. wissen. testapp. Android;
Public class mycontentprovider extendscontentprovider {
Privatesqlitedatabase sqldb;
Privatedatabasehelper dbhelper;
Privatestatic final string database_name = "users. DB ";
Privatestatic finalint database_version = 1;
Privatestatic final string table_name = "user ";
Privatestatic final string tag = "mycontentprovider ";
Private Static class databasehelper extends sqliteopenhelper {
Databasehelper (context ){
Super (context, database_name, null, database_version );
}
@ Override
Public void oncreate (sqlitedatabase dB ){
// Create a table for data storage
Db.exe csql ("create table" + table_name + "(_ id integer primarykey autoincrement, user_name text );");
}
@ Override
Public void onupgrade (sqlitedatabase dB, int oldversion, intnewversion ){
Db.exe csql ("Drop table if exists" + table_name );
Oncreate (db );
}
}
@ Override
Public intdelete (URI Uri, string S, string [] ){
Return 0;
}
@ Override
Publicstring GetType (URI ){
Return NULL;
}
@ Override
Public uriinsert (URI Uri, 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 (). policychange (rowuri, null );
Return rowuri;
}
Throw new sqlexception ("failed to insert row into" + URI );
}
@ Override
Publicboolean oncreate (){
Dbhelper = new databasehelper (getcontext ());
Return (dbhelper = NULL )? False: true;
}
@ Override
Publiccursor query (URI Uri, string [] projection, string selection, string [] selectionargs, string sortorder ){
Sqlitequerybuilder QB = new sqlitequerybuilder ();
Sqlitedatabase DB = dbhelper. getreadabledatabase ();
QB. settables (table_name );
Cursor c = QB. Query (dB, projection, selection, null, sortorder );
C. setnotificationuri (getcontext (). getcontentresolver (), Uri );
Return C;
}
@ Override
Public intupdate (URI Uri, contentvalues, string S, string [] ){
Return 0;
}
}
A contentprovider named mycontentprovider is created and used to add and read records from the SQLite database.
The content provider entry must be configured in androidmanifest. xml:
Then, let's use the defined content provider:
Package com. wissen. testapp;
Public class mycontentdemo extends activity {
@ Override
Protectedvoid oncreate (bundle savedinstancestate ){
Super. oncreate (savedinstancestate );
Insertrecord ("myuser ");
Displayrecords ();
}
Private voidinsertrecord (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 );
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 ());
}
}
}
The above class will first add a user data to the database, and then display all the user data in the database.
So far, we have understood how to use and create the content provider.