Implementation of the Data Sharing Mechanism in Android-from entry to entry-level proficiency in ContentProvider applications

Source: Internet
Author: User
The Content Provider in Android can share data among multiple applications with permission permits. Android also provides some major data types, such as audio, video, images, and private address book. Of course, if we want to make our application's data public accessible to other applications, we can implement our own ContentProvider class. One type of ContentProvider only allows one instance, but it can communicate with multiple contentresolvers of different applications or processes. The interaction between processes is completed by ContentResolver and ContentProvider. We can use the getContentResolver () method to obtain the ContentResolver object. Data Model: ContentProvider is exposed as a data table. each row of data has a unique _ ID value. Each time you query data, a Cursor object is returned. However, before using the Cursor object to obtain data, you must first know the data type. Android uses URIs to locate various resources. Each resource that can be called has a unique URI, slice, video, and so on. Similarly, each table in ContentProvider has a unique URI. The Uris provided by ContentProvider start with content. URI is used in all ContentProvider interactions. In addition, the first parameter of each ContentResolver method is URI, which tells the ContentProvider object to be accessed by the ContentResolver method and the target table of the operation. Therefore, it is necessary to specify a special CONTENT_URI constant for the URI in the Custom ContentProvider for convenience. What to prepare before querying data through Content Provider: 1. URI of the Provider to query data; 2. Name of the data column to be queried and their data type; the _ ID and _ COUNT columns have only one row of data and the total number of data rows. 3. For a row of data, you also need to know its ID value. If _ ID = 23, it is "content ://.... /23 "query data: ContentResolver can be used. query () method or Activity. the managedQuery () method to obtain the result Cursor. The life cycle of the Cursor obtained by the latter is managed by the Activity, without the need to manually close the Cursor, we can also conveniently and accurately control its loading and release. Activity. the startManagingCursor () method can add unmanaged Cursor to the management list (Note: We recommend that you use getLoaderManager () to get the LoaderManger object to manage the Cursor after Version 2.3) stopManagingCursor (Cursor) you can disable automatic management. 1. Obtain URI: ContentUris. withAppendedId () Uri. withAppendedPath (). You can add the parameter (ID) to the query URI. The ContentUris. parseId (uri) method can obtain the ID part of the URI. Example: import android. provider. contacts. people; import android. content. contentUris; import android.net. uri; import android. database. cursor; Uri myPerson = ContentUris. withAppendedId (People. CONTENT_URI, 23); Uri myPerson = Uri. withAppendedPath (People. CONTENT_URI, "23"); Cursor cur = managedQuery (myPerson, null, null); 2. Read data: private void getColumnData (Cursor cur) {if (cur. moveToFirst ()){ String name; String phoneNumber; int nameColumn = cur. getColumnIndex (People. NAME); int phoneColumn = cur. getColumnIndex (People. NUMBER); String imagePath; do {// Get the field values name = cur. getString (nameColumn); phoneNumber = cur. getString (phoneColumn); // Do something with the values ....} while (cur. moveToNext () ;}} if it is a small binary data, it can be directly saved to the table like normal data, but if the binary data volume is large and the table URI is content: in URI format, we need to use C OntentResolver. openInputStream () method to obtain the data stream for reading data. You must call the ContentResolver method to modify all data. First, save the data to be changed to the ContentValues object, and then call the corresponding method of ContentResolver to complete the update operation. Example: Add a new record: ContentValues values = new ContentValues (); values. put (People. NAME, "Abraham Lincoln"); values. put (People. STARRED, 1); Uri uri = getContentResolver (). insert (People. CONTENT_URI, values); add a new value to the original record: Uri phoneUri = null; phoneUri = Uri. withAppendedPath (uri, People. phones. CONTENT_DIRECTORY); values. clear (); values. put (People. pho Nes. TYPE, People. phones. TYPE_MOBILE); values. put (People. phones. NUMBER, "1233214567"); getContentResolver (). insert (phoneUri, values); The CONTENT_DIRECTORY is a constant, indicating that this is the append data. If the data is a large binary object in the form of content: URI, call ContentResolver. openOutputStream () to save it. Import android. provider. mediaStore. images. media; import android. content. contentValues; import java. io. outputStream; // Save the name and description of an image in a ContentValues map. contentValues values = new ContentValues (3); values. put (Media. DISPLAY_NAME, "road_trip_1"); values. put (Media. DESCRIPTION, "Day 1, trip to Los Angeles"); values. put (Media. MIME_TYPE, "image/jpeg "); // Add a new record without the bitmap, but with the values just set. // insert () returns the URI of the new record. uri uri = getContentResolver (). insert (Media. EXTERNAL_CONTENT_URI, values); // Now get a handle to the file for that record, and save the data into it. // Here, sourceBitmap is a Bitmap object representing the file to save to the database. try {OutputStream outStream = getContentRes Olver (). openOutputStream (uri); sourceBitmap. compress (Bitmap. compressFormat. JPEG, 50, outStream); outStream. close ();} catch (Exception e) {Log. e (TAG, "exception while writing image", e);} implements our own Content Provider: 1. You need to create a class and inherit the ContentProvider class, and implement the six methods in this abstract class. Public int delete (Uri uri, String selection, String [] selectionArgs) {} public Uri insert (Uri uri, ContentValues values) {} public Cursor query (Uri uri, string [] projection, String selection, String [] selectionArgs, String sortOrder) {}// SQLiteCursor, MatrixCursor public int update (Uri uri, ContentValues values, String selection, string [] selectionArgs) {} public boolean onCreate () {} public String GetType (Uri uri) {} 2, which defines the URI constant: public static final Uri CONTENT_URI; CONTENT_URI = Uri. parse ("content: // com. example. codelab. transportationprovider "); 3. Define the column name. Do not forget the _ ID column. Public static String ColumnName 4. If the data type is new, the custom MIME type must be returned in getType (). The name format of the custom type is vnd. android. cursor. item/vnd. yourcompanyname. contenttype vnd. android. cursor. dir/vnd. yourcompanyname. contenttype 5: When storing big binary data, content: URI is actually stored under the column name, and a "_ data" column is declared to save the real path of the file for ContentResolver. openInputStream. 6. When the data changes, it is best to call the ContentResolver. policychange () method to notify the caller. 7. Declare ContentProvider in AndroidManifest. xml. Example: <provider android: name = ". autoInfoProvider "android: authorities =" com. example. autos. autoinfoprovider "... /> </provider> <provider> you can set more parameters for ContentProvider In the tag attributes. A complete example of custom ContentProvider and shared call and event listening: Data Structure User. java: Java code 1. package com. yaku. pojo; 2. 3. public class User {4. private int id; 5. private String name; 6. private int age; 7. 8. public User (int id, String name, int age) {9. super (); 10. this. id = id; 11. this. name = name; 12. this. age = age; 13 .} 14. public int getId () {15. return id; 16 .} 17. public void setId (int id) {18. this. id = id; 19.} 20. public String getName () {21. return name; 22 .} 23. public void setName (String name) {24. this. name = name; 25 .} 26. public int getAge () {27. return age; 28 .} 29. public void setAge (int age) {30. this. age = age; 31 .} 32. @ Override 33. public String toString () {34. return "User [age =" + age + ", id =" + id + ", name =" + name + "]"; 35 .} 36 .} database Operation DBOpenHelper. java: Java code 1. package c Om. yaku. db; 2. 3. import android. content. context; 4. import android. database. sqlite. SQLiteDatabase; 5. import android. database. sqlite. SQLiteOpenHelper; 6. 7. public class DBOpenHelper extends SQLiteOpenHelper {8. private static final String DBNAME = "yaku. db "; // database name 9. private static final int DBVER = 1; // database version 10. 11. public DBOpenHelper (Context context) {12. super (context, DBNAME, null, DBVE R); 13 .} 14. 15. @ Override 16. public void onCreate (SQLiteDatabase db) {17. string SQL = "CREATE TABLE user (userid integer primary key autoincrement, name varchar (20), age integer)"; 18. db.exe cSQL (SQL); // execute the changed SQL statement 19 .} 20. 21. @ Override 22. public void onUpgrade (SQLiteDatabase db, int arg1, int arg2) {23. db.exe cSQL ("drop table if exists user"); 24. onCreate (db); 25 .} 26. 27 .} external shared processing class Con TentProviderUser. java: Java code 1. package com. yaku. contentProvider; 2. 3. import com. yaku. db. DBOpenHelper; 4. 5. import android. content. contentProvider; 6. import android. content. contentUris; 7. import android. content. contentValues; 8. import android. content. uriMatcher; 9. import android. database. cursor; 10. import android. database. sqlite. SQLiteDatabase; 11. import android.net. uri; 12. 13. public cl Ass ContentProviderUser extends ContentProvider {14. private DBOpenHelper dbOpenHelper; 15. // constant UriMatcher. NO_MATCH indicates the return code 16 that does not match any path. private static final UriMatcher MATCHER = new UriMatcher (UriMatcher. NO_MATCH); 17. private static final int USERS = 1; 18. private static final int USER = 2; 19. static {20. // If the match () method matches content: // com. yaku. contentProvider. userprovider/user path, returns a matching Code of 1 21. MATCHER. ad DURI ("com. yaku. contentProvider. userprovider "," user ", USERS); 22. // If the match () method matches content: // com. yaku. contentProvider. userprovider/user/123 path, returns a matching code of 2 23. MATCHER. addURI ("com. yaku. contentProvider. userprovider "," user/# ", USER); // #24 .} 25. @ Override 26. public int delete (Uri uri, String selection, String [] selectionArgs) {27. SQLiteDatabase db = dbOpenHelper. getWritableDatabase (); 28. int coun T = 0; 29. switch (MATCHER. match (uri) {30. case USERS: 31. count = db. delete ("user", selection, selectionArgs); 32. return count; 33. case USER: 34. // ContentUris class is used to obtain the ID Section 35 after the Uri path. long id = ContentUris. parseId (uri); 36. string where = "userid =" + id; 37. if (selection! = Null &&! "". Equals (selection) {38. where = selection + "and" + where; 39 .} 40. count = db. delete ("user", where, selectionArgs); 41. return count; 42. default: 43. throw new IllegalArgumentException ("Unkwon Uri:" + uri. toString (); 44 .} 45 .} 46. 47. /** 48. * This method is used to return the MIME type of the data represented by the current Url. 49. * If the operated data belongs to the set type, the MIME-type string should be vnd. android. cursor. dir/starts with 50. * If the data to be operated belongs to a non-set type, the MIME type string should be vnd. android. cursor. item/starts with 51. */52. @ Override 53. public String getType (Uri uri) {54. switch (MATCHER. match (uri) {55. case USERS: 56. return "vnd. android. cursor. dir/user "; 57. 58. case USER: 59. return "vnd. android. cursor. item/user "; 60. 61. default: 62. throw new IllegalArgumentException ("Unkwon Uri: "+ uri. toString (); 63 .} 64 .} 65. 66. @ Override 67. public Uri insert (Uri uri, ContentValues values) {68. SQLiteDatabase db = dbOpenHelper. getWritableDatabase (); 69. switch (MATCHER. match (uri) {70. case USERS: 71. long rowid = db. insert ("user", "name", values); 72. uri insertUri = ContentUris. withAppendedId (uri, rowid); // get the Uri 73 representing the newly added record. this. getContext (). getContentResolver (). notifyChang E (uri, null); 74. return insertUri; 75. 76. default: 77. throw new IllegalArgumentException ("Unkwon Uri:" + uri. toString (); 78 .} 79 .} 80. 81. @ Override 82. public boolean onCreate () {83. this. dbOpenHelper = new DBOpenHelper (this. getContext (); 84. return false; 85 .} 86. 87. @ Override 88. public Cursor query (Uri uri, String [] projection, String selection, String [] selectionArgs, 89. string sort Order) {90. SQLiteDatabase db = dbOpenHelper. getReadableDatabase (); 91. switch (MATCHER. match (uri) {92. case USERS: 93. return db. query ("user", projection, selection, selectionArgs, null, null, sortOrder); 94. case USER: 95. long id = ContentUris. parseId (uri); 96. string where = "userid =" + id; 97. if (selection! = Null &&! "". Equals (selection) {98. where = selection + "and" + where; 99 .} 100. return db. query ("user", projection, where, selectionArgs, null, null, sortOrder); 101. default: 102. throw new IllegalArgumentException ("Unkwon Uri:" + uri. toString (); 103 .} 104 .} 105. 106. @ Override 107. public int update (Uri uri, ContentValues values, String selection, String [] selectionArgs) {108. SQLiteDatabase db = d BOpenHelper. getWritableDatabase (); 109. int count = 0; 110. switch (MATCHER. match (uri) {111. case USERS: 112. count = db. update ("person", values, selection, selectionArgs); 113. return count; 114. case USER: 115. long id = ContentUris. parseId (uri); 116. string where = "userid =" + id; 117. if (selection! = Null &&! "". Equals (selection) {118. where = selection + "and" + where; 119 .} 120. count = db. update ("user", values, where, selectionArgs); 121. return count; 122. default: 123. throw new IllegalArgumentException ("Unkwon Uri:" + uri. toString (); 124 .} 125 .} 126 .} unit test class (in another application): Java code 1. package com. yaku. contentProvider; 2. 3. import android. content. contentResolver; 4. import android. content. contentValues; 5. import android. database. cursor; 6. import android.net. uri; 7. import android. test. androidTestCase; 8. import android. util. log; 9. 10. /** 11. * Perform unit test 12 on ContentProviderActivity in the ContentProvider project. */13. public class ContentProviderActivityTest extends AndroidTestCase {14. private static final String TAG = "ContentProvider"; 15. // Add data to the content provider 16. public void testInsert () throws Throwable {17. contentResolver contentResolver = this. getContext (). getContentResolver (); 18. uri insertUri = Uri. parse ("content: // com. yaku. contentProvider. userprovider/user "); 19. contentValues values = new ContentValues (); 20. values. put ("name", "channel length"); 21. values. put ("age", 86); 22. uri uri = contentResolver. insert (insertUri, values); 23. log. I (TAG, uri. toString (); 24 .} 25. 26. // update the data in the content provider 27. public void testUpdate () throws Throwable {28. contentResolver contentResolver = this. getContext (). getContentResolver (); 29. uri updateUri = Uri. parse ("content: // com. yaku. contentProvider. userprovider/user/1 "); 30. contentValues values = new ContentValues (); 31. values. put ("name", "qingmei Daolong"); 32. contentResolver. update (updateUri, values, null, null); 33 .} 34. 35. // delete data from the content provider 36. public void testDelete () throws Throwable {37. contentResolver contentResolver = this. getContext (). getContentResolver (); 38. uri deleteUri = Uri. parse ("content: // com. yaku. contentProvider. userprovider/user/1 "); 39. contentResolver. delete (deleteUri, null, null); 40 .} 41. 42. // obtain the data in the content provider 43. public void testFind () throws Throwable {44. contentResolver contentResolver = this. getContext (). getContentResolver (); 45. uri selectUri = Uri. parse ("content: // com. yaku. contentProvider. userprovider/user "); 46. cursor cursor = contentResolver. query (selectUri, null, "userid desc"); 47. while (cursor. moveToNext () {48. int id = cursor. getInt (cursor. getColumnIndex ("userid"); 49. string name = cursor. getString (cursor. getColumnIndex ("name"); 50. int age = cursor. getInt (cursor. getColumnIndex ("age"); 51. log. I (TAG, "id =" + id + ", name =" + name + ", age =" + age); 52 .} 53 .} 54. 55 .} monitoring data changes: Java code 1. <span style = "font-size: medium;"> package com. yaku. contentProvider; 2. 3. import android. content. contentResolver; 4. import android. content. contentValues; 5. import android. database. cursor; 6. import android.net. uri; 7. import android. test. androidTestCase; 8. import android. util. log; 9. 10. /** 11. * listen for data changes 12. */13. public class OtherContentProviderTest extends AndroidTestCase {14. private static final String TAG = "OtherContentProvider"; 15. 16. @ Override 17. public void onCreate (Bundle savedInstanceState) {18. super. onCreate (savedInstanceState); 19. setContentView (R. layout. main); 20. 21. uri insertUri = Uri. parse ("content: // com. yaku. contentProvider. userprovider/user "); 22. contentResolver contentResolver = this. getContentResolver (); 23. // listen on the specified uri. If the data represented by this uri changes, onChange () 24 in the PersonObserver is called. contentResolver. registerContentObserver (insertUri, true, new PersonObserver (new Handler (); 25 .} 26. 27. private final class PersonObserver extends ContentObserver {28. public PersonObserver (Handler handler) {29. super (handler); 30 .} 31. 32. @ Override 33. public void onChange (boolean selfChange) {34. contentResolver contentResolver = getContentResolver (); 35. uri selectUri = Uri. parse ("content: // com. yaku. contentProvider. userprovider/user "); 36. cursor cursor = contentResolver. query (selectUri, null, "userid desc"); 37. while (cursor. moveToNext () {38. int id = cursor. getInt (cursor. getColumnIndex ("userid"); 39. string name = cursor. getString (cursor. getColumnIndex ("name"); 40. int age = cursor. getInt (cursor. getColumnIndex ("age"); 41. log. I (TAG, "id =" + id + ", name =" + name + ", age =" + age); 42 .} 43 .} 44 .} 45 .} conclusion
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.