【Android基础】内容提供者ContentProvider的使用详解

1.什么是ContentProvider

首先,ContentProvider(内容提供者)是android中的四大组件之一,但是在一般的开发中,可能使用的比较少。

ContentProvider为不同的软件之间数据共享,提供统一的接口。也就是说,如果我们想让其他的应用使用我们自己程序内的数据,就可以使用ContentProvider定义一个对外开放的接口,从而使得其他的应用可以使用咱们应用的文件、数据库内存储的信息。当然,自己开发的应用需要给其他应用共享信息的需求可能比较少见,但是在Android系统中,很多系统自带应用,比如联系人信息,图片库,音频库等应用,为了对其他应用暴露数据,所以就使用了ContentProvider机制。所以,我们还是要学习ContentProvider的基本使用,在遇到获取联系人信息,图片库,音频库等需求的时候,才能更好的实现功能

2.如何定义一个ContentProvider

Android系统为了让我们更好的对外暴露数据,提供了统一的接口,所以定义了抽象类ContentProvider,因此,如果我们想对外提供数据,我们需要继承ContentProvider,并且实现下面的这几个方法:

onCreate()
当我们的provider初始化时被调用,我们应该在这个方法里面完成部分初始化操作

query() 查询方法,用于给调用者返回数据

insert() 插入操作,用于让外部应用插入数据到内容提供者中

update() 更新操作,用于更新内容提供者的数据

delete() 用于删除数据

getType 返回内容提供者的MIME Type

上面这些方法,当我们继承自ContentProvider的时候,eclipse会自动的给我们添加,但是这并不代表我们每个方法都需要自定义实现。如果我们只希望给其他应用提供数据,而不允许其他应用修改我们的数据,那么我们只需要实现onCreate(),getType()和query()这三个方法就可以了,其他的三个方法我们可以根据业务需求,实现或者是不实现。

因为一般使用ContentProvider向外部暴露数据库的信息,因此,本篇将以使用ContentProvider向其他应用暴露数据库信息为例,讲解ContentProvider的基本使用。

Android中SQLite数据库的创建和使用,本篇不再介绍,不清楚的请看这篇文章

SQLite数据库的简单实用

假设读者已经学会了SQLite数据库的使用,并且已经建立好了数据库,下面我们开始写我们的ContentProvider。

因为注释解析的比较详细,所以就不过多解释了

/**
 * 内容提供者
 *
 * @author ZhaoKaiQiang
 * @time 2014年6月6日
 */
public class StudentProvider extends ContentProvider {
	// 数据库操作类,用于获取SQLiteDatabase
	private MyDbOpenHelper dbHelper;

	private static final int STUDENT = 1;
	private static final int STUDENTS = 2;

	// UriMatcher类是一个很重要的类,因为我们需要根据传入的uri,来判断执行相对应的操作
	private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);

	// 静态代码块用于初始化MATCHER需要匹配的uri
	static {
		// MATCHER.addURI(主机名(用于唯一标示一个ContentProvider,这个需要和清单文件中的authorities属性相同),路径(可以用来表示我们要操作的数据,路径的构建应根据业务而定),返回值(用于匹配uri的时候,作为匹配的返回值));
		MATCHER.addURI("com.example.mydbdemo.StudentProvider", "student", STUDENTS);
		MATCHER.addURI("com.example.mydbdemo.StudentProvider", "student/#", STUDENT);
	}

	// 进行数据的初始化操作
	@Override
	public boolean onCreate() {
		dbHelper = new MyDbOpenHelper(getContext());
		return false;
	}

	// 查询
	// 如果uri为		content://com.example.mydbdemo.StudentProvider/student
	// 则代表查询所有的student表内的数据
	// 如果uri为		content://com.example.mydbdemo.StudentProvider/student/6
	// 则代表查询student表内id=6的数据
	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

		SQLiteDatabase db = dbHelper.getReadableDatabase();
		//判断传入的uri到底匹配哪一个,从而实现不同的业务需求
		switch (MATCHER.match(uri)) {
		//查询全部的学生信息
		case STUDENTS:
			//db.query(表明, 要查询的列(是一个String数组), where条件, where条件中的参数, groupBy, having, sortOrder);
			return db.query("student", projection, selection, selectionArgs, null, null, sortOrder);
		//查询某一个id对应的学生的信息
		case STUDENT:
			//取出我们要查询的数据的id
			long id = ContentUris.parseId(uri);
			String where = "id=" + id;
			//将selection查询信息拼接到我们的where条件中
			if (selection != null && !"".equals(selection)) {
				where = selection + " and " + where;
			}
			return db.query("student", projection, where, selectionArgs, null, null, sortOrder);
		//如uri不匹配,抛出不合法参数的异常
		default:
			throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
		}

	}

	// 插入
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		switch (MATCHER.match(uri)) {
		case STUDENTS:
			long id = db.insert("student", "name", values);
			return ContentUris.withAppendedId(uri, id);
		default:
			throw new IllegalArgumentException("Uri不匹配");
		}

	}

	//删除数据
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		int count = 0;
		switch (MATCHER.match(uri)) {
		case STUDENTS:
			count = db.delete("student", selection, selectionArgs);
			return count;

		case STUDENT:
			long id = ContentUris.parseId(uri);
			String where = "id=" + id;
			if (selection != null && !"".equals(selection)) {
				where = selection + " and " + where;
			}
			count = db.delete("student", where, selectionArgs);
			return count;

		default:
			throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
		}
	}

	//更新数据
	@Override
	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
		SQLiteDatabase db = dbHelper.getWritableDatabase();
		int count = 0;
		switch (MATCHER.match(uri)) {
		case STUDENTS:
			count = db.update("student", values, selection, selectionArgs);
			return count;

		case STUDENT:
			long id = ContentUris.parseId(uri);
			String where = "id=" + id;
			if (selection != null && !"".equals(selection)) {
				where = selection + " and " + where;
			}
			count = db.update("student", values, where, selectionArgs);
			return count;

		default:
			throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
		}
	}

	// 用于获取MIME Type
	@Override
	public String getType(Uri uri) {
		switch (MATCHER.match(uri)) {
		case STUDENT:
			return "vnd.android.cursor.item/student";
		case STUDENTS:
			return "vnd.android.cursor.dir/student";
		default:
			throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
		}

	}

}

我们在定义好我们的ContentProvider之后,因为ContentProvider数据四大组件之一,因此我们还需要在AndroidManifest清单文件中进行注册才能使用,下面是注册信息

<!-- 不要忘记exported这个属性,如果不加,可能会导致外部程序访问失败,错误信息为权限拒绝 -->
 		<!-- authorities这个属性就是我们在ContentProvider中使用的addURI方法时的第一个参数的取值 -->
        <provider
            android:name="com.example.mydbdemo.StudentProvider"
            android:exported="true"
            android:authorities="com.example.mydbdemo.StudentProvider" >
        </provider>

注意,provider的声明和activity一样,都是在application节点进行声明的。

至此,我们就完成了我们自己的ContentProvider的生命,其他的应用现在就可以使用我们往外部暴露的数据信息了。

3.外部应用如何使用我们的ContentProvider

我们已经定义好了我们自己的ContentProvider,那么外部应用如何调用呢?

下面,我将新建一个测试单元工程,完成对ContentProvider的各个方法的测试

添加方法测试

//使用ContentProvider添加数据的测试
	public void testadd() throws Throwable {
		//获取ContentResolver对象,完成对ContentProvider的调用
		ContentResolver contentResolver = this.getContext().getContentResolver();
		//构建我们的uir,这个uri
		Uri insertUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student");
		ContentValues values = new ContentValues();
		values.put("name", "zhaokaikai");
		values.put("age", 91);
		values.put("school", "bbbb");
		//返回值为我们刚插入进入的数据的uri地址
		Uri uri = contentResolver.insert(insertUri, values);
		Log.i(TAG, uri.toString());
	}

删除方法测试

//使用ContentProvider删除数据的测试
	public void testDelete() throws Throwable {
		ContentResolver contentResolver = this.getContext().getContentResolver();
		//删除id为6的学生信息
		Uri deleteUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student/6");
		contentResolver.delete(deleteUri, null, null);
	}

修改方法测试

//使用ContentProvider更新数据的测试
	public void testUpdate() throws Throwable {
		ContentResolver contentResolver = this.getContext().getContentResolver();
		//更新id = 6 的学生信息
		Uri updateUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student/6");
		ContentValues values = new ContentValues();
		values.put("name", "testUp");
		values.put("age", "101");
		values.put("school", "ccccc");
		contentResolver.update(updateUri, values, null, null);
	}
//使用ContentProvider查询数据的测试
	public void testFind() throws Throwable {
		ContentResolver contentResolver = this.getContext().getContentResolver();
		//这个uri用于查询所有的数据,若查询某个id的数据,则构建下面的uri
		//Uri selectUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student/要查询的id");
		Uri selectUri = Uri.parse("content://com.example.mydbdemo.StudentProvider/student");
		Cursor cursor = contentResolver.query(selectUri, null, null, null, "id desc");
		while (cursor.moveToNext()) {
			int id = cursor.getInt(cursor.getColumnIndex("id"));
			String name = cursor.getString(cursor.getColumnIndex("name"));
			int age = cursor.getInt(cursor.getColumnIndex("age"));
			String school = cursor.getString(cursor.getColumnIndex("school"));
			Log.i(TAG, "id=" + id + ",name=" + name + ",age=" + age +",school="+school);
		}
	}

上面的方法都经过了单元测试。

好了,至此,我们就使用ContentProvider实现了在第三方应用中对我们应用的数据库进行增删改查等操作,如有疑问,请留言。

【Android基础】内容提供者ContentProvider的使用详解

时间: 2024-10-21 21:18:01

【Android基础】内容提供者ContentProvider的使用详解的相关文章

Android中内容提供者ContentProvider实现数据库增删改查

1.我们首先new一个我们自己的类集成ContentProvider,并实现方法如下 package com.wzw.sqllitedemo.providers; import com.wzw.sqllitedemo.db.PersonSQLiteOpenHelper; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues;

[Android Pro] 内容提供者ContentProvider的基本使用

一.ContentProvider简介 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.ContentProvider为存储和获取数据提供了统一的接口.虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如采用文件方式对外共享数据,需要进行文件操作读写数据:采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据.而使用ContentProvider共享数据的

Android之内容提供者ContentProvider的总结

本文包含以下知识点: ContentProvider Uri 的介绍 ContentResolver: 监听ContentProvider的数据改变 一:ContentProvider部分 ContentProvider的作用: Content providers store and retrieve data and make it accessible to all applications. They're the only way to share data across applica

[Android Pro] 监听内容提供者ContentProvider的数据变化

转载自:http://blog.csdn.net/woshixuye/article/details/8281385 一.提出需求 有A,B,C三个应用,B中的数据需要被共享,所以B中定义了内容提供者ContentProvider:A应用修改了B应用的数据,插入了一条数据.有这样一个需求,此时C应用需要得到数据被修改的通知并处理相应操作. 二.示例代码 A应用 /** * 对内容提供者进行操作 * * @author XY * */ public class MainActivity exten

Android四大组件之内容提供者--ContentProvider

Android四大组件之内容提供者--ContentProvider 1,什么是ContentProvider ContentProvider将应用中的数据对其它应用进行共享, 提供增删改查的方法 ContentProvider统一了数据的访问方式,不必针对不同数据类型采取不同的访问策略 ContentProvider将数据封装,只暴露出我们希望提供给其它程序的数据 ContentProvider中可以注册观察者, 监听数据的变化 2,怎么创建 2.1定义类继承ContentProvider,

Android开发之内容提供者ContentProvider

2 内容提供者ContentProvider 一.ContentProvider简介 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据:采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据.而使用ContentProvider共享数据的好处是统一了数据

Android学习---通过内容提供者(ContentProvider)操作另外一个应用私有数据库的内容

一.什么是ContentProvider? ContentProvider直译过来就是内容提供者,主要作用就是A应用提供接口给B应用调用数据,和之前介绍的sharedPreference和直接开放文件访问类似,都是共享应用程序数据,不同的是之前的两种文件格式可能完全不同,如可能为xml,txt,sql等等,这里ContentProvider返回的数据格式是统一的,因此应用的更为广泛一点. 二.实例 这里使用的是A应用通过ContentProvider共享数据给B应用.这里A应用用的是前文中的an

内容提供者ContentProvider

首先在需要提供内容提供者的应用中添加内容提供者的代码 package com.example.sqllite; import com.example.sqllite.servise.DBOpenHelp; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher

android之内容提供者解析

该系统有两个应用,比较繁琐.但是内容提供者是android里非常非常重要的一个内容,我们得好好学习下哦.先看效果图,我们提供了四个按钮,点击按钮便会进行相应的操作. 我们先看内容提供者所在的应用,代码结构: activity代码: [java] view plaincopy package cn.com.contentProvider; import android.app.Activity; import android.os.Bundle; import android.widget.Tex