As my work grew longer and longer, I felt that I had learned too slowly. I had been away for nine months in the past two years and I was still confused about a lot of knowledge, I still don't fully understand JAVA. Now I have a little time to read something that I am interested in. I don't know how long it will last, but I have to grasp every point.
As my work grew longer and longer, I felt that I had learned too slowly. I had been away for nine months in the past two years and I was still confused about a lot of knowledge, I still don't fully understand JAVA. Now I have a little time to read something that I am interested in. I don't know how long it will last, but I have to grasp every point.
As my work grew longer and longer, I felt that I had learned too slowly. I had been away for nine months in the past two years and I was still confused about a lot of knowledge, I still don't have a thorough understanding of JAVA. Now I have a little time to read something that I am interested in. I don't know how long it will last, but seize every minute you can use to make yourself powerful. One day, you will become the person you want to be. Remember, you will always be the best!
1. ContentProvider database sharing-Overview
2. ContentProvider database sharing-instance description
3. ContentProvider database sharing-MIME type and getType ()
4. ContentProvider database sharing-read and write permissions and data listening
After the first three articles, I think you have a lot of knowledge about ContentProvider, but in the second article, we mentioned a function:
getContentResolver().notifyChange(uri, null);
This function is used to notify third-party applications when data in the database is changed. In this article, let's take a look at the database change notifications related to third-party monitoring;
Before that, you have a ContentProvider that shares the read and write permissions of the database;
I. Database read and write permissions 1. Overview
Let's take a look at the following code:
Pay special attention to the following parameters in this Code:
- Exported:This attribute is used to indicate whether the service can be called or interacted with other application components. The value is (true | false). If it is set to true, the service can be called or interacted, otherwise, no. If it is set to false, only components of the same application or applications with the same user ID can start or bind the service. For details, see Permission Denial: Meanings of android: exported properties hidden by opening provider.
- ReadPermission:The required permission to use the query function of Content Provider, that is, the permission to use the query () function in ContentProvider;
- WritePermission:The permissions required to use the ContentProvider modification function, that is, the permissions to use the insert (), update (), delete () functions of ContentProvider;
- Permission:The name of the permission required for the client to read and write data in the Content Provider. This attribute provides a quick way to set read and write permissions at one time. However, the readPermission and writePermission attributes take precedence over this setting. If the readPermission attribute is set at the same time, it controls the reading of the Content Provider. If the writePermission attribute is set, it also controls the modification to the Content Provider data. That is to say, if only the permission is set, the application with this permission can read and write the ContentProvider here. If both permission and readPermission are set, the application with readPermission permission can read, only users with permission can write data! That is to say, only the permission is not readable, because readPermission has a higher priority than permission. If readPermission, writePermission, and permission are set at the same time, the permission is invalid.
2. instance (1) User-Defined Permissions
For example, here we define a readPermission string. it is meaningless to simply write a string, because all permissions of the system are required, the String system cannot identify a String that has not been applied for. That is to say, anyone who comes in will be blocked!
In this way, our permission will be registered in the system and used in third-party applications.
For more information about custom permissions, see declare, use, and customize permissions.
(2) ContentProvder instance with Permissions
First, apply for two permissions from the system in ContentProviderBlog:
Corresponding to the read and write permissions for the database respectively
Scenario 1: Use read/write permissions
Then in the provider, we use the read and write permissions at the same time:
In this case, you can use a third-party application to apply for these two permissions at the same time to read and write the database, that is:
Case 2: Add read permission only
If we only add the read-Sharing database permission to the provider, how can a third party apply for the permission to read and write the database?
We can see from the above that we only added readPermission, and the third-party application can write the database without applying for any permissions, but the permission is required when reading the database; to read the database, add the following permission statement:
(3) effect:
In the instance code, the read and write permissions are added to the provider, but only the read permissions are added to the third-party APP: UseProvider, therefore, when using URI to read the shared database, the result is normal, but when writing the database, the permission-denied error will be thrown. If you do not need to try... catch... the result is as follows:
- An exception is thrown during insert (), delete (), or update () operations.
The source code is provided at the bottom of the article.
Ii. Data Monitoring 1. monitoring steps
To listen for database changes on a specified URI, the listener must take two steps:
(1) generate a class derived from ContentObserver
public class DataBaseObserver extends ContentObserver { public DataBaseObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); Log.d("harvic","received first database changed"); }}Note that an onChange () method will be automatically generated here, And the onChange () method will be run when there is a change, so we will create a LOG here, pay attention to the LOG Content: "Stored Ed first database changed". Obviously, I only use DataBaseObserver to listen to "content: // com. harvic. provider. peopleContentProvider/frist
(2) Registration and anti-registration listening
Before using URI to operate third-party data, register ContentObserver first. Here we register in the OnCreate () function of MainActivity:
Private DataBaseObserver observer; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); observer = new DataBaseObserver (new Handler (); // register the specified URI change listener getContentResolver (). registerContentObserver (CONTENT_URI_FIRST, true, observer );}The complete process is finished here, and the parameters of registerContentObserver () will be discussed later.
- When OnDestory () is used, anti-registration:
@ Overrideprotected void onDestroy () {super. onDestroy (); // cancel listening to getContentResolver (). unregisterContentObserver (observer );}
(3) Database Change Notification in ContentProvider
When database data changes are specified on the URI in ContentProvider, use the following function to notify you of the changes.
getContext().getContentResolver().notifyChange(uri, null);
This function is the notification function we mentioned in the second article;
Now, we have finished the Database Change Notification and listening process. Let's take a look at the usage of registerContentObserver () to register the listening function:
public final void registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)
Function: registers a ContentObserver derived class instance for the specified Uri. When the ** given ** Uri changes, the instance object is called back for processing.
Parameters:
- Uri:Uri to be observed
- Policyfordescendents:If it is set to false, it indicates exact match, that is, only the Uri is matched. If it is set to true, it indicates that the derived Uri can be matched at the same time.
For example: assume that the Uri registered in UriMatcher has the following types:
1. content: // com. qin. cb/student (student)
2. content: // com. qin. cb/student /#
3. content: // com. qin. cb/student/schoolchild (elementary school student, derived Uri)
Suppose the Uri we need to observe is content: // com. qin. cb/student. If the data change Uri is content: // com. qin. cb/student/schoolchild; When policyfordescendents is false, the ContentObserver cannot listen, but when policyfordescendents is true, the database changes of the Uri can be captured.
- Observer:ContentObserver derived class instance
2. Results
When the database changes, the following message is received:
Well, this is the end, and the usage of ContentProvider is also finished;
Source code is at the bottom of the article
Iii. Supplement: SetProjectionMap -- projection ing
In the above example, the name of the database column we provide is the same as that used internally, but it is easy for the other party to know the structure of our database. If you want to use a local column name, provide an external set of corresponding column names so that no one else can guess our column names. To solve this problem, the SQLiteQueryBuilder class provides internal and external column name ing functions, to allow ing between external and internal column names.
The main function used is setProjectionMap (HashMap map)
The usage is as follows:
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();Map projectionMap = new HashMap
();projectionMap.put("out_column_name_1","inside_column_name_1");projectionMap.put("out_column_name_2","inside_column_name_2");projectionMap.put("out_column_name_3","inside_column_name_3");queryBuilder.setTables(DatabaseHelper.TABLE_FIRST_NAME);queryBuilder.setProjectionMap(projectionMap);
As it is post-event supplementary knowledge, we will give you an example here for reference. You can try it on your own.
I would like to thank the following wonderful articles for their reference materials and inspiration:
1. android ContentProvider Usage Details (great)
2. Details of android ContentProvider and Uri
3. Android breakthrough Note 5: details about ContentProvider and Uri
4. Exploring details of custom ContentProvider
5. Explanation of android ContentResolver
6. Understanding of MIME types and contentprovidergetType () methods in android
7. Usage and understanding of getType (Uri uri) in ContentProvider
8. Does the getType method of ContentProvider need to be overwritten?
9. Understanding of getType (Uri uri) and android. intent. category. DEFAULT in ContentProvider (great)
10. Understanding of gettype () and MIME types in ContentProvider
11. Monitoring database changes-policychange
12. Android monitors data changes in ContentProvider
13. whether the value of the Android listening database changes
14. Permission Denial: the meaning of the android: exported attribute hidden by opening provider
15. Content Provider Permissions
The source code comes. The source code content:
1. Part 1: Database Read and Write Permissions
2. Part 2: Data Monitoring (delete the read/write permission code and only listen to the relevant code)
If this article helps you, remember to pay attention to it;
Source code: http://download.csdn.net/detail/harvic880925/8535963
Http://blog.csdn.net/harvic880925/article/details/44651967 thank you!