Android provides five data storage methods:
(1) files: Use fileinputstream and fileoutputstream to operate files. For details about how to use it, refer to the blog "android study note 34: Using files to store data".
(2) shared preferences: used to store data in the form of key-value pairs and save system configuration information. For details about how to use it, see the blog "android study note 35: using shared preferences to store data".
(3) content providers: data sharing for ApplicationsProgramData access.
(4) SQLite: a lightweight relational database built in Android that supports the SQL language. It is used to store a large amount of data and can be used, updated, maintained, and operated on the data. For more information about how to use the SDK, see the blog "android study note 36: Using SQLite to store data".
(5) Network: stores and obtains data through the network.
This blog post introduces the third way to share data between applications through content providers.
1. Introduction to content providers
In the Android system, there is no public data storage area for all applications to access, that is, data is private in each application. So, how to access data in another application in one application to achieve data sharing between applications?
Of course, you can set the second parameter mode in the openfileoutput () method as described in "android study note 34: using file storage data" to context. mode_world_readable and context. mode_world_writeable allows other applications to read and write files in the application. However, the disadvantages of using this method are also obvious, not only need to know the storage path of the file, but also completely expose the file content, it is inconvenient and insecure for content providers and content visitors.
Therefore, the android system provides content providers to facilitate secure data sharing between applications.
1.1 contentresolver
All content providers implement some common interfaces, including data query, addition, modification, and deletion. In the application, we can use the getcontentresolver () method to obtain a contentresolver object, and then we can use this contentresolver object to operate on the content provider you need. The contentresolver class provides methods used to operate content providers, including insert (), delete (), update (), and query ().
Generally, developers do not need to deal directly with the content provider object. When the system is running, all contentprovider objects are instantiated, and there is only one instance for each type of contentprovider. This instance can communicate with multiple contentresolver objects in different programs or processes. The interaction between these processes is handled by the contentresolver and contentprovider classes.
For content providers, the most important thing is the data storage structure and Uri.
1.2 Data Storage Structure
Content Providers provides the data stored in the form of a data table to visitors. In the data table, each row is a record, and each column is data of a specific type and meaning. For example, the contact's content provider Data Storage Structure 1 is shown.
Figure 1 content provider Data Storage Structure example
It can be seen that each record has a _ id field to uniquely identify the record, similar to the primary key in the database.
1.3uri
Each content provider provides a public URI that uniquely identifies its own dataset. If a content provider manages multiple datasets, it needs to assign an independent URI to each dataset.
Android requires that the Uris of all content providers must start with "content. Generally, a URI consists of three parts: "content: //", data path, and Id (optional ).
For example, the following are some Uris provided by the system:
(1) content: // media/Internal/Images
(2) content: // contacts/people/2
(3) content: // contacts/people
Among them, (1) All images stored on the device will be returned; (2) the contact records with the ID 5 in the contact information will be returned; (3) all contacts on the device are returned.
Each contentresolver object uses URI as its first parameter. Uri determines which content provider contentresolver will talk.
2. Get content provider content
The Android system provides a series of content providers for some common data types (such as audio, video, image, and address book contacts. The following uses the address book contact as an example to describe how to obtain the content provider.
First, we need to run the "contacts" application in the simulator and add Contacts to it. 2.
Figure 2 Add a contact
As shown in 2, I added two contacts in the "contacts" Application: Li Ming and Wang Lei.
Then, we need to create a project of our own. The main function of this project is to get the data in the content provider that holds the contact information. Here, I define a textview control in the layout file to display the obtained contact data, as shown in effect 3 after running.
Figure 3 get content provider
As shown in figure 3, the application we created does obtain data (ID and name fields) from the "contacts" application. Of course, if you need, you can obtain more field information in Figure 1.
The followingCodeA solution is provided to implement this function.
1 /* 2 * Function: obtains the contact list. 3 * Author: blog Park-still indifferent 4 */ 5 Public String getresult (){ 6 7 String result = "" ; 8 Uri uri = URI. parse ("content: // contacts/People "); // Uri of the contact content provider 9 String [] Columns = {People. _ id, people. name }; // Contact ID and name 10 11 Contentresolver = getcontentresolver (); // Get contentresolver object 12 Cursor cursor = contentresolver. Query (Uri, columns, Null , Null , Null ); // Query content provider 13 Int Peopleid = cursor. getcolumnindex (people. _ id ); // Obtain the column index of the ID field 14 Int Peoplename = cursor. getcolumnindex (people. Name ); // Obtain the column index of the Name field 15 16 // Traverse cursor objects and extract data 17 For (Cursor. movetofirst ();(! Cursor. isafterlast (); cursor. movetonext ()){ 18 Result = Result + cursor. getstring (peopleid) + "\ t"; 19 Result = Result + cursor. getstring (peoplename) + "\ t \ n" ; 20 } 21 Cursor. Close (); 22 Return Result; 23 }
The code above shows that to obtain the content of the content provider, we need to know the URI of the content provider and the data storage form (field name and field type) of the content provider ). Then, we can query the content provider by using the query () method of the contentresolver object, the query results must be stored using the cursor object (for more information about the cursor, see Android study note 36: Using SQLite to store data ). Finally, traverse the cursor object and retrieve the information of each field.
Because the application needs to access the contact information, you also need to add the corresponding permission to the androidmanifest. xml file, as shown below:
<Uses-PermissionAndroid: Name= "Android. Permission. read_contacts"/>
So far, we have completed the function of getting the content of the contact content provider.
3. Provide content provider content
The preceding section describes how to obtain content providers from other applications. How to provide content providers in your own applications for access by other applications?
In general, there are two ways to allow your data to be accessed by other applications: Create your own content provider (that is, inherit from the content provider subclass ), or add your data to the existing content provider. Adding your data to the existing content provider has some limitations, because you must ensure that your data is of the same type as the existing content provider, and has the write permission for this content provider.
The following describes how to create a content provider in three steps.
3.1 establish a data storage system
Obviously, to share data in your applications with others, you must establish your own data storage system. Of course, the developer determines the storage system (such as the file storage system and SQLite database.
In Android study note 36: Using SQLite to store data, we have built a simple SQLite database system. In this database, a table with three fields (studentid, studentname, and studentage) is created to store student information.
Here, we will take this project as an example to explain how to share the student information in this project through the content provider method.
3.2 extended content provider class
In this project, we need to create a class that inherits from contentprovider. The data to be shared is encapsulated and displayed as contentresolver objects and cursor objects that can be accessed. Here, I name this class "studentcontentprovider ".
The contentprovider class provides six Abstract METHODS:
(1) Public abstract cursor query (URI Uri, string [] projection, string selection, string [] selectionargs, string sortorder );
(2) public abstract URI insert (URI Uri, contentvalues values );
(3) Public abstract int Update (URI Uri, contentvalues values, string selection, string [] selectionargs );
(4) Public abstract int Delete (URI Uri, string selection, string [] selectionargs );
(5) public abstract string GetType (URI );
(6) Public Abstract Boolean oncreate ();
The query () method is used to return the queried data in the form of a cursor object. The insert () method is used to insert a new data record to the content provider, the second contentvalues object in this method indicates the ing between the column name and column value of the data record; the update () method is used to update the existing data record in the content provider; Delete () the method is used to delete data records from the content provider. The GetType () method is used to return the (MIME) type of data in the content provider. The oncreate () method is called when the content provider starts.
The above six methods will be called in the contentresolver object, so good implementation of these abstract methods will provide a perfect external interface for contentresolver.
Of course, you can choose to implement the above six methods based on your application's needs. For example, you can only implement the query () method, in this way, other applications can query the content provider you provide, but cannot add or delete the content provider you provide, thus ensuring data security.
The following code implements the query () method.
1 /* 2 * Function: Query Method 3 * Author: blog Park-still indifferent 4 */ 5 Public Cursor query (URI Uri, string [] projection, string selection, string [] selectionargs, string sortorder ){ 6 DB = Mysqliteopenhelper. getwritabledatabase (); 7 Cursor cursor = dB. Query ("tab_student", projection, selection, selectionargs, Null ,Null , Sortorder ); 8 Return Cursor; 9 }
We can see that the core of the query is to call the query () method provided by the sqlitedatabase class, store the query results in the cursor object, and then directly return the cursor object.
In addition, in the "studentcontentprovider" inherited from the contentprovider class, we also need to do a very important thing, that is, specify the content provider Uri. The URI must be unique and cannot be the same as the system Uri, and cannot be the same as the URI of the content provider provided by other applications.
Here I define the URI of the content provider as "content: // com. example. SQLite. studentprovider/student ".
3.3 declare the permissions of the content provider
The created content provider must be declared in the androidmanifest. xml file of the application. Otherwise, the content provider is invisible to the Android system.
The specific declaration method is as follows:
1
declare the content provider --> 2 provider
Android: Name =" com. example. android_datastorage_sqlite.provider.studentcontentprovider " 3 Android: authorities = "com. example. SQLite. studentprovider " > 4 provider >
The <provider> </provider> label is located under the <Application> </Application> label. The Android: Name attribute specifies the full name of the studentcontentprovider class name. The Android: authorities attribute uniquely identifies a content provider.
So far, we have created our own content provider in this project and provided the query () method for other applications to query the SQLite data table in this project.
3.4 Verification
3 records are added to the SQLite data table of the application android_datastorage_sqlite, as shown in figure 4.
Figure 4 SQLite data table information
Create an application android_datastorage_contentproviders to obtain the custom content provider content. The method for getting custom content provider content is similar to the method for getting the content provider content of the Contact application described earlier. Use the URI of the custom content provider and query the corresponding fields in the data table. The queried information is shown in Figure 5.
Figure 5 query custom content provider content
We can see that in the application android_datastorage_contentproviders, the data table information in the application android_datastorage_sqlite is indeed accessed, and the data sharing between applications is realized through the content provider method.