`
liaokang.java
  • 浏览: 152096 次
  • 性别: 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  
随便看看了。。

相关推荐

Global site tag (gtag.js) - Google Analytics