当Android中的应用需要访问其他应用的数据时,用ContentProvider可以很好的解决这个问题。今天介绍一下ContentProvider的用法。
首先开发ContentProvider有两个步骤:
1、开发一个ContentProvider的子类,该子类需要实现增、删、改、查等方法。
2、在AndroidManifest.xml文件中注册该ContentProvider。
下面通过一个实例来介绍一下ContentProvider到底怎么实现的。首先,我们也像系统一样把ContentProvider的Uri、数据列等信息以常量的形式公开出来、方便访问。为此,定义一个工具类,该类中只是包含一个public static的常量,该工具类的代码如下:
1 public final class Words 2 { 3 // 定义该ContentProvider的Authority 4 public static final String AUTHORITY 5 = "org.crazyit.providers.dictprovider"; 6 //定义一个静态内部类 7 public static final class Word implements BaseColumns 8 { 9 // 定义Content所允许操作的3个数据列10 public final static String _ID = "_id";11 public final static String WORD = "word";12 public final static String DETAIL = "detail";13 // 定义该Content提供服务的两个Uri14 public final static Uri DICT_CONTENT_URI = 15 Uri.parse("content://" + AUTHORITY + "/words");16 public final static Uri WORD_CONTENT_URI = 17 Uri.parse("content://" + AUTHORITY + "/word"); 18 }19 }
上面的工具类只是定义了一些简单的常量的工具类,这个工具类的作用就是告诉其他应用访问该ContentProvider的一些常用的入口。
接下来开发一个ContentProvider的子类,并重写其中的增、删、改、查等方法,代码如下:1 public class DictProvider extends ContentProvider 2 { 3 private static UriMatcher matcher 4 = new UriMatcher(UriMatcher.NO_MATCH); 5 private static final int WORDS = 1; 6 private static final int WORD = 2; 7 private MyDatabaseHelper dbOpenHelper; 8 static 9 { 10 // 为UriMatcher注册两个Uri 11 matcher.addURI(Words.AUTHORITY, "words", WORDS); 12 matcher.addURI(Words.AUTHORITY, "word/#", WORD); 13 } 14 // 第一次调用该DictProvider时,系统先创建DictProvider对象,并回调该方法 15 @Override 16 public boolean onCreate() 17 { 18 dbOpenHelper = new MyDatabaseHelper(this.getContext(), "myDict.db3", 1); 19 return true; 20 } 21 // 插入数据方法 22 @Override 23 public Uri insert(Uri uri, ContentValues values) 24 { 25 // 获得数据库实例 26 SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); 27 // 插入数据,返回行ID 28 long rowId = db.insert("dict", Words.Word._ID, values); 29 // 如果插入成功返回uri 30 if (rowId > 0) 31 { 32 // 在已有的 Uri的后面追加ID数据 33 Uri wordUri = ContentUris.withAppendedId(uri, rowId); 34 // 通知数据已经改变 35 getContext().getContentResolver().notifyChange(wordUri, null); 36 return wordUri; 37 } 38 return null; 39 } 40 // 删除数据的方法 41 @Override 42 public int delete(Uri uri, String selection, String[] selectionArgs) 43 { 44 SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); 45 // 记录所删除的记录数 46 int num = 0; 47 // 对于uri进行匹配。 48 switch (matcher.match(uri)) 49 { 50 case WORDS: 51 num = db.delete("dict", selection, selectionArgs); 52 break; 53 case WORD: 54 // 解析出所需要删除的记录ID 55 long id = ContentUris.parseId(uri); 56 String where = Words.Word._ID + "=" + id; 57 // 如果原来的where子句存在,拼接where子句 58 if (selection != null && !selection.equals("")) 59 { 60 where = where + " and " + selection; 61 } 62 num = db.delete("dict", where, selectionArgs); 63 break; 64 default: 65 throw new IllegalArgumentException("未知Uri:" + uri); 66 } 67 // 通知数据已经改变 68 getContext().getContentResolver().notifyChange(uri, null); 69 return num; 70 } 71 // 修改数据的方法 72 @Override 73 public int update(Uri uri, ContentValues values, String selection, 74 String[] selectionArgs) 75 { 76 SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); 77 // 记录所修改的记录数 78 int num = 0; 79 switch (matcher.match(uri)) 80 { 81 case WORDS: 82 num = db.update("dict", values, selection, selectionArgs); 83 break; 84 case WORD: 85 // 解析出想修改的记录ID 86 long id = ContentUris.parseId(uri); 87 String where = Words.Word._ID + "=" + id; 88 // 如果原来的where子句存在,拼接where子句 89 if (selection != null && !selection.equals("")) 90 { 91 where = where + " and " + selection; 92 } 93 num = db.update("dict", values, where, selectionArgs); 94 break; 95 default: 96 throw new IllegalArgumentException("未知Uri:" + uri); 97 } 98 // 通知数据已经改变 99 getContext().getContentResolver().notifyChange(uri, null);100 return num;101 }102 // 查询数据的方法103 @Override104 public Cursor query(Uri uri, String[] projection, String selection,105 String[] selectionArgs, String sortOrder)106 {107 SQLiteDatabase db = dbOpenHelper.getReadableDatabase();108 switch (matcher.match(uri))109 {110 case WORDS:111 // 执行查询112 return db.query("dict", projection, selection, selectionArgs,113 null, null, sortOrder);114 case WORD:115 // 解析出想查询的记录ID116 long id = ContentUris.parseId(uri);117 String where = Words.Word._ID + "=" + id;118 // 如果原来的where子句存在,拼接where子句119 if (selection != null && !"".equals(selection))120 {121 where = where + " and " + selection;122 }123 return db.query("dict", projection, where, selectionArgs, null,124 null, sortOrder);125 default:126 throw new IllegalArgumentException("未知Uri:" + uri);127 }128 }129 // 返回指定uri参数对应的数据的MIME类型130 @Override131 public String getType(Uri uri)132 {133 switch (matcher.match(uri))134 {135 // 如果操作的数据是多项记录136 case WORDS:137 return "vnd.android.cursor.dir/org.crazyit.dict";138 // 如果操作的数据是单项记录139 case WORD:140 return "vnd.android.cursor.item/org.crazyit.dict";141 default:142 throw new IllegalArgumentException("未知Uri:" + uri);143 }144 }145 }
上面的DictProvider类继承了ContentProvider,并实现了操作数据的增、删、改、查等方法。接下来需要在AndroidManitest.xml文件中注册该ContentProvider,代码:
1 2
至此,整个ContentProvider开发完成,为了测试它,我们需要新建一个工程。
在新的工程里,我们需要把上面创建的工具类拷贝到新工程里,下面的是使用ContentProvider的代码:1 public class DictResolver extends Activity 2 { 3 ContentResolver contentResolver; 4 Button insert = null; 5 Button search = null; 6 @Override 7 public void onCreate(Bundle savedInstanceState) 8 { 9 super.onCreate(savedInstanceState);10 setContentView(R.layout.main);11 // 获取系统的ContentResolver对象12 contentResolver = getContentResolver();13 insert = (Button)findViewById(R.id.insert);14 search = (Button)findViewById(R.id.search); 15 // 为insert按钮的单击事件绑定事件监听器16 insert.setOnClickListener(new OnClickListener()17 {18 @Override19 public void onClick(View source)20 {21 //获取用户输入22 String word = ((EditText)findViewById(R.id.word))23 .getText().toString();24 String detail = ((EditText)findViewById(R.id.detail))25 .getText().toString();26 //插入生词记录27 ContentValues values = new ContentValues();28 values.put(Words.Word.WORD , word);29 values.put(Words.Word.DETAIL , detail);30 contentResolver.insert(Words.Word.DICT_CONTENT_URI , values);31 //显示提示信息32 Toast.makeText(DictResolver.this, "添加生词成功!" , 8000)33 .show();34 } 35 });36 // 为search按钮的单击事件绑定事件监听器37 search.setOnClickListener(new OnClickListener()38 {39 @Override40 public void onClick(View source)41 {42 // 获取用户输入43 String key = ((EditText) findViewById(R.id.key)).getText()44 .toString();45 // 执行查询46 Cursor cursor = contentResolver.query(47 Words.Word.DICT_CONTENT_URI, null 48 , "word like ? or detail like ?"49 , new String[]{"%" + key + "%" , "%" + key + "%"} 50 , null);51 //创建一个Bundle对象52 Bundle data = new Bundle();53 data.putSerializable("data", converCursorToList(cursor));54 //创建一个Intent55 Intent intent = new Intent(DictResolver.this56 , ResultActivity.class);57 intent.putExtras(data);58 //启动Activity59 startActivity(intent);60 }61 });62 }63 64 private ArrayList
至此,测试ContentProvider的关键代码已经给出了,希望能够帮助大家,在此也希望大家多多关注本人。