实现多个ContentProvider对多张表进行操作

时间:2021-05-14 05:15:12

http://blog.csdn.net/maylian7700/article/details/7365373

SQLite数据库直接操作类:

DatabaseHelper.java

  1. package com.jacp.database;
  2. import android.content.Context;
  3. import android.database.sqlite.SQLiteDatabase;
  4. import android.database.sqlite.SQLiteOpenHelper;
  5. import com.jacp.demo.provider.Provider;
  6. public class DatabaseHelper extends SQLiteOpenHelper {
  7. private static final String DATABASE_NAME = "jacp_demo.db";
  8. private static final int DATABASE_VERSION = 1;
  9. public DatabaseHelper(Context context) {
  10. super(context, DATABASE_NAME, null, DATABASE_VERSION);
  11. }
  12. @Override
  13. public void onCreate(SQLiteDatabase db) {
  14. // 创建programmer表
  15. db.execSQL("CREATE TABLE " + Provider.ProgrammerColumns.TABLE_NAME + " ("
  16. + Provider.ProgrammerColumns._ID + " INTEGER PRIMARY KEY,"
  17. + Provider.ProgrammerColumns.NAME + " TEXT,"
  18. + Provider.ProgrammerColumns.AGE + " INTEGER"
  19. + ");");
  20. // 创建leader表
  21. db.execSQL("CREATE TABLE " + Provider.LeaderColumns.TABLE_NAME + " ("
  22. + Provider.LeaderColumns._ID + " INTEGER PRIMARY KEY,"
  23. + Provider.LeaderColumns.NAME + " TEXT,"
  24. + Provider.LeaderColumns.TITLE + " TEXT,"
  25. + Provider.LeaderColumns.LEVEL + " INTEGER"
  26. + ");");
  27. }
  28. @Override
  29. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  30. db.execSQL("DROP TABLE IF EXISTS " + Provider.ProgrammerColumns.TABLE_NAME);
  31. db.execSQL("DROP TABLE IF EXISTS " + Provider.LeaderColumns.TABLE_NAME);
  32. onCreate(db);
  33. }
  34. }

保存跟数据库及表有关的常量:
Provider.java

  1. package com.jacp.demo.provider;
  2. import android.net.Uri;
  3. import android.provider.BaseColumns;
  4. /**
  5. * 保存数据库中的常量
  6. * @author jacp
  7. *
  8. */
  9. public class Provider {
  10. public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.jacp.demo";
  11. public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.jacp.demo";
  12. /**
  13. * 保存programmer表中用到的常量
  14. * @author jacp
  15. *
  16. */
  17. public static final class ProgrammerColumns implements BaseColumns {
  18. // 注意两张表的authority要不一样
  19. public static final String AUTHORITY = "com.jacp.provider.demo.programmer";
  20. public static final Uri CONTENT_URI = Uri.parse("content://"+ AUTHORITY +"/programmers");
  21. public static final String TABLE_NAME = "programmer";
  22. public static final String DEFAULT_SORT_ORDER = "age desc";
  23. public static final String NAME = "name";
  24. public static final String AGE = "age";
  25. }
  26. /**
  27. * 保存leader表中用到的常量
  28. * @author mayliang
  29. *
  30. */
  31. public static final class LeaderColumns implements BaseColumns {
  32. public static final String AUTHORITY = "com.jacp.provider.demo.leader";
  33. public static final Uri CONTENT_URI = Uri.parse("content://"+ AUTHORITY +"/leaders");
  34. public static final String TABLE_NAME = "leader";
  35. public static final String DEFAULT_SORT_ORDER = "level desc";
  36. public static final String NAME = "name";
  37. public static final String TITLE = "title";
  38. public static final String LEVEL = "level";
  39. }
  40. }

对leader表进行增删改查操作的ContentProvider类:

LeaderProvider.java

  1. package com.jacp.demo.provider;
  2. import java.util.HashMap;
  3. import android.content.ContentProvider;
  4. import android.content.ContentUris;
  5. import android.content.ContentValues;
  6. import android.content.UriMatcher;
  7. import android.database.Cursor;
  8. import android.database.SQLException;
  9. import android.database.sqlite.SQLiteDatabase;
  10. import android.database.sqlite.SQLiteQueryBuilder;
  11. import android.net.Uri;
  12. import android.text.TextUtils;
  13. import com.jacp.database.DatabaseHelper;
  14. /**
  15. * 对leader表进行操作的ContentProvider
  16. * @author jacp
  17. *
  18. */
  19. public class LeaderProvider extends ContentProvider {
  20. private static HashMap<String, String> sLeadersProjectionMap;
  21. private static final int LEADERS = 1;
  22. private static final int LEADER_ID = 2;
  23. private static final UriMatcher sUriMatcher;
  24. private DatabaseHelper mOpenHelper;
  25. @Override
  26. public boolean onCreate() {
  27. mOpenHelper = new DatabaseHelper(getContext());
  28. return true;
  29. }
  30. @Override
  31. public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
  32. String sortOrder) {
  33. SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
  34. qb.setTables(Provider.LeaderColumns.TABLE_NAME);
  35. switch (sUriMatcher.match(uri)) {
  36. case LEADERS:
  37. qb.setProjectionMap(sLeadersProjectionMap);
  38. break;
  39. case LEADER_ID:
  40. qb.setProjectionMap(sLeadersProjectionMap);
  41. qb.appendWhere(Provider.LeaderColumns._ID + "=" + uri.getPathSegments().get(1));
  42. break;
  43. default:
  44. throw new IllegalArgumentException("Unknown URI " + uri);
  45. }
  46. // If no sort order is specified use the default
  47. String orderBy;
  48. if (TextUtils.isEmpty(sortOrder)) {
  49. orderBy = Provider.LeaderColumns.DEFAULT_SORT_ORDER;
  50. } else {
  51. orderBy = sortOrder;
  52. }
  53. // Get the database and run the query
  54. SQLiteDatabase db = mOpenHelper.getReadableDatabase();
  55. Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
  56. // Tell the cursor what uri to watch, so it knows when its source data changes
  57. c.setNotificationUri(getContext().getContentResolver(), uri);
  58. return c;
  59. }
  60. @Override
  61. public String getType(Uri uri) {
  62. switch (sUriMatcher.match(uri)) {
  63. case LEADERS:
  64. return Provider.CONTENT_TYPE;
  65. case LEADER_ID:
  66. return Provider.CONTENT_ITEM_TYPE;
  67. default:
  68. throw new IllegalArgumentException("Unknown URI " + uri);
  69. }
  70. }
  71. @Override
  72. public Uri insert(Uri uri, ContentValues initialValues) {
  73. // Validate the requested uri
  74. if (sUriMatcher.match(uri) != LEADERS) {
  75. throw new IllegalArgumentException("Unknown URI " + uri);
  76. }
  77. ContentValues values;
  78. if (initialValues != null) {
  79. values = new ContentValues(initialValues);
  80. } else {
  81. values = new ContentValues();
  82. }
  83. // Make sure that the fields are all set
  84. if (values.containsKey(Provider.LeaderColumns.NAME) == false) {
  85. values.put(Provider.LeaderColumns.NAME, "");
  86. }
  87. if (values.containsKey(Provider.LeaderColumns.TITLE) == false) {
  88. values.put(Provider.LeaderColumns.TITLE, "");
  89. }
  90. if (values.containsKey(Provider.LeaderColumns.LEVEL) == false) {
  91. values.put(Provider.LeaderColumns.LEVEL, 0);
  92. }
  93. SQLiteDatabase db = mOpenHelper.getWritableDatabase();
  94. long rowId = db.insert(Provider.LeaderColumns.TABLE_NAME, Provider.LeaderColumns.NAME, values);
  95. if (rowId > 0) {
  96. Uri noteUri = ContentUris.withAppendedId(Provider.LeaderColumns.CONTENT_URI, rowId);
  97. getContext().getContentResolver().notifyChange(noteUri, null);
  98. return noteUri;
  99. }
  100. throw new SQLException("Failed to insert row into " + uri);
  101. }
  102. @Override
  103. public int delete(Uri uri, String where, String[] whereArgs) {
  104. SQLiteDatabase db = mOpenHelper.getWritableDatabase();
  105. int count;
  106. switch (sUriMatcher.match(uri)) {
  107. case LEADERS:
  108. count = db.delete(Provider.LeaderColumns.TABLE_NAME, where, whereArgs);
  109. break;
  110. case LEADER_ID:
  111. String noteId = uri.getPathSegments().get(1);
  112. count = db.delete(Provider.LeaderColumns.TABLE_NAME, Provider.LeaderColumns._ID + "=" + noteId
  113. + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
  114. break;
  115. default:
  116. throw new IllegalArgumentException("Unknown URI " + uri);
  117. }
  118. getContext().getContentResolver().notifyChange(uri, null);
  119. return count;
  120. }
  121. @Override
  122. public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
  123. SQLiteDatabase db = mOpenHelper.getWritableDatabase();
  124. int count;
  125. switch (sUriMatcher.match(uri)) {
  126. case LEADERS:
  127. count = db.update(Provider.LeaderColumns.TABLE_NAME, values, where, whereArgs);
  128. break;
  129. case LEADER_ID:
  130. String noteId = uri.getPathSegments().get(1);
  131. count = db.update(Provider.LeaderColumns.TABLE_NAME, values, Provider.LeaderColumns._ID + "=" + noteId
  132. + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
  133. break;
  134. default:
  135. throw new IllegalArgumentException("Unknown URI " + uri);
  136. }
  137. getContext().getContentResolver().notifyChange(uri, null);
  138. return count;
  139. }
  140. static {
  141. sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  142. sUriMatcher.addURI(Provider.LeaderColumns.AUTHORITY, "leaders", LEADERS);
  143. sUriMatcher.addURI(Provider.LeaderColumns.AUTHORITY, "leaders/#", LEADER_ID);
  144. sLeadersProjectionMap = new HashMap<String, String>();
  145. sLeadersProjectionMap.put(Provider.LeaderColumns._ID, Provider.LeaderColumns._ID);
  146. sLeadersProjectionMap.put(Provider.LeaderColumns.NAME, Provider.LeaderColumns.NAME);
  147. sLeadersProjectionMap.put(Provider.LeaderColumns.TITLE, Provider.LeaderColumns.TITLE);
  148. sLeadersProjectionMap.put(Provider.LeaderColumns.LEVEL, Provider.LeaderColumns.LEVEL);
  149. }
  150. }

对programmer表进行增删改查操作的ContentProvider类:

ProgrammerProvider.java

  1. package com.jacp.demo.provider;
  2. import java.util.HashMap;
  3. import android.content.ContentProvider;
  4. import android.content.ContentUris;
  5. import android.content.ContentValues;
  6. import android.content.UriMatcher;
  7. import android.database.Cursor;
  8. import android.database.SQLException;
  9. import android.database.sqlite.SQLiteDatabase;
  10. import android.database.sqlite.SQLiteQueryBuilder;
  11. import android.net.Uri;
  12. import android.text.TextUtils;
  13. import com.jacp.database.DatabaseHelper;
  14. /**
  15. * 对programmer表进行操作的ContentProvider
  16. * @author jacp
  17. *
  18. */
  19. public class ProgrammerProvider extends ContentProvider {
  20. private static HashMap<String, String> sprogrammersProjectionMap;
  21. private static final int PROGRAMMERS = 1;
  22. private static final int PROGRAMMERS_ID = 2;
  23. private static final UriMatcher sUriMatcher;
  24. private DatabaseHelper mOpenHelper;
  25. @Override
  26. public boolean onCreate() {
  27. mOpenHelper = new DatabaseHelper(getContext());
  28. return true;
  29. }
  30. @Override
  31. public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
  32. String sortOrder) {
  33. SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
  34. qb.setTables(Provider.ProgrammerColumns.TABLE_NAME);
  35. switch (sUriMatcher.match(uri)) {
  36. case PROGRAMMERS:
  37. qb.setProjectionMap(sprogrammersProjectionMap);
  38. break;
  39. case PROGRAMMERS_ID:
  40. qb.setProjectionMap(sprogrammersProjectionMap);
  41. qb.appendWhere(Provider.ProgrammerColumns._ID + "=" + uri.getPathSegments().get(1));
  42. break;
  43. default:
  44. throw new IllegalArgumentException("Unknown URI " + uri);
  45. }
  46. // If no sort order is specified use the default
  47. String orderBy;
  48. if (TextUtils.isEmpty(sortOrder)) {
  49. orderBy = Provider.ProgrammerColumns.DEFAULT_SORT_ORDER;
  50. } else {
  51. orderBy = sortOrder;
  52. }
  53. // Get the database and run the query
  54. SQLiteDatabase db = mOpenHelper.getReadableDatabase();
  55. Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
  56. // Tell the cursor what uri to watch, so it knows when its source data changes
  57. c.setNotificationUri(getContext().getContentResolver(), uri);
  58. return c;
  59. }
  60. @Override
  61. public String getType(Uri uri) {
  62. switch (sUriMatcher.match(uri)) {
  63. case PROGRAMMERS:
  64. return Provider.CONTENT_TYPE;
  65. case PROGRAMMERS_ID:
  66. return Provider.CONTENT_ITEM_TYPE;
  67. default:
  68. throw new IllegalArgumentException("Unknown URI " + uri);
  69. }
  70. }
  71. @Override
  72. public Uri insert(Uri uri, ContentValues initialValues) {
  73. // Validate the requested uri
  74. if (sUriMatcher.match(uri) != PROGRAMMERS) {
  75. throw new IllegalArgumentException("Unknown URI " + uri);
  76. }
  77. ContentValues values;
  78. if (initialValues != null) {
  79. values = new ContentValues(initialValues);
  80. } else {
  81. values = new ContentValues();
  82. }
  83. // Make sure that the fields are all set
  84. if (values.containsKey(Provider.ProgrammerColumns.NAME) == false) {
  85. values.put(Provider.ProgrammerColumns.NAME, "");
  86. }
  87. if (values.containsKey(Provider.ProgrammerColumns.AGE) == false) {
  88. values.put(Provider.ProgrammerColumns.AGE, 0);
  89. }
  90. SQLiteDatabase db = mOpenHelper.getWritableDatabase();
  91. long rowId = db.insert(Provider.ProgrammerColumns.TABLE_NAME, Provider.ProgrammerColumns.NAME, values);
  92. if (rowId > 0) {
  93. Uri noteUri = ContentUris.withAppendedId(Provider.ProgrammerColumns.CONTENT_URI, rowId);
  94. getContext().getContentResolver().notifyChange(noteUri, null);
  95. return noteUri;
  96. }
  97. throw new SQLException("Failed to insert row into " + uri);
  98. }
  99. @Override
  100. public int delete(Uri uri, String where, String[] whereArgs) {
  101. SQLiteDatabase db = mOpenHelper.getWritableDatabase();
  102. int count;
  103. switch (sUriMatcher.match(uri)) {
  104. case PROGRAMMERS:
  105. count = db.delete(Provider.ProgrammerColumns.TABLE_NAME, where, whereArgs);
  106. break;
  107. case PROGRAMMERS_ID:
  108. String noteId = uri.getPathSegments().get(1);
  109. count = db.delete(Provider.ProgrammerColumns.TABLE_NAME, Provider.ProgrammerColumns._ID + "=" + noteId
  110. + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
  111. break;
  112. default:
  113. throw new IllegalArgumentException("Unknown URI " + uri);
  114. }
  115. getContext().getContentResolver().notifyChange(uri, null);
  116. return count;
  117. }
  118. @Override
  119. public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
  120. SQLiteDatabase db = mOpenHelper.getWritableDatabase();
  121. int count;
  122. switch (sUriMatcher.match(uri)) {
  123. case PROGRAMMERS:
  124. count = db.update(Provider.ProgrammerColumns.TABLE_NAME, values, where, whereArgs);
  125. break;
  126. case PROGRAMMERS_ID:
  127. String noteId = uri.getPathSegments().get(1);
  128. count = db.update(Provider.ProgrammerColumns.TABLE_NAME, values, Provider.ProgrammerColumns._ID + "=" + noteId
  129. + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
  130. break;
  131. default:
  132. throw new IllegalArgumentException("Unknown URI " + uri);
  133. }
  134. getContext().getContentResolver().notifyChange(uri, null);
  135. return count;
  136. }
  137. static {
  138. sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  139. sUriMatcher.addURI(Provider.ProgrammerColumns.AUTHORITY, "programmers", PROGRAMMERS);
  140. sUriMatcher.addURI(Provider.ProgrammerColumns.AUTHORITY, "programmers/#", PROGRAMMERS_ID);
  141. sprogrammersProjectionMap = new HashMap<String, String>();
  142. sprogrammersProjectionMap.put(Provider.ProgrammerColumns._ID, Provider.ProgrammerColumns._ID);
  143. sprogrammersProjectionMap.put(Provider.ProgrammerColumns.NAME, Provider.ProgrammerColumns.NAME);
  144. sprogrammersProjectionMap.put(Provider.ProgrammerColumns.AGE, Provider.ProgrammerColumns.AGE);
  145. }
  146. }

保存leader表的数据对象:

Leader.java

  1. package com.jacp.pojos;
  2. public class Leader {
  3. public String name;
  4. public String title;
  5. public int level;
  6. }

保存Programmer表的数据对象:

Programmer.java

  1. package com.jacp.pojos;
  2. public class Programmer {
  3. public String name;
  4. public int age;
  5. }

Activity测试:

  1. package com.jacp.demo;
  2. import android.app.Activity;
  3. import android.content.ContentValues;
  4. import android.database.Cursor;
  5. import android.net.Uri;
  6. import android.os.Bundle;
  7. import android.text.TextUtils;
  8. import android.util.Log;
  9. import com.jacp.demo.provider.Provider;
  10. import com.jacp.pojos.Leader;
  11. import com.jacp.pojos.Programmer;
  12. public class ContentProviderDemoActivity extends Activity {
  13. private static final String TAG = "ProviderActivity";
  14. @Override
  15. public void onCreate(Bundle savedInstanceState) {
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.main);
  18. testLeader();
  19. testProgrammer();
  20. }
  21. private void testProgrammer() {
  22. Programmer p = new Programmer();
  23. p.name = "jacp";
  24. p.age = 99;
  25. int id = insertProgrammer(p);
  26. queryProgrammer(id);
  27. }
  28. private int insertProgrammer(Programmer programmer) {
  29. ContentValues values = new ContentValues();
  30. values.put(Provider.ProgrammerColumns.NAME, programmer.name);
  31. values.put(Provider.ProgrammerColumns.AGE, programmer.age);
  32. Uri uri = getContentResolver().insert(Provider.ProgrammerColumns.CONTENT_URI, values);
  33. Log.i(TAG, "insert uri="+uri);
  34. String lastPath = uri.getLastPathSegment();
  35. if (TextUtils.isEmpty(lastPath)) {
  36. Log.i(TAG, "insert failure!");
  37. } else {
  38. Log.i(TAG, "insert success! the id is " + lastPath);
  39. }
  40. return Integer.parseInt(lastPath);
  41. }
  42. private void queryProgrammer(int id) {
  43. Cursor c = getContentResolver().query(Provider.ProgrammerColumns.CONTENT_URI, new String[] { Provider.ProgrammerColumns.NAME, Provider.ProgrammerColumns.AGE }, Provider.ProgrammerColumns._ID + "=?", new String[] { id + "" }, null);
  44. if (c != null && c.moveToFirst()) {
  45. Programmer p = new Programmer();
  46. p.name = c.getString(c.getColumnIndexOrThrow(Provider.ProgrammerColumns.NAME));
  47. p.age = c.getInt(c.getColumnIndexOrThrow(Provider.ProgrammerColumns.AGE));
  48. c.close(); // 用完Cursor要释放资源,如果Cursor没有关闭系统会打出Error级别的Log
  49. Log.i(TAG, "programmer.name="+p.name+"---programmer.age="+p.age);
  50. } else {
  51. Log.i(TAG, "query failure!");
  52. }
  53. }
  54. private void testLeader() {
  55. Leader leader = new Leader();
  56. leader.name = "jacky";
  57. leader.title = "CTO";
  58. leader.level = 30;
  59. int id = insertLeader(leader);
  60. queryLeader(id);
  61. }
  62. private int insertLeader(Leader leader) {
  63. ContentValues values = new ContentValues();
  64. values.put(Provider.LeaderColumns.NAME, leader.name);
  65. values.put(Provider.LeaderColumns.TITLE, leader.title);
  66. values.put(Provider.LeaderColumns.LEVEL, leader.level);
  67. Uri uri = getContentResolver().insert(Provider.LeaderColumns.CONTENT_URI, values);
  68. Log.i(TAG, "insert uri="+uri);
  69. String lastPath = uri.getLastPathSegment();
  70. if (TextUtils.isEmpty(lastPath)) {
  71. Log.i(TAG, "insert failure!");
  72. } else {
  73. Log.i(TAG, "insert success! the id is " + lastPath);
  74. }
  75. return Integer.parseInt(lastPath);
  76. }
  77. private void queryLeader(int id) {
  78. Cursor c = getContentResolver().query(Provider.LeaderColumns.CONTENT_URI, new String[] { Provider.LeaderColumns.NAME, Provider.LeaderColumns.TITLE, Provider.LeaderColumns.LEVEL }, Provider.LeaderColumns._ID + "=?", new String[] { id + "" }, null);
  79. if (c != null && c.moveToFirst()) {
  80. Leader leader = new Leader();
  81. leader.name = c.getString(c.getColumnIndexOrThrow(Provider.LeaderColumns.NAME));
  82. leader.title = c.getString(c.getColumnIndexOrThrow(Provider.LeaderColumns.TITLE));
  83. leader.level = c.getInt(c.getColumnIndexOrThrow(Provider.LeaderColumns.LEVEL));
  84. Log.i(TAG, "leader.name="+leader.name+"---leader.title="+leader.title+"---leader.level="+leader.level);
  85. } else {
  86. Log.i(TAG, "query failure!");
  87. }
  88. }
  89. }

Manifest.xml文件中的注册(要注意的地方,下面已标注):

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.jacp.demo"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6. <uses-sdk android:minSdkVersion="8" />
  7. <application
  8. android:icon="@drawable/ic_launcher"
  9. android:label="@string/app_name" >
  10. <activity
  11. android:label="@string/app_name"
  12. android:name=".ContentProviderDemoActivity" >
  13. <intent-filter >
  14. <action android:name="android.intent.action.MAIN" />
  15. <category android:name="android.intent.category.LAUNCHER" />
  16. </intent-filter>
  17. </activity>
  18. <!-- 这个地方的两个provider的authories要不一样,否则找不到对应ContentProvider处理出现 java.lang.IllegalArgumentException: Unknown URI异常 -->
  19. <provider android:name=".provider.ProgrammerProvider"
  20. android:authorities="com.jacp.provider.demo.programmer" />
  21. <provider android:name=".provider.LeaderProvider"
  22. android:authorities="com.jacp.provider.demo.leader" />
  23. </application>
  24. </manifest>

demo下载地址:http://download.csdn.net/detail/maylian7700/4150144

如有遗漏不当之处,欢迎批评指正!