现在的位置: 首页 > 综合 > 正文

android ContentProvider入门

2013年10月17日 ⁄ 综合 ⁄ 共 4012字 ⁄ 字号 评论关闭
这里举例是A应用要访问B应用
1、在B应用里创建数据库
只需要创建一个类继承DBOpenHelper
public class DBOpenHelper extends SQLiteOpenHelper {
	private static int DATABASE_VERSION = 1;//版本号
	public DBOpenHelper(Context context) {
		super(context, "表名", null, DATABASE_VERSION);
	}
	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL("CREATE TABLE <表名> ( _id INTEGER primary key autoincrement, <字段> varchar(20))");
	}
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// 更新表
	}

}
*这个数据库是创建好了,可是要想自己操作该数据库就需要这样了
	DBOpenHelper helper = new DBOpenHelper(context);
	SQLiteDatabase db = helper.getWritableDatabase();
	db.execSQL("insert into......");//仅代表执行sql语句
	db.close(); 

2、在B应用里创建ContentProvider
只需要创建一个类继承ContentProvider

public class PicturesProvider extends ContentProvider {
	private static final int PICTURES = 1;// 代表访问/picture
	private static final int PICTURE = 2;// 代表访问/picture/#
	private static final UriMatcher MATCHER = new UriMatcher(
			UriMatcher.NO_MATCH);// 初始化UriMatcher的不匹配码,如果不匹配就会返回UriMatcher.NO_MATCH也就是-1
	private DBOpenHelper helper;//之前创建的操作数据库的类
	//在静态代码块里添加匹配的uri
	static {
		MATCHER.addURI("com.xy.picturesprovider", "picture_table", PICTURES);// 代表访问/picture
		MATCHER.addURI("com.xy.picturesprovider", "picture_table/#", PICTURE);// 代表访问/picture/#
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		int num = 0;
		SQLiteDatabase db = helper.getWritableDatabase();
		switch (MATCHER.match(uri)) {
		case PICTURES:// 代表访问/picture
			num = db.delete("picture_table", selection, selectionArgs);
			break;
		case PICTURE:// 代表访问/picture/#
			long id = ContentUris.parseId(uri);//截取id
			String where = "_id=" + id;
			if (selection != null && !"".equals(selection.trim())) {
				where += " and" + selection;
			}
			num = db.delete("", where, selectionArgs);
			break;
		default:
			throw new IllegalArgumentException("Unkonwn Uri:" + uri);//没有匹配的就抛出异常
		}
		return num;//返回删掉的数量
	}

	@Override
	public String getType(Uri uri) {
		String type = null;
		//返回数据类型
		switch (MATCHER.match(uri)) {
		case PICTURES:// 代表访问/picture
			type = "vnd.android.cursor.dir/xxx";//xxx是自己随便写的  主要是前面  这个代表要操作的数据数据集合类型
			break;
		case PICTURE:// 代表访问/picture/#
			type = "vnd.android.cursor.item/xxx";//代表要操作的数据属于非集合类型
			break;
		default:
			throw new IllegalArgumentException("Unkonwn Uri:" + uri);//没有匹配的就抛出异常
		}
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// TODO Auto-generated method stub
		Log.e("xxxxxxxxxxxxxxxxxxxxx", "insert");
		SQLiteDatabase db = helper.getWritableDatabase();
		switch (MATCHER.match(uri)) {
		case PICTURES:
			long rowid = db.insert("picture_table", "_path", values);// 返回该记录的行号
			db.close();
 			Uri noteUri = ContentUris.withAppendedId(uri, rowId);
            		getContext().getContentResolver().notifyChange(noteUri, null);
            		return noteUri;
		default:
			throw new IllegalArgumentException("Unkonwn Uri:" + uri);
		}
	}

	@Override
	public boolean onCreate() {
		// TODO Auto-generated method stub
		helper = new DBOpenHelper(getContext());//初始化
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		// TODO Auto-generated method stub
		return 0;
	}

}
3、在B应用的manifest文件的application节点里添加provider节点
	<provider  android:name=".刚写的Provider类名" android:authorities="com.xy.picturesprovider"></provider>
	authorities里的属性自己写  主要是为了区别用的   待会就是根据这个路径找到该应用的

4、现在可以着手完成A应用了
	如果要测试A访问B的话,就看第5点
	下面代码是增加和删除的测试代码
		public void testInsert(){
			 ContentResolver resolver = getContext().getContentResolver();
			 Uri uri = Uri.parse("content://com.xy.picturesprovider/picture_table");//#1
			 ContentValues values = new ContentValues();
			 values.put("_path", "www.sina.com");
			 resolver.insert(uri, values);
		}
		public void testDelete(){
			ContentResolver resolver = getContext().getContentResolver();
			 Uri uri = Uri.parse("content://com.xy.picturesprovider/picture_table/5");//#2
			 ContentValues values = new ContentValues();
			 resolver.delete(uri, null, null);
		}
	这里解释下#1:content://是固定写法,紧接着的就是之前在manifest里设置的一串东西,虽然可以任意写,
可是这里却需要和那里写的一致否则访问不到B应用,然后接着后面的就是要访问的表名了
	#2的话只多了一个参数,代表访问的时表中的第5条记录
至此 , 您已经操作了其他应用
5、如果需要测试的话需要在manifest文件里的两处添加代码
	一是在application节点里activity节点外添加<uses-library android:name="android.test.runner" />
	二是在application外面添加 
	<instrumentation
		android:name="android.test.InstrumentationTestRunner"
		android:targetPackage="com.xy.b" />后面这个属性必须写成要测试应用的package属性

	

抱歉!评论已关闭.