(Android review)ContentProvider的基本使用

1、某些数据库在外面是不能使用的。
2、ContentProvider让A程序中的数据能让B程序使用
3、ContentProvider主要是共享数据。可以添加ContentObserver来观察数据的变化
4、<provider />中的authorities主要用于区分不同的provider
5、content://cn.itcast.aqlite.provider((/person)/id)
解析:
content://    ----->固定写法,必须有
cn.itcast.aqlite.provider:   ------》这个应用的应用名
person:  表名


6、A应用通过B应用的ContentProvider访问B应用的数据库


7、使用ContentProvider查询的几种方式:
1)不带表名
2)只代表名

3)带表名和id


这个例子用的还是之前那个例子

1、SQLiteProvider

package com.example.provider;

import com.example.sqlitetest.DBOpenHelper;

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.widget.Switch;

public class SQLiteProvider extends ContentProvider {

	private UriMatcher matcher;
	private DBOpenHelper helper;

	public static final int PERSON = 1;
	public static final int PERSON_ID = 2;
	private SQLiteDatabase db;

	@Override
	public boolean onCreate() {//第一次启动时执行,会长期驻留在后台,除非被杀死,否则不会再被执行..
		matcher = new UriMatcher(UriMatcher.NO_MATCH);
		matcher.addURI("com.example.provider", "person", PERSON);// 设置一个Uri,如果匹配到person,则返回1
		matcher.addURI("com.example.provider", "person/#", PERSON_ID);

		helper = new DBOpenHelper(getContext());

		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {

		System.out.println("--------->query");

		db = helper.getReadableDatabase();

		switch (matcher.match(uri)) {
		case PERSON_ID:
			long id = ContentUris.parseId(uri);// 获取uri最后的id
			// selection = "id=" + id; //将id添加到查询条件中.这种方式只能解决查询条件只用id的情况
			selection = selection == null ? "id=" + id : selection
					+ " AND id= " + id;// 这时候就能处理查询条件可以不仅仅有id的情况了
		case PERSON:
			return db.query("person", projection, selection, selectionArgs,
					null, null, sortOrder);

		default:
			throw new RuntimeException("Uri不能匹配");
		}
	}

	@Override
	public String getType(Uri uri) {
		switch (matcher.match(uri)) {
		case PERSON_ID:
			
			return "带了ID.操作指定person";
		case PERSON:
			return "没带ID.操作所有person";
		default:
			
			break;
		}
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		SQLiteDatabase db = helper.getWritableDatabase();
		switch (matcher.match(uri)) {
		case PERSON:
			long id = db.insert("person", "id", values);// 插入记录,得到id
			return ContentUris.withAppendedId(uri, id);
		default:
			throw new RuntimeException("表明非法");
		}
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase db = helper.getWritableDatabase();

		switch (matcher.match(uri)) {
		case PERSON_ID:
			long id = ContentUris.parseId(uri);// 获取uri最后的id
			// selection = "id=" + id; //将id添加到查询条件中.这种方式只能解决查询条件只用id的情况
			selection = selection == null ? "id=" + id : selection
					+ " AND id= " + id;// 这时候就能处理查询条件可以不仅仅有id的情况了
		case PERSON:
			return db.delete("person", selection, selectionArgs);

		default:
			throw new RuntimeException("Uri不能匹配");
		}
	}

	/**
	 * 有时候可能会改不了...
	 * 不知道是为什么
	 */
	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		SQLiteDatabase db = helper.getWritableDatabase();

		switch (matcher.match(uri)) {
		case PERSON_ID:
			long id = ContentUris.parseId(uri);// 获取uri最后的id
			// selection = "id=" + id; //将id添加到查询条件中.这种方式只能解决查询条件只用id的情况
			selection = selection == null ? "id=" + id : selection
					+ " AND id= " + id;// 这时候就能处理查询条件可以不仅仅有id的情况了
		case PERSON:
//			return db.delete("person", selection, selectionArgs);
			return db.update("person", values, selection, selectionArgs);
		default:
			throw new RuntimeException("Uri不能匹配");
		}
	}
	
	
//	@Override
//	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
//		SQLiteDatabase db = helper.getWritableDatabase();
//		switch (matcher.match(uri)) {					// 用匹配器匹配传入的uri
//			case PERSON_ID:
//				long id = ContentUris.parseId(uri);		// 获取uri最后的id
//				selection = selection == null ? "id=" + id : selection + " AND id=" + id;	// 构建查询条件
//			case PERSON:
//				return db.update("person", values, selection, selectionArgs);
//			default:
//				throw new RuntimeException("Uri不能识别: " + uri);
//		}
//	}
}


至于这个例子中的其他代码其实是和前面是一样的。谢了ContentProvider以后记得早AndroidManifest.xml中添加上相应的注册代码:

 

<provider android:name="com.example.provider.SQLiteProvider"
            android:authorities="com.example.provider"
            />




2、B应用的ProviderTest

package com.example.test;

import com.example.pojo.Person;

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

public class ProviderTest extends AndroidTestCase {
	
	/**
	 * 这个程序的执行顺序:
	 *  .class -> .dex -> .apk -> 安装 -> 开启进程(开启主线程) -> 
	 *  创建ProviderTest对象 (成员变量的方式在这里getContext(),这时还没有getContext())-> setContext() -> 测试方法 -> getContext()
	 */

	public void test1() {
		ContentResolver resolver = getContext().getContentResolver();//注意,这里不能讲resolver作为全局变量

		ContentValues values = new ContentValues();
		Uri parse = Uri.parse("content://com.example.provider");

		resolver.insert(parse, values);
		resolver.delete(parse, null, null);
		resolver.update(parse, values, null, null);
		resolver.query(parse, null, null, null, null);
		/**
		 * content://com.example.provider :决定了访问那个应用的数据库
		 */
	}
	
	
	public void testQuery(){
		ContentResolver resolver = getContext().getContentResolver();
		
		/**
		 * content://com.example.provider/person
		 * content:// 固定写法
		 * com.example.provider: authorities
		 * person: 表名
		 */
//		Uri uri = Uri.parse("content://com.example.provider/person");//不带id进行查询
		Uri uri = Uri.parse("content://com.example.provider/person/10");//带上id进行查询
//		Cursor c = resolver.query(uri, null, "id>?", new String[]{"50"}, null);
		Cursor c = resolver.query(uri, null, null, null, null);
		
		while(c.moveToNext()){
			Person p = new Person(c.getInt(0), c.getString(1), c.getInt(2));
			System.out.println(p);
		}
	}
	
	public void testInsert(){
		ContentResolver resolver = getContext().getContentResolver();
		Uri uri = Uri.parse("content://com.example.provider/person");
		
		ContentValues values = new ContentValues();
		values.put("name", "li kaifu");
		values.put("balance", 12345);
		Uri uri1 = resolver.insert(uri, values);//插入数据,并且得到数据的uri
		
		System.out.println(uri1);
	}
	
	public void testUpdate(){
		ContentResolver resolver = getContext().getContentResolver();
//		Uri uri = Uri.parse("content://com.example.provider/person/102");//指定id,只修改某一条记录
		Uri uri = Uri.parse("content://com.example.provider/person");//不指定id,将整张表都修改
		
		ContentValues values = new ContentValues();
		values.put("name", "kaifu lili");
		values.put("balance", 9999);
		resolver.update(uri, values, null, null);
		
	}
	
	public void testDelete(){
		ContentResolver resolver = getContext().getContentResolver();
		Uri uri = Uri.parse("content://com.example.provider/person/104");
		
		resolver.delete(uri, null, null);
	}
	
	public void testGetType(){
		ContentResolver resolver = getContext().getContentResolver();
		
		String type1 = resolver.getType(Uri.parse("content://com.example.provider/person"));
		String type2 = resolver.getType(Uri.parse("content://com.example.provider/person/102"));
	    
		System.out.println(type1);
		System.out.println(type2);
	}
}


源码下载:







(Android review)ContentProvider的基本使用,布布扣,bubuko.com

(Android review)ContentProvider的基本使用

上一篇:实验3:OpenFlow协议分析实践


下一篇:Windows使用进阶