自定义ContentProvider的使用

来源:互联网 发布:mysql创建普通索引 编辑:程序博客网 时间:2024/06/06 00:29
一、自定义ContentProvider:
(一)、操作步骤:

1、编写一个类,必须继承自ContentProvider类;

2、实现ContentProvider类中所有的抽象方法;

    需要实现:onCreate() 、getType() 、query() 、insert() 、update()、delete() 等方法。


【备注:】

ContentProvider暴露出来的数据和方法并不是给自身调用的,而是给其他应用程序来调用。其他应用程序通过其ContentResolver对象调用的query() 、insert() 、update()、delete() 等方法就是我们在这里暴露出来的ContentProvider类中的重写后的query() 、insert() 、update()、delete() 方法。

3、定义ContentProvider的Uri。这个Uri是ContentResolver对象执行CRUD操作时重要的参数;

4、使用UriMatcher对象映射Uri返回代码;

5、在AndroidMainfest.xml文件中使用<provider>标签注册ContentProvider。


(二)、ContentProvider类中的六个抽象方法:

1、boolean onCreate() 

2、Uri insert(Uri uri, ContentValues values)

3、int delete(Uri uri, String selection, String[] selectionArgs)

4、int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)

5、Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 

6、String getType(Uri uri) 


(三)、ContentProvider类中六个抽象方法的说明:

1、onCreate()   初始化provider

2、query()         返回数据给调用者

3、insert()         插入新数据到ContentProvider

4、update()       更新ContentProvider已经存在的数据

5、delete()        从ContentProvider中删除数据

6、getType()    返回ContentProvider数据的Mime类型


(四)、在清单文件中声明注册ContentProvider:


<provider android:name=".MyProvider"
android:authorities="com.hht.englishwordsprovider"
android:exported="true"
/>

//android:name属性的值是:ContentProvider类的子类的完整路径;
//android:authorities属性的值是:content:URI中authority部分。一般就是将name属性的值全小写。
//android:exported属性是否允许其他应用调用。如果是false,则该ContentProvider不允许其他应用调用。

(五)、UriMatcher:
        继承ContentProvider类后发现,ContentProvider类中只有一个onCreate()生命周期方法——当其他应用程序通过ContentResolver第一次访问该ContentProvider时,onCreate()会被回调。
        其他应用在通过ContentResolver对象执行CRUD操作时,都需要一个重要的参数Uri。为了能顺利提供这个Uri参数,Android系统提供了一个UriMatcher工具类。

UriMatcher工具类提供了两个方法:
1、void addURI(String authority , String path , int code)  :  该方法用于向UriMatcher对象注册Uri。其中authority和path是Uri中的重要部分。而code代表该Uri对应的标示符。
2、int match(Uri uri) : 根据注册的Uri来判断指定的Uri对应的标示符。如果找不到匹配的标示符,该方法返回-1。

private static UriMatcher matcher = null;
static {
// 定义一个Uri匹配器。将UriMatcher.NO_MATCH,即-1作为参数。
matcher = new UriMatcher(UriMatcher.NO_MATCH);
// 定义一组匹配规则
matcher.addURI(AUTHORITY, "words", 1);
matcher.addURI(AUTHORITY, "newwords", 2);
}

【备注:】
        ContentProvider是单例模式的,当多个应用程序通过使用ContentResolver 来操作使用ContentProvider 提供的数据时,ContentResolver 调用的数据操作会委托给同一个ContentProvider 来处理。这样就能保证数据的一致性。
实例代码:
package com.hht.android14_wordstest;import java.util.regex.Pattern;import android.content.ContentProvider;import android.content.ContentValues;import android.content.UriMatcher;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.net.Uri;import android.util.Log;public class Myprovider extends ContentProvider {private static final String TAG = "Myprovider";private MySQLiteOpenHelper dbHelper = null;private SQLiteDatabase db = null;private static UriMatcher matcher = null;private static final String AUTHORITY = "com.hht.englishwordsprovider";private static final int CODE1 = 1;private static final int CODE2 = 2;private static final int CODE3 = 3;static {matcher = new UriMatcher(UriMatcher.NO_MATCH);matcher.addURI(AUTHORITY, "englishwords", CODE1);matcher.addURI(AUTHORITY, "newwords", CODE2);matcher.addURI(AUTHORITY, "englishwords/*", CODE3);// 匹配任何文本}@Overridepublic boolean onCreate() {Log.i(TAG, "==onCreate");dbHelper = new MySQLiteOpenHelper(getContext());db = dbHelper.getReadableDatabase();return true;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {Cursor cursor = null;switch (matcher.match(uri)) {case CODE1:// Log.i(TAG, "==query");cursor = db.query("englishwords", projection, selection,selectionArgs, null, null, sortOrder);Log.i(TAG, "==query" + cursor.getCount());break;case CODE2:cursor = db.query("newwords", projection, selection, selectionArgs,null, null, sortOrder);break;case CODE3:Log.i("MyProvider", "==返回值是:" + matcher.match(uri));String data = uri.getLastPathSegment();Log.i("MyProvider", "==" + data);if (isChineseWord(data)) {cursor = db.query("englishwords", projection, "detail like ?",new String[] { data + "%" }, null, null, sortOrder);} else if (isNumber(data)) {cursor = db.query("englishwords", projection, "_id=?",new String[] { data }, null, null, sortOrder);} else {cursor = db.query("englishwords", projection, "words like ?",new String[] { data + "%" }, null, null, sortOrder);}}return cursor;}@Overridepublic Uri insert(Uri uri, ContentValues values) {long id = 0;String resultUri = "";switch (matcher.match(uri)) {case CODE1:id = db.insert("englishwords", null, values);resultUri = "content://" + AUTHORITY + "/englishwords/" + id;case CODE2:id = db.insert("newwords", null, values);resultUri = "content://" + AUTHORITY + "/newwords/" + id;}return Uri.parse(resultUri);}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {int count = 0;switch (matcher.match(uri)) {case CODE1:count = db.delete("englishwords", selection, selectionArgs);break;case CODE2:count = db.delete("newwords", selection, selectionArgs);break;}return count;}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {int count = 0;switch (matcher.match(uri)) {case CODE1:count = db.update("englishwords", values, selection, selectionArgs);break;case CODE2:count = db.update("newwords", values, selection, selectionArgs);break;}return count;}@Overridepublic String getType(Uri uri) {return null;}public static boolean isNumber(String str) {Pattern pattern = Pattern.compile("[0-9]+");return pattern.matcher(str).matches();}public static boolean isChineseWord(String str) {Pattern pattern = Pattern.compile("[\u4e00-\u9fa5]+");return pattern.matcher(str).matches();}}

在另一个应用中利用我们暴漏的ContentProvider获得数据,封装一个工具类进行CRUD操作
package com.hht.homework_testwordsprovider.utils;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.util.Log;public class MyWordsHelper {// 获取单词信息public static List<Map<String, Object>> selectWords(ContentResolver resolver) {List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();String uri_englishwords = "content://com.hht.englishwordsprovider/englishwords";// 从englishwords表中或许英文单词。Cursor cursor_englishwords = resolver.query(Uri.parse(uri_englishwords),new String[] { "_id", "words", "detail" }, null, null, null);// 遍历所有的单词的信息while (cursor_englishwords.moveToNext()) {int _id = cursor_englishwords.getInt(cursor_englishwords.getColumnIndex("_id"));String words = cursor_englishwords.getString(cursor_englishwords.getColumnIndex("words"));String detail = cursor_englishwords.getString(cursor_englishwords.getColumnIndex("detail"));Map<String, Object> map = new HashMap<String, Object>();map.put("_id", _id);map.put("words", words);map.put("detail", detail);list.add(map);}Log.i("hht", "==" + list.toString());return list;}// 以下代码是更新单词的方法。public static boolean updateWords(ContentResolver resolver,Map<String, Object> map, int id) {String uri_englishwords = "content://com.hht.englishwordsprovider/englishwords";ContentValues values = new ContentValues();// 修改englishwords表中的数据values.put("words", map.get("words").toString());values.put("detail", map.get("detail").toString());int count1 = resolver.update(Uri.parse(uri_englishwords), values,"_id=?", new String[] { id + "" });if (count1 > 0) {return true;} else {return false;}}public static void insertWords(ContentResolver resolver,Map<String, Object> map) {String uri_englishwords = "content://com.hht.englishwordsprovider/englishwords";Uri uri = Uri.parse(uri_englishwords);ContentValues values = new ContentValues();// englishwords向表中添加用户名称信息values.put("words", map.get("words").toString());values.put("detail", map.get("detail").toString());resolver.insert(uri, values);}// 以下代码是删除englishwords表中单词的方法。public static int deleteWords(ContentResolver resolver, String where,String[] whereArgs) {String uri_englishwords = "content://com.hht.englishwordsprovider/englishwords";return resolver.delete(Uri.parse(uri_englishwords), where, whereArgs);}}

在主文件中利用工具类封装的方法进行CRUD操作就行了
package com.hht.homework_testwordsprovider;import java.util.ArrayList;import java.util.List;import java.util.Map;import android.app.Activity;import android.content.ContentResolver;import android.content.Intent;import android.database.Cursor;import android.os.Bundle;import android.view.ContextMenu;import android.view.ContextMenu.ContextMenuInfo;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.AdapterView.AdapterContextMenuInfo;import android.widget.ListView;import android.widget.SimpleAdapter;import com.hht.homework_testwordsprovider.utils.MyWordsHelper;public class MainActivity extends Activity {private ListView listView_main_words;private List<Map<String, Object>> totallist = null;private SimpleAdapter adapter = null;private Cursor cursor = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);listView_main_words = (ListView) findViewById(R.id.listView_main_word);this.registerForContextMenu(listView_main_words);// 加载适配器totallist = new ArrayList<Map<String, Object>>();adapter = new SimpleAdapter(this, totallist,R.layout.item_listview_main, new String[] { "_id", "words","detail" }, new int[] { R.id.textView_id,R.id.textView_item_words, R.id.textView_item_detail });listView_main_words.setAdapter(adapter);// 适配器数据的填充fillListView(getlist());}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// TODO Auto-generated method stubswitch (item.getItemId()) {// 插入操作case R.id.action_insert:Intent intent = new Intent(MainActivity.this, AddActivity.class);startActivity(intent);break;case R.id.action_query:// 查询操作Intent intent2 = new Intent(MainActivity.this, SearchActivity.class);startActivity(intent2);break;default:break;}return super.onOptionsItemSelected(item);}@Overridepublic void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {// TODO Auto-generated method stubsuper.onCreateContextMenu(menu, v, menuInfo);getMenuInflater().inflate(R.menu.update, menu);}@Overridepublic boolean onContextItemSelected(MenuItem item) {// TODO Auto-generated method stub// 上下文菜单的使用,及选择事件的监听AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();switch (item.getItemId()) {case R.id.action_update:// 更新操作Intent intent = new Intent(MainActivity.this, UpdateActivity.class);Bundle bundle = new Bundle();bundle.putInt("_id",Integer.parseInt(totallist.get(info.position).get("_id").toString()));bundle.putString("words", totallist.get(info.position).get("words").toString());bundle.putString("detail",totallist.get(info.position).get("detail").toString());intent.putExtras(bundle);startActivity(intent);break;case R.id.action_delete:// 删除操作,利用封装的工具类只需要传人指定的参数就行int id = Integer.parseInt(totallist.get(info.position).get("_id").toString());ContentResolver resolver = getContentResolver();MyWordsHelper.deleteWords(resolver, "_id=?",new String[] { id + "" });Intent intent1 = new Intent(MainActivity.this, MainActivity.class);startActivity(intent1);finish();break;}return super.onContextItemSelected(item);}// 适配器数据更新函数public void fillListView(List<Map<String, Object>> list) {totallist.addAll(list);adapter.notifyDataSetChanged();}// 获得列表数据,作为ListView的数据源public List<Map<String, Object>> getlist() {ContentResolver contentResolver = getContentResolver();List<Map<String, Object>> list = MyWordsHelper.selectWords(contentResolver);return list;}}

还有几个子文件我就不一一贴出来了,主要是看一下怎样自己自定义ContentProvider及使用自定义的ContentProvider

0 0