`
liaokang.java
  • 浏览: 155527 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

Android ContentProvider共享数据

阅读更多
ContentProvider的基本概念
a.ContentProvider为存储和读取数据提供了统一的接口
b.使用ContentProvider,应用程序可以实现数据共享
c.android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)

1.数据模型
    Content Provider 将其存储的数据以数据表的形式提供给访问者,在数据表中每一行为一条记录,每一列为具有特定类型和意义的数据。每一条数据记录都包括一个 "_ID" 数值字段,改字段唯一标识一条数据。

2.Uri
    Uri,每一个Content Provider 都对外提供一个能够唯一标识自己数据集(dataset)的公开URI, 如果一个Content Provider管理多个数据集,其将会为每个数据集分配一个独立的URI。所有的Content Provider 的URI 都以"content://" 开头,其中"content:"是用来标识数据是由Content Provider管理的 schema。

      在几乎所有的Content Provider 的操作中都会用到Uri,因此一般来讲,如果是自己开发的Content Provider,最好将URI定义为常量,这样在简化开发的同时也提高了代码的可维护性。

我们将Uri分为A,B,C,D 4个部分:

A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的"content://"

B:Uri的标识,它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的,小写的类名。这个标识在元素的authorities属性中说明:一般是定义该ContentProvider的包.类的名称,如"content://com.lamp.provider.personprovider"

C:路径,Uri下的某一个Item,就像网站一样,主网页下包含很多小网页。这里通俗的讲就是你要操作的数据库中表的名字(比如我操作的表为person),或者你也可以自己定义,记得在使用的时候保持一致就ok了,如"content://com.lamp.provider.personprovider/person"

D:如果Uri中包含表示需要获取的记录的ID;则就返回该id对应的数据,如果没有ID,就表示对全部记录进行操作,例如content://com.lamp.provider.personprovider/person 针对表中所有记录
content://com.lamp.provider.personprovider/person/5 针对id为5的记录

UriMatcher:用于匹配Uri,它的用法如下:
1.首先把你需要匹配Uri路径全部给注册上。

1.常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码(-1)。
UriMatcher  uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

2.注册匹配的Uri
//content://com.lamp.provider.personprovider/person 针对表中所有记录,如果匹配该路径,返回1
uriMatcher.addURI(authority, "person", 1);

//content://com.lamp.provider.personprovider/person/# 针对符合条件的记录,如果匹配该路径,返回2
uriMatcher.addURI(authority, "person/#",2);


3.注册完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹 配就返回匹配码,匹配码是调用 addURI()方法传入的第三个参数,假设匹配 content://com.lamp.provider.personprovider/person 路径,返回的匹配码为1。

ContentUris:用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
withAppendedId(uri, id)用于为路径加上ID部分
parseId(uri)方法用于从路径中获取ID部分


下面是一个小例子来说明ContentProvider的使用
1.新建一个类来继承ContentProvider
package com.lamp.db;

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;
import android.text.TextUtils;

import com.lamp.service.DataBaseOpenHelper;

public class PersonContentProvider extends ContentProvider {
	 
	private DataBaseOpenHelper dbHelper = null;
	private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
	private static final int ALLPERSON = 1;
	private static final int PERSON = 2;
	private static final String authority = "com.lamp.provider.personprovider";
	private static String TABLENAME = "person";
	static{
		//content://com.lamp.provider.personprovider/person 针对表中所有记录,如果匹配该路径,返回1
		uriMatcher.addURI(authority, TABLENAME, ALLPERSON);
		
		//content://com.lamp.provider.personprovider/person/# 针对符合条件的记录,如果匹配该路径,返回2
		uriMatcher.addURI(authority, TABLENAME + "/#", PERSON);
	} 

	@Override
	public boolean onCreate() {
		dbHelper = new DataBaseOpenHelper(this.getContext());
		return true;
	}
	
	//删除数据
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase database = dbHelper.getWritableDatabase();
		int count = 0;
		switch (uriMatcher.match(uri)) {
		case ALLPERSON:	
			count = database.delete(TABLENAME, selection, selectionArgs);
			break;
		case PERSON:
			long personid = ContentUris.parseId(uri);
			String where = TextUtils.isEmpty(selection)?"personid=?":selection + " personid=?";
			String[] params = new String[]{String.valueOf(personid)};
			if(!TextUtils.isEmpty(selection) && selectionArgs!=null){
				params = new String[selectionArgs.length+1];
				for (int i = 0; i < selectionArgs.length; i++) {
					params[i] = selectionArgs[i];
				}
				params[selectionArgs.length] = String.valueOf(personid);
			}
			count = database.delete(TABLENAME, where, params);
			break;
		default:
			throw new IllegalArgumentException("参数错误" + uri);
		}
		return count;
	}

	@Override
	public String getType(Uri uri) {
		switch (uriMatcher.match(uri)) {
		case ALLPERSON:			
			return "vnd.android.cursor.dir/personprovider.person";
		case PERSON:		
			return "vnd.android.cursor.item/personprovider.person";
		default:
			throw new IllegalArgumentException("参数错误" + uri);
		}
	}

	//插入数据
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		SQLiteDatabase database = dbHelper.getWritableDatabase();
		long id = 0;
		switch (uriMatcher.match(uri)) {
		case ALLPERSON:			
			id = database.insert(TABLENAME, "name", values);
			return ContentUris.withAppendedId(uri, id);
		case PERSON:			
			id = database.insert(TABLENAME, "name", values);
			String uriString = uri.toString();
			uriString = uriString.substring(0, uriString.lastIndexOf("/")) + id;
			return Uri.parse(uriString);
		default:
			throw new IllegalArgumentException("参数错误" + uri);
		}
	}



	//查询数据
	@Override
	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
			String sortOrder) {
		SQLiteDatabase database = dbHelper.getWritableDatabase();
		switch (uriMatcher.match(uri)) {
		case ALLPERSON:	
			return database.query(TABLENAME, projection, selection, selectionArgs, null, null, sortOrder);
		case PERSON:
			long personid = ContentUris.parseId(uri);
			String where = TextUtils.isEmpty(selection)?"personid=?":selection + " personid=?";
			String[] params = new String[]{String.valueOf(personid)};
			if(!TextUtils.isEmpty(selection) && selectionArgs!=null){
				params = new String[selectionArgs.length+1];
				for (int i = 0; i < selectionArgs.length; i++) {
					params[i] = selectionArgs[i];
				}
				params[selectionArgs.length] = String.valueOf(personid);
			}
			return database.query(TABLENAME, projection, where, params, null, null, sortOrder);
		default:
			throw new IllegalArgumentException("参数错误" + uri);
		}
	}

	//更新数据
	@Override
	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
		SQLiteDatabase database = dbHelper.getWritableDatabase();
		int count = 0;
		switch (uriMatcher.match(uri)) {
		case ALLPERSON:	
			count = database.update(TABLENAME, values, selection, selectionArgs);
			break;
		case PERSON:	
			long personid = ContentUris.parseId(uri);
			String where = TextUtils.isEmpty(selection)?"personid=?":selection + " personid=?";
			String[] params = new String[]{String.valueOf(personid)};
			if(!TextUtils.isEmpty(selection) && selectionArgs!=null){
				params = new String[selectionArgs.length+1];
				for (int i = 0; i < selectionArgs.length; i++) {
					params[i] = selectionArgs[i];
				}
				params[selectionArgs.length] = String.valueOf(personid);
			}
			count = database.update(TABLENAME, values, where, params);
			break;
		default:
			throw new IllegalArgumentException("参数错误" + uri);
		}
		return count;
	}

}



2.在AndroidManifest.xml对ContentProvider进行配置,为了能使其它应用能找到该ContentProvider,ContentProvider采用了android:authorities对它进行唯一标识,你可以把ContentProvider看成是一个网站,authorities就是它的域名
<application android:icon="@drawable/icon" android:label="@string/app_name">
    	<uses-library android:name="android.test.runner" />
    
    	<provider android:name=".PersonContentProvider" android:authorities="com.lamp.provider.personprovider"/>
.....


3.由于我操作的数据是针对数据库,新建一个类继承SQLiteOpenHelper
package com.lamp.service;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DataBaseOpenHelper extends SQLiteOpenHelper {
	private static final String DBNAME = "android";
	private static final int VERSION = 1;

	public DataBaseOpenHelper(Context context) {
		super(context, DBNAME, null, VERSION);
	}

	@Override
	public void onCreate(SQLiteDatabase sqLiteDatabase) {
		String sql = "create table person (personid integer primary key autoincrement,name varchar(20),age integer)";
		sqLiteDatabase.execSQL(sql);
	}

	@Override
	public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
		String sql = "drop table if exists person";
		sqLiteDatabase.execSQL(sql);
		onCreate(sqLiteDatabase);
	}

}



4.用到的实体bean为Person
package com.lamp.domain;

public class Person {
	private Integer personid = null;
	private String name = null;
	private Integer age = null;
	public Person() {
	}
	public Person(String name,Integer age){
		this.name = name;
		this.age = age;
	}
	public Integer getPersonid() {
		return personid;
	}
	public void setPersonid(Integer personid) {
		this.personid = personid;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "personid:" + this.personid + "name: " + this.name + ", age:" + this.age;
	}
	
}



至此ContentProvider的配置完成,将项目部署到模拟器或者手机中,下面来编写一个新的应用来对上一个应用的数据进行测试

1.新建一个新的项目
package com.lamp.provider;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;

public class PersonProviderTestActivity extends Activity {
	private static final String TAG = "PersonProviderTestActivity";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        ContentResolver cr = this.getContentResolver();
        //通过唯一的Uri对特定的应用进行数据的操作
        Uri uri = Uri.parse("content://com.lamp.provider.personprovider/person");
        
        //插入数据
        /*
      	uri = Uri.parse("content://com.lamp.provider.personprovider/person");
        ContentValues values = new ContentValues();
        values.put("name", "kang");
        values.put("age", 35);
        Uri uris = cr.insert(uri, values);
        */
        
        //查询数据,此处是查询personid=13的记录
     /*   Uri uri = Uri.parse("content://com.lamp.provider.personprovider/person/13");   
        Cursor cursor = cr.query(uri, new String[]{"personid","name","age"}, null, null, null);
        while(cursor.moveToNext()){
        	Log.i(TAG, cursor.getInt(0) + " name:" + cursor.getString(1));
        }
        cursor.close();*/
  
        
        //测试删除,此处是删除personid=10的记录
    	uri = Uri.parse("content://com.lamp.provider.personprovider/person/10");
        int count = cr.delete(uri, null, null);
        Log.i(TAG, String.valueOf(count));
      
        
        //测试更新,此处是更新personid=14的记录
        /*   
 		uri = Uri.parse("content://com.lamp.provider.personprovider/person/14");
        ContentValues values2 = new ContentValues();
        values2.put("name", "aaaaa");
        values2.put("age", 35);
        int count = cr.update(uri, values2, null, null);
        Log.i(TAG, String.valueOf(count));
        */
    }
}


记得在AndroidManifest.xml中注册权限
<uses-permission android:name="android.permission.READ_CONTACTS" /> 


分享到:
评论
2 楼 ct19900913 2011-11-24  
顶一个!!!
1 楼 justwyy 2011-09-05  
随便看看了。。

相关推荐

    使用ContentProvider共享数据

    "使用ContentProvider共享数据"这个主题涉及到如何构建和使用ContentProvider来开放数据库,以及如何通过ContentResolver来执行对这些共享数据的操作。 首先,理解ContentProvider的结构至关重要。ContentProvider...

    ContentProvider数据共享

    在Android系统中,ContentProvider是实现应用程序间数据共享的核心组件。它允许一个应用将自己的数据集公开,让其他应用可以通过标准的ContentResolver接口进行访问。这种机制使得数据可以在多个应用之间透明地共享...

    android 数据共享(ContentProvider)

    总结来说,ContentProvider是Android平台中实现数据共享的关键组件,通过定义Uri、注册到Manifest以及重写核心方法,我们可以创建一个能够跨应用共享数据的ContentProvider。同时,配合CursorLoader和LoaderManager...

    实验8 contentProvider共享数据1

    `ContentProvider`是Android系统中用于不同应用程序间共享数据的一种核心组件。在本实验中,我们将学习如何创建和使用`ContentProvider`,以及如何通过`ContentResolver`和`ContentObserver`来与`ContentProvider`...

    Android实现使用自定义ContentProvider共享生词本数据库

    Android高级编程雪梨作业之自定义ContentProvider 将任务01生词本作业中生成的生词本数据库通过自定义ContentProvider的方式,共享给其他应用。 要求如下: (1) 使用自定义SQLiteOpenHelper来管理数据库; (2) 提交...

    Android+Room+ContentProvider

    ContentProvider是Android系统中用于数据共享的一种机制,它可以使得应用的数据对其他应用可见并可操作。通过ContentProvider,我们可以实现跨应用的数据交换,比如联系人、日历等系统数据就是通过ContentProvider...

    Android学习 ContentProvider数据更新与Observer模式.doc

    ContentProvider作为Android系统中数据共享的桥梁,允许不同的应用程序之间交换数据,而Observer模式则是一种设计模式,用于实现实时数据同步和更新。 **ContentProvider**是Android框架的一部分,它提供了一种标准...

    Android ContentProvider全面解析

    在Android系统中,ContentProvider是四大组件之一,它扮演着数据共享和访问的重要角色。ContentProvider使得应用程序可以将自己的数据结构暴露给其他应用,同时也能够访问其他应用公开的数据。本篇文章将全面解析...

    疯狂android资料:第九章使用ContentProvider实现数据共享.doc

    * 数据共享:ContentProvider 允许不同的应用程序之间共享数据,从而实现数据的共享和重用。 * 数据安全:ContentProvider 可以对数据进行保护,以免其他应用程序未经授权地访问数据。 * 灵活性:ContentProvider ...

    Android应用程序组件Content Provider的共享数据更新通知机制分析.doc

    总结来说,Content Provider的共享数据更新通知机制是通过ContentService、ContentResolver和ContentObserver三者的协作实现的。ContentService作为服务注册中心,ContentResolver作为通信桥梁,ContentObserver则...

    ContentProvider共享数据的使用

    在Android系统中,ContentProvider是一种核心组件,它允许应用程序之间共享和访问数据。ContentProvider封装了数据存储的方式,使得不同的应用可以透明地读写数据,而无需关心数据具体是如何存储的,例如SQLite...

    ContentProvider 共享SharedPreferences 值

    `ContentProvider` 是Android提供的一种机制,允许应用间安全地共享数据。本篇将详细讲解如何利用`ContentProvider`来共享`SharedPreferences`的值。 首先,理解`SharedPreferences`。它是Android系统提供的一种轻...

    android contentprovider 数据共享

    ContentProvider(数据提供者)是在应用程序间共享数据的一种接口机制。应用程序在不同的进程中运行,因此,数据和文件在不同应用程序之间是不能够直接访问的。

    使用contentprovider共享生词本数据

    在Android开发中,ContentProvider是一种重要的组件,它允许应用程序之间共享数据。本篇文章将深入探讨如何使用ContentProvider来共享生词本数据。首先,我们来看看什么是ContentProvider。 ContentProvider是...

    android ContentProvider Demo

    在Android开发中,ContentProvider是一种重要的组件,它允许应用程序之间共享数据。本示例"android ContentProvider Demo"将深入探讨如何创建和使用ContentProvider来实现跨应用的数据交换。ContentProvider作为...

    采用ContentProvider对外共享数据

    本篇将深入探讨如何使用ContentProvider对外共享数据以及如何监听内容提供者中的数据变化。 一、ContentProvider基础 ContentProvider是Android四大组件之一,它负责管理应用程序的数据,并提供统一的接口供其他...

    ContentProvider实现数据共享

    在Android系统中,ContentProvider是四大组件之一,它扮演着数据共享的重要角色。ContentProvider使得应用程序之间能够安全、有序地访问彼此的数据,无论是保存在SQLite数据库中的数据,还是存储在文件系统或者其他...

    android 用ContentProvider操作文件

    在Android系统中,ContentProvider是一种核心组件,它允许应用程序之间共享数据,而无需直接访问对方的内部存储。在本教程中,我们将深入探讨如何利用ContentProvider来操作文件,以及其在跨应用数据传输中的作用。 ...

    android程序间数据的共享(ContentProvider和ContentResolver的使用)

    首先,ContentProvider是Android四大组件之一,它作为数据存储和访问的桥梁,允许不同应用之间共享数据。ContentProvider基于URI(统一资源标识符)来暴露数据,并通过标准的CRUD(创建、读取、更新、删除)操作管理...

    Android ContentProvider简单实现

    在Android开发中,ContentProvider是四大组件之一,它充当了数据共享的桥梁,使得不同的应用程序之间可以安全地访问和共享数据。本篇文章将详细介绍如何在Android中实现一个简单的ContentProvider。 首先,理解...

Global site tag (gtag.js) - Google Analytics