Android中内容提供者ContentProvider的使用

内容提供者是安卓四大组件之一。

如果a应用想把自己的数据库暴露给别的应用程序使用,就必须实现contentprovider 。

创建一个类 继承系统的ContentProvider一定要在清单文件里面配置 放入application结点下。(作为一个组件)

指定uri的主机名com.example.provider.personprovider。

        <provider android:name="com.example.provider.PersonProvider"
            android:authorities="com.example.provider.personprovider"
            >
                        <!-- 通过一个地址来暴露内容 -->
            
        </provider>


下面给出PersonProvider代码。

第一步,定义macher工具   public static final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);

第二步,定义一些常量

public static final int ALL_PERSONS = 1;
public static final int PERSON = 2;
public static final int HAHA = 3;
public static final int INSERT = 4;
public static final int DELETE = 5;
public static final int UPDATE = 6;

第三步,定义此程序将要暴露的路径,在静态代码块中定义。



static {
/**
* com.example.provider.personprovider 清单文件中的主机名
* */
matcher.addURI("com.example.provider.personprovider", "persons",
ALL_PERSONS);
// 指定一个路径的匹配规则
// 如果路径 满足 content://com.example.provider.personprovider/persons 返回值就是(
// ALL_PERSONS) 1
matcher.addURI("com.example.provider.personprovider", "person/#",
PERSON);
// 如果路径 满足 content://com.example.provider.personprovider/person/10
// 返回值就是( PERSON) 2
matcher.addURI("com.example.provider.personprovider", "haha", HAHA);
matcher.addURI("com.example.provider.personprovider", "insert", INSERT);
matcher.addURI("com.example.provider.personprovider", "delete", DELETE);
matcher.addURI("com.example.provider.personprovider", "update", UPDATE);
}



第四步,实现重写的方法。


package com.example.provider;

import com.example.db1.DBHelper;
import com.example.db1.PersonDAO;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public class PersonProvider extends ContentProvider {

	public static final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
	public static final int ALL_PERSONS = 1;
	public static final int PERSON = 2;
	public static final int HAHA = 3;
	public static final int INSERT = 4;
	public static final int DELETE = 5;
	public static final int UPDATE = 6;
	private DBHelper helper;
	Uri baseuri = Uri.parse("content://cn.itcast.db.personprovider");
	static {
		/**
		 * com.example.provider.personprovider 清单文件中的主机名
		 * */
		matcher.addURI("com.example.provider.personprovider", "persons",
				ALL_PERSONS);
		// 指定一个路径的匹配规则
		// 如果路径 满足 content://com.example.provider.personprovider/persons 返回值就是(
		// ALL_PERSONS) 1
		matcher.addURI("com.example.provider.personprovider", "person/#",
				PERSON);
		// 如果路径 满足 content://com.example.provider.personprovider/person/10
		// 返回值就是( PERSON) 2
		matcher.addURI("com.example.provider.personprovider", "haha", HAHA);
		matcher.addURI("com.example.provider.personprovider", "insert", INSERT);
		matcher.addURI("com.example.provider.personprovider", "delete", DELETE);
		matcher.addURI("com.example.provider.personprovider", "update", UPDATE);
	}

	/**
	 * PeronProvder 内容提供者第一次被创建的时候 调用的方法 这里给一个得到和数据库的变量
	 */
	@Override
	public boolean onCreate() {
		helper = new DBHelper(getContext());
		return false;
	}

	/**
	 * 有的时候 我们需要知道内容提供者返回的数据类型 知道返回的数据 是一个集合呀 还是一个单独的条目
	 * 
	 * 有的时候 告诉调用者 返回的数据是什么样的类型 mime的数据类型
	 */
	@Override
	public String getType(Uri uri) {
		int result = matcher.match(uri);
		switch (result) {
		// 符合 content://com.example.provider.personprovider/persons 代表的返回所有的数据
		case ALL_PERSONS:
			return "vnd.android.cursor.dir/people";
			// content://com.example.provider.personprovider/person/10
		case PERSON:
			return "vnd.android.cursor.item/people";
		default:
			return null;
		}
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		int result = matcher.match(uri);

		switch (result) {
		case DELETE:
			SQLiteDatabase db = helper.getWritableDatabase();
			getContext().getContentResolver().notifyChange(baseuri, null);
			return db.delete("person", selection, selectionArgs);
		default:
			throw new IllegalArgumentException("uri 不能被识别 ");
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// content://com.example.provider.personprovider/insert
		int result = matcher.match(uri);

		switch (result) {
		case INSERT:
			SQLiteDatabase db = helper.getWritableDatabase();
			db.insert("person", "personid", values);
			// 当数据发生改变的时候
			getContext().getContentResolver().notifyChange(baseuri, null);

			return uri;
		default:
			throw new IllegalArgumentException("uri 不能被识别 ");
		}
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {

		int result = matcher.match(uri);
		switch (result) {
		// 符合content://com.example.provider.personprovider/persons 代表返回所有数据
		case ALL_PERSONS:

			PersonDAO dao = new PersonDAO(getContext());

			return dao.findAllbyCursor();

		case PERSON:
			long id = ContentUris.parseId(uri);
			helper = new DBHelper(getContext());
			SQLiteDatabase sb = helper.getReadableDatabase();
			if (sb.isOpen()) {
				Cursor cursor = sb.query("person", null, "personid=?",
						new String[] { id + "" }, null, null, null);
				return cursor;
			}

		case HAHA:
			android.util.Log.i("TAG", "我是haha对应的路径");
			break;

		default:
			throw new IllegalArgumentException("uri不能被识别");
		}

		return null;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		int result = matcher.match(uri);

		switch (result) {
		case UPDATE:
			SQLiteDatabase db = helper.getWritableDatabase();
			getContext().getContentResolver().notifyChange(baseuri, null);
			return db.update("person", values, selection, selectionArgs);

		default:
			throw new IllegalArgumentException("uri 不能被识别 ");
		}
	}

}


</pre><p></p><pre>

这样,此程序就暴露了自己的数据。别的程序就可以访问它提供的方法来操作它的数据了。

比如在另一个项目中,可以这样写

必须先得到ContentReolver。

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		ContentResolver resolver=getContentResolver();
		Uri  uri=Uri.parse("content://com.example.provider.personprovider/haha");//定义uri
		Cursor cursor=resolver.query(uri, null, null, null, null);//null为查询条件 可以不关心
		while(cursor!=null&&cursor.moveToNext()){
			String name=cursor.getString(cursor.getColumnIndex("name"));
			System.out.println("姓名"+name);
		}
		
	}

}


在程序中添加这行代码getContext().getContentResolver().notifyChange(baseuri, null);

当数据发生变化时会通知baseuri数据的变化。

在另一个应用中,可以监听到其他程序的数据变化。


public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);		
		Uri  uri=Uri.parse("content://com.example.provider.personprovider/");//定义uri		
		//content://com.example.provider.personprovider
		//注册了内容观察者
		getContentResolver().registerContentObserver(uri, true, new MyObserver(new Handler()));
					
	}
	
	/**
	 * 当内容观察者发现了数据发生改变的时候调用的方法
	 * */
		public class MyObserver extends ContentObserver{

			public MyObserver(Handler handler) {
				super(handler);
			}
			
			
			@Override
			public void onChange(boolean selfChange) {
			super.onChange(selfChange);
			System.out.println("数据发生了改变");
			}
			
		}
		


}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值