Android — Content Providers
A content provider component supplies data from one application to others on request. Such requests are handled by the methods of the ContentResolver class. A content provider can use different ways to store its data and the data can be stored in a database, in files, or even over a network.
ContentProvider
sometimes it is required to share data across applications. This is where content providers become very useful.
Content providers let you centralize content in one place and have many different applications access it as needed. A content provider behaves very much like a database where you can query it, edit its content, as well as add or delete content using insert(), update(), delete(), and query() methods. In most cases this data is stored in an SQlite database.
A content provider is implemented as a subclass of ContentProvider class and must implement a standard set of APIs that enable other applications to perform transactions.
Content URIs
To query a content provider, you specify the query string in the form of a URI which has following format −
Here is the detail of various parts of the URI −
Sr.No | Part & Description | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 |
Step | Description |
---|---|
1 | You will use Android StudioIDE to create an Android application and name it as My Application under a package com.example.MyApplication, with blank Activity. |
2 | Modify main activity file MainActivity.java to add two new methods onClickAddName() and onClickRetrieveStudents(). |
3 | Create a new java file called StudentsProvider.java under the package com.example.MyApplication to define your actual provider and associated methods. |
4 | Register your content provider in your AndroidManifest.xml file using tag |
5 | Modify the default content of res/layout/activity_main.xml file to include a small GUI to add students records. |
6 | No need to change string.xml.Android studio take care of string.xml file. |
7 | Run the application to launch Android emulator and verify the result of the changes done in the application. |
Following is the content of the modified main activity file src/com.example.MyApplication/MainActivity.java. This file can include each of the fundamental life cycle methods. We have added two new methods onClickAddName() and onClickRetrieveStudents() to handle user interaction with the application.
Create new file StudentsProvider.java under com.example.MyApplication package and following is the content of src/com.example.MyApplication/StudentsProvider.java −
Following will the modified content of AndroidManifest.xml file. Here we have added
tag to include our content provider:
Following will be the content of res/layout/activity_main.xml file−
Make sure you have following content of res/values/strings.xml file:
Let’s try to run our modified My Application application we just created. I assume you had created your AVD while doing environment set-up. To run the app from Android Studio IDE, open one of your project’s activity files and click Run icon from the tool bar. Android Studio installs the app on your AVD and starts it and if everything is fine with your set-up and application, it will display following Emulator window, be patience because it may take sometime based on your computer speed −
Now let’s enter student Name and Grade and finally click on Add Name button, this will add student record in the database and will flash a message at the bottom showing ContentProvider URI along with record number added in the database. This operation makes use of our insert() method. Let’s repeat this process to add few more students in the database of our content provider.
Once you are done with adding records in the database, now its time to ask ContentProvider to give us those records back, so let’s click Retrieve Students button which will fetch and display all the records one by one which is as per our the implementation of our query() method.
You can write activities against update and delete operations by providing callback functions in MainActivity.java file and then modify user interface to have buttons for update and deleted operations in the same way as we have done for add and read operations.
This way you can use existing Content Provider like Address Book or you can use Content Provider concept in developing nice database oriented applications where you can perform all sort of database operations like read, write, update and delete as explained above in the example.
Источник
Using Android’s Content Providers to Manage App Data
In my last article, I created an Android Todo App, which is a more advanced version of the classic вЂHello World’ application for mobile development. In that article, I introduced building views for Android, assigning methods (functions) to events such as button clicks, and using the embedded SQLite database to store, retrieve and delete data (tasks).
In that tutorial, I had to write SQL queries to achieve this, but there is a simpler way, Content Providers.
Providing Content for Android
Content providers are a simpler way to manage the data stored in the embedded SQLite database. They are a standard interface that connects data in one process with code running in another process. They might seem hard to understand or implement, they are not. In this tutorial, I will show you how to create your own content provider.
You don’t need to develop your own provider if you don’t intend to share your data with other applications. However, you do need your own provider to provide custom search suggestions in your own application. You also need your own provider if you want to copy and paste complex data or files from your application to other applications.
To start following the tutorial, download the current repo of the project from GitHub and import it into your IDE.
Before writing the content provider class, we have to add some code to the TaskContract class. Add the code below the existing variable declarations in the class:
The code is nothing but a list of static constants ( final variables) containing necessary information. Firstly, I chose an authority for the content provider. Normally, this would be .provider , but you can choose anything as long as you are sure it won’t conflict any other app.
After the authority, a content URI is set to content://com.example.TodoList.mytasks/tasks (with tasks being the TABLE ). This content URI should always start with content:// and is used to access the data in the table. If you will use more than one table, you can use the same structure as above, though you have to change the table name.
CONTENT_TYPE and CONTENT_TYPE_ITEM are used to identify if a URI requested points to a directory (i.e. table) or to an item (i.e. record in the table).
We also need to add the content provider to the AndroidManifest.xml file, add the following code:
Just before the closing application tag.
Now that the contract is ready, we can create the content provider.
Creating a provider
A content provider is a simple Java class that extends the ContentProvider class and implements its methods.
Our content provider will be called TaskProvider , and will be placed in the db package. To do this, create a new class file inside the db folder called TaskProvider.java and add the following code:
At this moment, this class doesn’t do much. It is a content provider, but it doesn’t provide any content, since the methods are not yet implemented. All it does is create a UriMatcher instance which will then be used to check if the URI accessed is valid or not. In a static block two URIs are added to the UriMatcher , the URI corresponding to the table and the URI corresponding to the record.
Let’s implement the onCreate() method. The Android system calls this method immediately after it creates the provider. This means that it should be kept as simple as possible, since we don’t want the system to make too many calculations when the provider is created. Put this code into the onCreate() method in the class we just created:
In this method, the TaskDBHelper class is used to create a helper object which creates the database if it does not already exist. This method would return false if the provider won’t be loaded because the database is not accessible, otherwise would return true. This simple code is more than enough to create our Content Provider.
Now let’s add the query() functionality, which is used to retrieve the data stored in the database and return a Cursor instance:
The query() method should return a Cursor instance, or throw an exception if there is any problem with querying.
In the method above, a SQLiteQueryBuilder instance is used to help creating the query. If the object requested (by the URI) is a record (an item, not a list/table), the SQLiteQueryBuilder uses the appendWhere() method to add the WHERE clause to the query. In the end, a Cursor instance is created by executing the query created by query builder, which is then returned by the method. If the URI requested is invalid, an IllegalArgumentException is thrown.
After adding the query() method, we are going to implement the insert() method, which adds some values stored in a ContentValues instance as a new record in a table:
This method receives two arguments, the URI where the records are going to be inserted and the values that are going to make up the record. If the URI doesn’t matches the URI of the table, then an IllegalArgumentException is thrown. If the URI is correct, then the insert() method of a SQLiteDatabase instance is used to insert the data into the proper table. This insert() method returns the URI of the new record. This is done if the id is greater than 0 (which means that the record is added at the table), and the new URI is created by using the withAppendedId() method. If the id is not greater than 0, it means the record is not stored, so an SQLException is thrown.
Now let’s move on to another method, the update() method. This method is used to change (i.e. update) an existing record of a given table in the SQLite database:
This method takes four parameters:
- Uri uri : The URI to query. It can be the URI of a single record, or the URI of a table.
- ContentValues contentValues : A set of key-value pairs, with the column name as a key and the values to update as values.
- String s : A selection to match the rows which are going to be updated.
- String[] strings : The arguments of the above rows.
Using this method, we initially check if the URI corresponds to a table or to a record. If it corresponds to a table, we call the update() method to an SQLiteDatabase instance, passing the same parameters as our method (except for the URI, which is changed to the table name).
If the URI corresponds to a record, we have to change the third parameter to match the id required to the ID of the record in the database, and add any selection that the user required.
Finally, the update() record is called to the SQLiteDatabase instance, passing the table name, content values, our where clause, and the last argument.
This method would return the number of rows updated, or throw an IllegalArgumentException if the URI passed is not correct.
The next method is delete() . You will notice that this method is not that different from the update() method implemented above:
Just like the update() method, the delete() method checks if the URI passed corresponds to a table and if so, it deletes the table. If it corresponds to a record, it deletes that record from the table. In the latter case, we make sure to add a clause for the id to the selection parameter.
As above, the delete() method would return the number of deleted rows, or throw an IllegalArgumentException if the URI is invalid.
To finalize our TaskProvider class, we have to implement the last method, the getType() method. This method will tell if an URI passed corresponds to a table, to a record, or is invalid. This method is simply:
Use your own provider
In order to use our new Content Provider, we need to open MainActivity.java and change some of its code.
Go to the updateUI() method and we will change the method of querying the data from the database. Remove this piece of code:
And replace it with:
For deleting tasks, remove the following code from onDoneButtonClick() method:
And replace it with this:
Now you can delete tasks using the content provider created, without needing any SQL queries.
Finally, we need to insert new tasks using the insert() method we created. Find the onOptionsItemSelected() method and replace following code:
Now the values will be added to the database using the insert() method we created earlier.
Conclusion
As you can see, Content Providers are not hard, especially after trying them in a few projects.
I hope this guide gave you a good insight on Android Content Providers, their implementation and their usage. You can find the source code of this tutorial on Github.
Источник