Createing a content provider:
Http://developer.android.com/guide/topics/providers/content-provider-creating.html#:android 4.0 R1 translator's signature: rongqi fan Translator link:
-
Createing a content provider
The Content Manager manages access to data. You can use one or more classes and elements in the manifest file to implement a provider. You can use a class to implement the provider that communicates with other applications. It is a subclass of contentprovider. Although the provider makes the data available for the application, you also need an activity to allow the user to query and modify the data managed by the provider.
The following are the basic steps for creating a provider and the APIs to be used.
Directory [Hide]
- 1
Before Building
- 2
Design Data Storage
- 3
Data design considerations
- 4
Design Content: Uris
- 5
Implement content provider class
- 6
Implement content provider MIME type
- 7
Implement a contract
- 8
Implement content provider Permissions
- 9
Intent and data access
|
Before Building
Before building a provider, do the following:
1. Determine whether a provider is required.Consider the following features:
You want to provide complex data or files to other applications. You want to allow users to copy complex data to other applications. You want to provide customized search recommendations through the search framework.
If the user does not interact with other applications, you do not need to use the provider to operate the SQLite database.
2. If you are not clear about the basic knowledge of the provider, read content provider basics first.
Next, follow these steps to build your provider:
1. Design raw data storage for your data. The provider provides data in two ways:
File data
Data usually needs to be written into files, such as images, audios, and videos. Files are stored in the private space of your application. In response to requests from other programs, the provider provides the file handle.
"Struct" Data
Data is usually stored in databases, arrays, and similar structures. Store data in the form of table-compatible columns. A row represents an entity, such as a person or an item in stock. The column represents the data of this entity, such as the price of the person name and item. It is usually stored in the SQLite database, but you can use any storage type. For more information about the data types supported by Android, see designing data storage.
2. define the specific implementation and required functions of contentprovider. This class is your data and Android system interface. For more information, see Implementing the contentprovider class.
3. Define the provider's permission string, content Uris, and column name. If you want the provider to process intent, define intent behavior, and expand data and flag. Define data access permissions. You need to define these values as constants in a separate contract class, and then expose this class to other developers. For more information about the content Uris, see the designing content Uris. For more information about intent, see intents and data access ..
4. other options, such as simple data or abstractthreadedsyncadapter that can provide asynchronous data (communication between the provider and cloud-based data.
Design Data Storage
A provider is an interface that stores data in the structure. Before you create an interface, you decide how to store data. You can store them in any form and design the read/write interfaces as needed.
Data storage technology available in Android:
The Android system contains the SQLite database API, which is used by Android providers to store table-oriented data. The sqliteopenhelper class helps you create databases. The sqlitedatabase class is the base class for accessing databases.
You do not need to use a database to store your data. The provider's external performance is similar to a relational database, which is a set of tables, but this is not necessary for the internal implementation of the provider.
To store file data, Android has a series of file-oriented APIs. For more information, see. If the provider you designed needs to process media files such as music and video, you need a provider that combines table data and files.
To process network-based data, use classes in java.net and android.net. You can synchronize network-based data to local data storage, such as databases, and provide data in the form of tables or files. The sample sync adapter is a simple example of this synchronization type.
Data design considerations
Some tips about designing the provider's data structure:
Table data requires a "primary key" column, and the provider maintains a unique value for each row. You can use this value to contact related rows of other tables (as a "foreign key "). Although you can give this column any name, it is best to call it basecolumns. _ id. Because, to provide the query result of the provider to a listview, You need to obtain a column named _ id.
If you want to provide bitmap files or other large file-oriented data, store the data in a file and provide it directly instead of using tables. If you do, you need to inform your users that they need to use the contentresolver file function to access data.
Use the Binary Large Object (BLOB) data type to store data with size changes or data structure changes. For example, a blob column is used to store a protocol buffer or JSON structure.
You can use blob to implement a table in standalone mode. For this type of table, you define a column as the primary key, a MIME type column, and other columns as blob. The significance of the data in the Blob column is specified by the mime column. In this way, you can store different data types in the same table. The contactscontract. Data Table of the Contract provider is an example of an independent mode.
Design Content: Uris
A content URI is the URI of the data identified by the provider. The content URI contains the symbolic name of the object provider (its permissions) and the name of a table or file (a path. The optional ID points to a row in the table. Each data access function in contentprovider has a content URI as the parameter. You can decide to access tables, rows, and files.
The Uris content is described in content provider basics.
Design a permissionThe provider has a single permission as its internal name in Android. To avoid conflicts with other providers, you use the network domain name permission (reverse) as the provider's permission. This suggestion is always effective for the android package name. You can define the provider permission as an extension of the package name. For example, if your android package name is com. example. <appname>, your provider's permission can be com. example. <appname>. provider.
Design a path StructureDevelopers usually create the URL from the permission and append the URL to a single table. For example, you have two tables: tablestable1 and Table2. You have merged the permissions from the previous example to generate the content Uris COM. example. <appname>. provider/Table1 and COM. example. <appname>. provider/Table2.
IDs for processing content URIAccording to the Conventions, the provider provides a URI with a row ID to access a single row. This ID is at the end of the URI. The provider matches the id value with the table _ id to execute an access request for the matched row.
This Convention facilitates the design of a general design pattern for the access provider. The application queries data from the provider and uses cursoradapter to display cursor in the listview. The definition of cursoradapter requires that one row in cursor be _ id.
Click a row to view or modify the data. The application obtains the response from listview to cursor, obtains the _ id value for this line, attaches it to the content Uri, and sends it to the Creator. The provider queries or modifies extended rows.
Content URI ModeTo help you select an operation method for a content Uri, the provider's API contains a class that maps the content Uri "Mode" to an integer. You can use integer numbers in the statement to select the matching mode of the content URI or Uris.
A content URI pattern matches the content URIs with wide characters:
*: Match strings of any value or length. #: Match a numeric string of any length.
An example of Uri processing of design and encoding content, consider a provider with the com. example. App. provider permission, and acknowledge that the following content Uris points to the table:
content://com.example.app.provider/table1: A table called table1.content://com.example.app.provider/table2/dataset1: A table called dataset1.content://com.example.app.provider/table2/dataset2: A table called dataset2.content://com.example.app.provider/table3: A table called table3.
The provider also identifies the row ID appended to the content Uris. For example, content: // com. example. App. provider/table3/1 indicates Row 1 in table 3. The following content URI mode is acceptable:
Content: // com. example. App. provider/* matches any content URI of the provider. Content: // com. example. App. provider/Table2/* matches the content URI of dataset1 and dataset2, and does not match the content URI of Table1 or table3. Content: // COM. example. app. provider/table3/# match the URI of a single row in table 3, such as content: // COM. example. app. provider/table3/6 indicates Row 6. The following code snippet shows how urimatcher functions work. The Uris of the code processing object table is different from the URI of a single row. It uses content: // <authority>/<path> mode to process the table. content: // <authority>/<path>/<ID> process a single row.
The adduri () function maps permissions and paths to an integer. The function returns the integer number of a URI. A switch statement is used to query object items and query a single record:
There is code here, and no code has been addedFor other classes, contenturis provides a function to process the ID of the content Uri. Class Uri and Uri. Builder include parsing existing URI classes and building a new one.
Implement content provider class
The contentprovider instance manages other application requests and accesses structured datasets. The essence of all access forms is to call contentresolver and call the specific functions of contentprovider for access.
Request functionYou need to implement six Abstract Functions Defined by the abstract class contentprovider In the subclass. Among these functions, except oncreate (), other applications call functions to access your provider.
Query () obtains data from the provider. You can use parameters to select the queried table, return rows or columns, and sort the results. Returns data in the form of an object cursor.
Insert () inserts a new row into the provider. Use parameters to select a table and obtain the column values used. Returns the content URI of a newly inserted row.
Update () updates existing rows. Use the parameter to select a table and update rows to obtain the updated column value. Returns the number of updated rows.
Delete () deletes a row. Use parameters to delete tables and rows. Returns the number of rows to be deleted.
GetType () returns the MIME type of the provider content. The function is described in the implementing content provider MIME types section.
Oncreate () initializes the provider. The Android system calls this function immediately after creating the provider. Note that the provider does not create a contentresolver object until it is accessed.
Note: These functions have the same signature as the contentresolver function with the same name.
When you implement these functions, consider the following:
In addition to oncreate (), these functions require thread security. Multi-threaded knowledge, read processes and threads.
Avoid long-time operations in oncreate. Wait until the initialization task is needed. Read implementing the oncreate () method section.
Even if you need to implement these functions, your code can do nothing. For example, if you want to prevent other programs from inserting data, you can ignore the insert () function and return a 0 value.
Query ()
The contentprovider. Query () function must return a cursor object. An exception is thrown unless execution fails. If you use the SQLite database to store data, you can use the sqlitedatabase function query () to return the cursor object. If no matching row exists, a cursor instance is returned, and its getcount () function returns 0. If an internal error occurs in the query, null is returned.
If you do not need data inventory data, you can use a subclass of the cursor class. For example, the matrixcursor class implements an array object for row data. Use addrow () to add a new row.
The Android system can use exceptions for inter-process communication. The following exceptions are useful when Android processes query errors.
Illegalargumentexception if your provider receives an invalid Content Uri and throws this exception)
Nullpointerexception
Implement the insert () function
The insert () function adds rows to an appropriate table and sets values in the contentvalues parameter. If there is no row name in contentvalues, the provider uses the default value in the code or database framework.
This function returns the content URI of the new row. Use the withappendedid () function to append the _ ID (or another primary key) of the new row to the table content Uri.
Implement the delete () function
The Delete () function does not physically delete a row. If you use a synchronization adapter, You need to mark the deleted row as "delete" instead of removing the row entity. The synchronization adapter checks the deleted rows and removes them from the service before the provider deletes them.
Implement the update () function
The Update () function uses the same contentvalues parameters as the insert () function, and the same selection and selectionargs parameters as the delete () and contentprovider. Query () functions. This allows you to use the same code before these functions.
Implement the oncreate () function
The Android system calls oncreate () when the provider starts (). You need to initialize the function quickly, delay database creation and data loading until the provider receives the data request. If you perform a long task in oncreate (), the startup of the provider will be slowed down. This slows down the response to other applications.
For example, you can create a new sqliteopenhelper object in the contentprovider. oncreate () function to use the database and create a table when opening the database. In this case, you call getwritabledatabase () for the first time and automatically call the sqliteopenhelper. oncreate () function ().
The following code calls the contentprovider. oncreate () and sqliteopenhelper. oncreate () functions. The first section implements contentprovider. oncreate ():
There is code here, and no code has been added
The following code implements sqliteopenhelper. oncreate (), including a help class:
There is code here, and no code has been added
Implement content provider MIME type
The contentprovider class has two functions that return the MIME type:
GetType () The request function you need to implement.
Getstreamtypes () If your provider provides files, you need to implement this function.
Mime Type of the tableThe GetType () function returns a mime-formatted string that describes the data type returned by the URI parameter. The URI parameter can be a mode or a specified URI. In this case, you can return the Data Type of the mode that matches the content Uri.
The common data types include text, HTML, JPEG, and GetType (). The standard MIME type is returned. The standard type of information is on the website: IANA mime media types.
The URL that points to the row or table data. The function returns the android MIME type specified by the supplier in the MIME format:
Type part: VND
Child type; Android. cursor. Item/
If the URI is a single row: Android. cursor. DIR/
If the URI is multiline: the specified part of the provider: VND. <Name>. <type>
You provide <Name> and <type>. The <Name> value must be globally unique, and the <type> value is unique in Uri mode. A good choice for <Name> is your company name or a part of the application package name. <Type> A good choice is the string indicating the connected Uri.
For example, if the permission of a provider is com. example. App. provider, its table name is Table1, And the MIME type of multiple rows in intable1 table is:
vnd.android.cursor.dir/vnd.com.example.provider.table1
Single Row in table 1. The MIME type is:
vnd.android.cursor.item/vnd.com.example.provider.table1
Object MIME type
If your provider Supports files, implement the getstreamtypes () function (). This function returns a string of the MIME type of the stationery store. Your provider can return a specified content Uri. You can filter MIME types by filtering parameters of the MIME type. You can return the MIME types to be processed by the client.
For example, the Provider supports. jpg,. PNG, And. GIF image files. The application uses the filter string image/* (an "image") to call contentresolver. getstreamtypes (). The contentprovider. getstreamtypes () function returns the following array:
{ "image/jpeg", "image/png", "image/gif"}
If the application only needs a file. jpg, it uses the filter string * \/JPEG when calling contentresolver. getstreamtypes.
The contentprovider. getstreamtypes () function returns:
{"image/jpeg"}
The provider does not support filtering any mime-type files in the string. The getstreamtypes () function returns NULL.
Implement a contract
A contract class is a public final class that defines Uris, column name, MIME type, and other metadata constants of the modifier. Creates a contract between the provider and the application to determine whether the provider can correctly access the actual values of URIs, column names, and so on.
Contract Classes usually use semantic names to name constants to help developers, so that developers rarely mistakenly use column names or Uris. Although it is a class, it can contain documents. The integrated development environment, such as Eclipse, can automatically complete the constant name and display relevant documents.
Developers can compile class files, but they can also use file. jar for static compilation.
Example of a contract class, such as the contactscontract class and its nested class.
Implement content provider Permissions
For details about permissions and access to the Android system, see security and permissions. The Data Storage section also describes how to efficiently process the Security and permissions of different media. In short, the key points are:
By default, data is stored inside the device and private to applications and providers.
The sqlitedatabase you created is private to the provider and application.
By default, data is stored in external media. Files are public and globally readable. You cannot use providers to restrict access to files, because other applications can use APIs to read and write files.
By default, functions that open or create files and databases on the internal storage medium of the device have read and write permissions for other applications. If you use internal files or databases as the provider's permissions, you can grant them the "Global read" and "global write" permissions, the permissions set in the provider's manifest file do not protect your data. Files and databases in the internal storage media are private. You do not need to modify the permissions of your provider.
If you use a provider to control data access, you need to store data in internal files, SQLite databases, and "Cloud" (for example, remote servers ), you need to keep the data private to your provider.
Implement Permissions
All programs can read and write your provider, or even the data is private, because the provider does not have a permission set by default. Set the provider permission in the manifest file and use the <provider> label. You can set permissions for some providers, some tables, and some records.
Use one or more <permission> in the manifest file to define the permissions of the provider. Permissions are unique to your provider. The Android: Name attribute uses a Java-style scope. For example, the read permission com. example. App. provider. Permission. read_provider.
The following list describes the scope of the provider's permissions. The scope starts from the provider, and the granularity is smaller. The permission of a small granularity takes precedence over the scope of a large granularity:
The read and write permissions of a single read/write provider to the object provider are specified through the Android: Permission attribute of the <provider> element.
Separate the read/write permissions of the entity provider at the provider level. Use the Android: readpermission and Android: writepermission attributes of the <provider> element. They take precedence over permission Android: permission.
The read, write, and read/write permissions of the URL-level permission provider. Use the <provider> sub-element <path-Permission> of the element to specify. You can specify permissions for the daily content Uri, including read, write, and read/write. Read and Write Permissions take precedence over read/write permissions. The path permission takes precedence over the provider permission.
Temporary permissions allow the application to access the temporary permissions, or even the application does not have the usual access permissions. The temporary access feature can reduce the number of permissions that the program has in the manifest file. You can open temporary permissions. Only programs that require continuous access to data require "permanent" permissions.
Consider that you need to implement the permissions and Applications of an email provider. When you want to allow external image display programs to display your image attachments. Grant the access permission to the image display program and create a temporary permission for the image content Uri. Design your email program so that users can display images. The program sends an intent containing the image content Uri and permission flag to the image display program. The image display program can query your email provider and obtain images, although the image display program has no read permission.
You can set the Android: granturipermissions attribute of the <provider> element, or add one or more <grant-Uri-Permission> sub-elements to open temporary permissions. If you use temporary permissions, call the context. revokeuripermission () function when you want to remove the content URI. The URI is associated with the temporary permission.
The attribute value determines the number of access permissions of the provider. If the attribute is set to true, the system obtains the temporary permissions of your provider and reloads the provider-level or path-level permissions of any of your providers.
If the flag is set to false, you need to add the sub-element <grant-Uri-Permission> in <provider>. Each sub-element specifies the content URI for obtaining the temporary variable.
Indicates temporary access to the application. An intent must contain the flag_grant_read_uri_permission or flag_grant_write_uri_permission flag, or both. Set through the setflags () function.
If the Android: granturipermissions attribute is not set, the default value is false.
<Provider> element
Like the activity and service components, the subclass of contentprovider needs to be defined in the manifest file and the <provider> element is used.
The Android system obtains the following information:
Permission (Android: Authorities) system. The description of this attribute is in the designing content Uris section.
The Class Name of contentprovider is implemented by the provider class name (Android: name. For more information about this class, see Implementing the contentprovider class.
Permission:
Android: granturipermssions: temporary permission. Android: permission: Global read/write permissions for a single provider. Android: readpermission: Global read permission of the provider. Android: writepermission: Global write permission of the provider.
The details of permissions and attributes are described in the implementing content provider permissions. Section.
The launch and control attributes determine when and how the Android system starts the provider, processes the features of the provider, and other runtime settings:
Android: enabled: allows the system to start the provider. Android: exported: The provider used to run other applications. Android: initorder: the commands started by the provider, which are related to other providers in the same process. Android: Multiprocess: allows the system to start the provider in the same process of the same client. Android: Process: process name of the running provider. Android: syncable: identifies the provider's data and server synchronization.
The <provider> element in the developer documentation has a detailed description.
Information attributes
Optional icons and labels of the provider:
Android: icon: indicates the paint icon resource of the provider. Insettings> apps> all are under the provider tag of the program list. Android: Label: the label that describes the information of the provider or data. In the tag of the program list.
The details of all attributes are in the <provider> element of the developer documentation.
Intent and data access
The program accesses the content provider through intent. Functions that are not used by the program. It sends an intent to start the activity, which is part of the program. The target activity obtains or displays data. Intent-dependent behavior. The target activity also prompts the user to modify the data. An intent will also contain "extended" data, and the activity will display them on the UI. The user chooses to change the data before modifying the data.
You want to use intent to determine the dataset. Your provider depends on data insertion, update, and deletion records to strictly define business logic. In this case, your program can directly modify the data, which will lead to illegal data. If you want developers to use intent access, Please carefully describe it. This is why intent uses the program UI better than trying to modify data in the code.
Processing input intent to modify data is no different from processing other intent. Learn how to use intent. You can read intents and intent filters.
From "http://wikidroid.sinaapp.com/%e5%88%9b%e5%bb%bacontent_provider"