android学习之contentProvider

翻译 2015年11月19日 16:41:49

一、相关ContentProvider概念解析:

1、ContentProvider简介
在Android官方指出的Android的数据存储方式总共有五种,分别是:Shared Preferences、网络存储、文件存储、外储存储、SQLite。但是我们知道一般这些存储都只是在单独的一个应用程序之中达到一个数据的共享,有时候我们需要操作其他应用程序的一些数据,例如我们需要操作系统里的媒体库、通讯录等,这时我们就可能通过ContentProvider来满足我们的需求了。

2、为什么要选择ContentProvider?

ContentProvider向我们提供了我们在应用程序之前共享数据的一种机制,而我们知道每一个应用程序都是运行在不同的应用程序的,数据和文件在不同应用程序之间达到数据的共享不是没有可能,而是显得比较复杂,而正好Android中的ContentProvider则达到了这一需求,比如有时候我们需要操作手机里的联系人,手机里的多媒体等一些信息,我们都可以用到这个ContentProvider来达到我们所需。

1)、ContentProvider为存储和获取数据提供了统一的接口。ContentProvide对数据进行封装,不用关心数据存储的细节。使用表的形式来组织数据。
2)、使用ContentProvider可以在不同的应用程序之间共享数据。 
3)、Android为常见的一些数据提供了默认的ContentProvider(包括音频、视频、图片和通讯录等)。 
总的来说使用ContentProvider对外共享数据的好处是统一了数据的访问方式。

3、Uri介绍

为系统的每一个资源给其一个名字,比方说通话记录。
1)、每一个ContentProvider都拥有一个公共的URI,这个URI用于表示这个ContentProvider所提供的数据。 
2)、Android所提供的ContentProvider都存放在android.provider包中。 将其分为A,B,C,D 4个部分:

\
A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的;"content://"
B:URI 的标识,用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的类名。这个标识在 元素的 authorities属性中说明:一般是定义该ContentProvider的包.类的名称
C:路径(path),通俗的讲就是你要操作的数据库中表的名字,或者你也可以自己定义,记得在使用的时候保持一致就可以了;"content://com.bing.provider.myprovider/tablename"
D:如果URI中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示返回全部; "content://com.bing.provider.myprovider/tablename/#" #表示数据id。

PS:

路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
1、要操作person表中id为10的记录,可以构建这样的路径:/person/10
2、要操作person表中id为10的记录的name字段, person/10/name
3、要操作person表中的所有记录,可以构建这样的路径:/person
4、要操作xxx表中的记录,可以构建这样的路径:/xxx
5、当然要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式,如下:
要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
6、如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:Uri uri = Uri.parse("content://com.bing.provider.personprovider/person")

4、UriMatcher类使用介绍

因为Uri代表了要操作的数据,所以我们经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher和ContentUris 。掌握它们的使用,会便于我们的开发工作。

5。 ContentProvider:为存储和获取数据提供统一的接口。可以在不同的应用程序之间共享数据。Android已经为常见的一些数据提供了默认的ContentProvider
  1、ContentProvider使用表的形式来组织数据
   无论数据的来源是什么,ContentProvider都会认为是一种表,然后把数据组织成表格
  2、ContentProvider提供的方法
   query:查询
   insert:插入
   update:更新
   delete:删除
   getType:得到数据类型
   onCreate:创建数据时调用的回调函数
  3、每个ContentProvider都有一个公共的URI,这个URI用于表示这个ContentProvider所提供的数据。Android所提供的ContentProvider都存放在android.provider包当中
 6、ContentProvider的内部原理
  自定义一个ContentProvider,来实现内部原理
  步骤:
  1、定义一个CONTENT_URI常量(里面的字符串必须是唯一)
  Public static final Uri CONTENT_URI = Uri.parse("content://com.WangWeiDa.MyContentprovider");
  如果有子表,URI为:
  Public static final Uri CONTENT_URI = Uri.parse("content://com.WangWeiDa.MyContentProvider/users");
  2、定义一个类,继承ContentProvider
  Public class MyContentProvider extends ContentProvider
  3、实现ContentProvider的所有方法(query、insert、update、delete、getType、onCreate)

这里上传自己写的contentProvider类

数据源Bean

package com.leige.stu.domain;

public class Student {
	private int id;
	private String name;
	private String sex;
	private int age;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Student(int id, String name, String sex, int age) {
		super();
		this.id = id;
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", sex=" + sex
				+ ", age=" + age + "]";
	}
	public Student() {
		super();
	}
	
	
}

ContentProvider类,详细解释都在类的注解中

欢迎大家纠错

package com.leige.stu.mycontentprovider;

import com.leige.stu.mysqllite.StudentSqlHelper;
import com.leige.stu.mysqllite.Studentdao;

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 MyProvider extends ContentProvider {
	private StudentSqlHelper helper;
	private static final UriMatcher uriMatcher;
	//定义authority
	private static final String authority="com.leige.stu.mycontentprovider.MyProvider";
	//定义匹配操作码
	private static final int STUDENT_INSERT_CODE = 0;
	private static final int STUDENT_UPDATE_CODE = 1;
	private static final int STUDENT_FINDBYID_CODE = 2;
	private static final int STUDENT_DELETE_CODE = 3;
	private static final int STUDENT_FINDALL_CODE = 4;
	static{
		//实例化UriMatcher
		uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
		//匹配路径content://com.leige.stu.mycontentprovider.MyProvider/student/insert
		uriMatcher.addURI(authority, "student/insert", STUDENT_INSERT_CODE);
		//匹配路径content://com.leige.stu.mycontentprovider.MyProvider/student/delete
		uriMatcher.addURI(authority, "student/delete", STUDENT_DELETE_CODE);
		//匹配路径content://com.leige.stu.mycontentprovider.MyProvider/student/update
		uriMatcher.addURI(authority, "student/update", STUDENT_UPDATE_CODE);
		//匹配路径content://com.leige.stu.mycontentprovider.MyProvider/student/findById/#
		uriMatcher.addURI(authority, "student/findById/#", STUDENT_FINDBYID_CODE);
		//匹配路径content://com.leige.stu.mycontentprovider.MyProvider/student/findAll
		uriMatcher.addURI(authority, "student/findAll", STUDENT_FINDALL_CODE);
	}
	@Override
	public boolean onCreate() {
		// TODO Auto-generated method stub
		//创建数据库
	
		helper=new StudentSqlHelper(getContext(), "stu.db",null , 1);
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// TODO Auto-generated method stub
		//得到数据库
		SQLiteDatabase db=helper.getReadableDatabase();
			switch (uriMatcher.match(uri)) {
			case STUDENT_FINDALL_CODE:
			{
				if(db.isOpen()){
				//查询得到游标对象,返回,查询所有
				Cursor cursor=db.query( "student", projection, selection,
						selectionArgs, null, null,sortOrder);
				return cursor;
				}
			}
				break;
			case STUDENT_FINDBYID_CODE:
			{
				if(db.isOpen()){//查询单个,
					int id=(int) ContentUris.parseId(uri);
					Cursor cursor=db.query("student",projection ,"_id=", 
							new String[]{1+""}, null, null, sortOrder);
					return cursor;
					
				}
			}
			break;
			default:
				break;
			}
			//返回游标,不能关闭db,切记
			//db.close();
		return null;
	}

	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		switch (uriMatcher.match(uri)) {
		case STUDENT_FINDALL_CODE:
			return "vnd.android.cursor.dir/student";
		case STUDENT_FINDBYID_CODE:
			return "vnd.android.cursor.item/student";
		default:
			break;	
		}
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// TODO Auto-generated method stub
		SQLiteDatabase db=helper.getWritableDatabase();
		switch (uriMatcher.match(uri)) {
		case STUDENT_INSERT_CODE:
		{
			if(db.isOpen()){
				long id=db.insert("student",null, values);
				db.close();
				return ContentUris.withAppendedId(uri, id);
			}
		}
			break;

		default:
			break;
		}
		return null;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		
		// TODO Auto-generated method stub
		SQLiteDatabase db=helper.getWritableDatabase();
		switch (uriMatcher.match(uri)) {
		case STUDENT_DELETE_CODE:
		{
			if(db.isOpen()){
				int count=db.delete("student",  selection, selectionArgs);
				db.close();
				return count;
				
			}
		}
			break;

		default:
			break;
		}
		return 0;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		// TODO Auto-generated method stub
		SQLiteDatabase db=helper.getWritableDatabase();
		switch (uriMatcher.match(uri)) {
		case STUDENT_UPDATE_CODE:
		{
			if(db.isOpen()){
				int count=db.update("student", values, selection, selectionArgs);
				db.close();
				return count;
				
			}
		}
			break;

		default:
			break;
		}
		return 0;
	}

}

contentProvider类写完后,需要发布到机器上,提供统一的uri接口可以被外部程序所访问,另外contentProvider是android的四大组件之一,所以需要在androidMainfest.xml文件中注册

例如

     <provider android:name=".mycontentprovider.MyProvider"
             android:authorities="com.leige.stu.mycontentprovider.MyProvider"
             android:readPermission="myprovider.read"
            android:writePermission="myprovider.write"
            >
   <!--
   自定义权限需要声明,才会被系统所认可,所以需要定义permission节点,声明自定义权限        
    android:readPermission="myprovider.read"
            android:writePermission="myprovider.write" -->         
        </provider>
这里定义了对contentprovider的读写权限设置,如果在其他程序中访问contentprovider,需要申请权限

测试类代码

package comleige.testcontentprovider.test;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;

public class MyTest extends AndroidTestCase {
	public void test(){
		//得到内容提供者的访问对象
		ContentResolver resolver = getContext().getContentResolver();
		//设定uri
		Uri uri=Uri.parse("content://com.leige.stu.mycontentprovider.MyProvider/student/insert");
		ContentValues values=new ContentValues();
		values.put("name", "磊哥2");
		values.put("sex", "男");
		values.put("age", 18);
		resolver.insert(uri, values);
	}

/*	public void testFindById(){
		ContentResolver resolver=getContext().getContentResolver();
		Uri uri=Uri.parse
	("content://com.leige.stu.mycontentprovider.MyProvider/student/findById/#");
		uri=ContentUris.withAppendedId(uri,1);
		Cursor cursor=resolver.query(uri,
				new String[]{"_id","name","sex","age"}, null, null, null);
		if(cursor!=null){
			cursor.moveToFirst();
			int id=cursor.getInt(0);
			String name=cursor.getString(1);
			String sex=cursor.getString(2);
			int age=cursor.getInt(3);
			Student s=new Student(id,name,sex,age);
			System.out.println(s);
			Log.i("err", s.toString());
			Log.d("err", "leige");
		}
	}*/
}



相关文章推荐

Android学习之自定义ContentProvider类

  • 2014年10月25日 18:00
  • 1.41MB
  • 下载

Android学习篇章38-ContentProvider-获取联系人信息

Mainactivity: public class MainActivity extends Activity { ListView listview=null; @Overrid...

Android学习19--使用ContentProvider实现数据共享

1、数据共享标准:ContentProvider简介 ContentProvider是不同应用程序之间进行数据交换的标准API,ContentProvider以某种Uri的形式对外提供数据,允许...

Android学习笔记(十)-数据共享标准:ContentProvider

当在系统中部署了一个又一个Android应用之后,系统里将会包含多个Android应用,有时候就需要在不同的应用之间共享数据,对于这种需要在不同应用之间共享数据的需求,当然可以让一个应用程序直接去操作...

Android学习第六周_SQLite和ContentProvider

一、SQLite1、基本概念 SQLite是一个轻量级、独立、隔离、跨平台、多语言接口、安全性高的关系型数据库,主要用于嵌入式设备之上,Android中的数据库就是使用的是SQLite数据库。 2...

步步为营_Android开发课[6]_ContentProvider学习

Focus on technology, enjoy life!—— QQ:804212028 浏览链接:http://blog.csdn.net/y18334702058/article/det...

android学习ContentProvider

摘要: 本文主要记录了android四大组件之ContentProvider的作用,用法和主要api 等,内容比较简单,仅仅做于学习内容的回顾和温习之用,不妥之处敬请指出。 1.Co...

android组件ContentProvider学习心得(上)

应用和应用之间的数据通常都不是孤立的,每个应用都需要与其他的应用来交换数据,例如,我们安装在手机上的安全软件提供了来电防火墙的功能,这个时候安全软件通常会需要访问我们手机自带通信录中数据。在andro...

Android学习-四大组件(ContentProvider)

今天继续复习内容提供者,ContentProvider可以实现不同程序之间的数据共享和数据操作。...
  • hamotim
  • hamotim
  • 2016年02月22日 20:53
  • 119

Pro Android学习笔记(一)——ContentProvider(上)

简要介绍了ContentProvider的概念,所涉及到的知识。
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android学习之contentProvider
举报原因:
原因补充:

(最多只允许输入30个字)