自定义ContentProvider的使用

一、自定义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);// 匹配任何文本

	}

	@Override
	public boolean onCreate() {

		Log.i(TAG, "==onCreate");
		dbHelper = new MySQLiteOpenHelper(getContext());
		db = dbHelper.getReadableDatabase();
		return true;

	}

	@Override
	public 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;
	}

	@Override
	public 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);
	}

	@Override
	public 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;
	}

	@Override
	public 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;
	}

	@Override
	public 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;

	@Override
	protected 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());

	}

	@Override
	public 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;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch (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);
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		// TODO Auto-generated method stub
		super.onCreateContextMenu(menu, v, menuInfo);
		getMenuInflater().inflate(R.menu.update, menu);
	}

	@Override
	public 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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值