您的位置:首页 > 移动开发 > Android开发

Android ContentProvider(内容提供者)

2011-12-08 11:29 483 查看
//ContentProvider主要实现数据共享,例如:继承了ContentProvider的类创建的XML文件,数据库文件,等等。。。。只要继承了ContentProvider类的,那么它都可以被其它应用访问,不像用DOM,SAX,PULL,sharePrefrences那样生成的东西要用自己的API来解析。

//ContentProvider主要实现了,数据的共享和统一了操作实现方式

//一个小例子,目录结构



//先写DBHelper类,用于创建数据库

package sn.len.contentprovider.demo;

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

public class DBHelper extends SQLiteOpenHelper
{
private static final String DBNAME="demoprovider.db";
private static final int DBVERSION=1;
public DBHelper(Context context)
{
super(context, DBNAME, null, DBVERSION);
}

@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("create table demo(_id integer primary key autoincrement,name varchar(20),amount varchar(20))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{

}

}


//再写继承自ContentProvider的TestContentProvider.java类

package sn.len.contentprovider.demo;

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.util.Log;

public class TestContentProvider extends ContentProvider
{

private DBHelper db;
private static final UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH);
private static final int RETURN1=1;
private static final int RETURN2=2;
static
{
matcher.addURI("sn.len.contentprovider.demo.providers.TestContentProvider", "demo", RETURN1);
matcher.addURI("sn.len.contentprovider.demo.providers.TestContentProvider", "demo/#", RETURN2);
}
@Override
public boolean onCreate()
{
this.db=new DBHelper(this.getContext());
this.db.getWritableDatabase();
return false;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder)
{
switch(matcher.match(uri))
{
case RETURN1://查询整个表
{
SQLiteDatabase selecttablesql=this.db.getWritableDatabase();
Cursor cursor=selecttablesql.rawQuery("select * from demo",null);
return cursor;
}
case RETURN2://根据ID来查询
{
SQLiteDatabase selectidsql=this.db.getWritableDatabase();
//分离出ID
long id=ContentUris.parseId(uri);
//检测用户查询条件是什么
String where="_id="+id;
if(selection!=null && !"".equals(selection))
{
where=where+" and "+selection;
}
Cursor cursor=selectidsql.query("demo", projection, where, selectionArgs, null, null, sortOrder);
return cursor;
}
default:
{
throw new IllegalArgumentException();
}
}
}

@Override
public String getType(Uri uri)
{
switch(matcher.match(uri))
{
case RETURN1:return "vnd.android.cursor.dir/demo"; //如果返回多条记录,所谓集合就是dir
case RETURN2:return "vnd.android.cursor.item/demo"; //如果返回多单记录,所谓一个对象就是item
default: throw new IllegalArgumentException("unknow uri"+uri.toString());
}
}

@Override
public Uri insert(Uri uri, ContentValues values)
{
switch(matcher.match(uri)) //在上在static静态区域添加的URI和传过来的参数URI相比较
{
case RETURN1://只有符合表的情况下。才可以插入数据,即使为空也要插入一条数据,这是SQLite的特点
{
SQLiteDatabase insertsql=this.db.getWritableDatabase();
long insertrow=insertsql.insert("demo", "_id", values);
return ContentUris.withAppendedId(uri, insertrow);
}
default:
{
throw new IllegalArgumentException();
}
}
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs)
{
switch(matcher.match(uri))
{
case RETURN1:
{
SQLiteDatabase deltablesql=this.db.getWritableDatabase();
int delrow=deltablesql.delete("demo",selection,selectionArgs);
return delrow;
}
case RETURN2:
{
SQLiteDatabase delrecordsql=this.db.getWritableDatabase();
//分解ID
long id=ContentUris.parseId(uri);
String where="_id="+id;
if(selection!=null && !"".equals(selection))
{
where=where+" and "+selection;
}
int delrow=delrecordsql.delete("demo", where, selectionArgs);
return delrow;
}
default:
{
throw new IllegalArgumentException();
}

}
}

@Override
public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs)
{

switch(matcher.match(uri))
{
case RETURN1:
{
SQLiteDatabase updatetablesql=this.db.getWritableDatabase();
return updatetablesql.update("demo", values, selection, selectionArgs);
}
case RETURN2:
{
SQLiteDatabase updaterowesql=this.db.getWritableDatabase();
//取出ID
long id=ContentUris.parseId(uri);
String where="_id="+id;
if(selection!=null && !"".equals(selection))
{
where=where+" and"+selection;
}
return updaterowesql.update("demo", values, selection, selectionArgs);
}
default:
{
throw new IllegalArgumentException();
}

}
}

}


再到另一个项目中去写一个Junit类AccessDemo.java,测试刚才在ContentProviderDemo那个项目中创建的数据,看看是否可以实现数据共享的目的



//AccessDemo.java类

package sn.len.others;

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

public class AccessDemo extends AndroidTestCase
{
private static final String TAG="AccessContentProviderdemo";
public void testInsert()
{
ContentResolver insertcr=this.getContext().getContentResolver();
Uri inserturi=Uri.parse("content://sn.len.contentprovider.demo.providers.TestContentProvider/demo");
ContentValues values=new ContentValues();
values.put("name","xiaoyang");
values.put("amount","800");
Uri uri=insertcr.insert(inserturi,values);
Log.i(TAG, uri.toString());
values.clear();
values.put("name","Android");
values.put("amount","0");
uri=insertcr.insert(inserturi,values);
Log.i(TAG, uri.toString());
values.clear();
values.put("name","家里蹲大学");
values.put("amount","0");
uri=insertcr.insert(inserturi,values);
Log.i(TAG, uri.toString());
values.clear();
values.put("name","呆在家里学Android");
values.put("amount","0");
uri=insertcr.insert(inserturi,values);
Log.i(TAG, uri.toString());
}
public void testSelect()
{
ContentResolver selectcr=this.getContext().getContentResolver();
Uri selecturi=Uri.parse("content://sn.len.contentprovider.demo.providers.TestContentProvider/demo");
Cursor cursor=selectcr.query(selecturi,null,null,null, null);
while(cursor.moveToNext())
{
StringBuilder builder=new StringBuilder();
int id=cursor.getInt(cursor.getColumnIndex("_id"));
String name=cursor.getString(cursor.getColumnIndex("name"));
String amount=cursor.getString(cursor.getColumnIndex("amount"));
builder.append("_id=").append(id).append("   name=").append(name).append("   amount=").append(amount);
Log.i(TAG, builder.toString());
}

}
public void testDel()
{
ContentResolver del=this.getContext().getContentResolver();
Uri deluri=Uri.parse("content://sn.len.contentprovider.demo.providers.TestContentProvider/demo/1");
int row=del.delete(deluri, null, null);
Log.i(TAG, row+"");
}
public void testUpdate()
{
ContentResolver update=this.getContext().getContentResolver();
Uri uri=Uri.parse("content://sn.len.contentprovider.demo.providers.TestContentProvider/demo/2");
ContentValues values=new ContentValues();
values.put("name", "呆在家里学Android");
values.put("amount", "0");
int updaterecord=update.update(uri, values,"name=?",new String[]{"家里蹲大学"});
Log.i(TAG, updaterecord+"");
}
}


//分别执行 insert select del update

insert



select



delete过后再查询



update过后再查询



//结果证明,可以在别的应用中可以访问它的数据,证明可以数据共享。

如果是初学者的话,我觉得没有必要去深入了解原理,知道怎么用就行了,我在学习这个时候也想弄明白,到底是怎么样的,我都没有NEW那个类的对象就可以访问那个类的insert 这些东西。感觉很不可思议。只要知道,你Junit里面的增,删,改,查,会去调用系统的增删除改查函数,系统然后又去调用你继承ContentPrrovider的类的增删改查就行了。

只要是继承ContentProvider的类,就可以现实数据共享.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息