3.3内容提供者ContentProvider,供其他软件访问本软件的数据操作

我们先看看官方文档

Content providers are one of the primary building blocks of Android applications, providing content to applications. They encapsulate data and provide it to applications through the single ContentResolver interface. A content provider is only required if you need to share data between multiple applications. For example, the contacts data is used by multiple applications and must be stored in a content provider. If you don't need to share data amongst multiple applications you can use a database directly via SQLiteDatabase.

For more information, read Content Providers.

When a request is made via a ContentResolver the system inspects the authority of the given URI and passes the request to the content provider registered with the authority. The content provider can interpret the rest of the URI however it wants. The UriMatcher class is helpful for parsing URIs.

The primary methods that need to be implemented are:

This class takes care of cross process calls so subclasses don't have to worry about which process a request is coming from.

意思就是说:

内容提供商是Android应用程序的四大主要构件之一,为应用程序提供内容。它们封装数据和通过单一ContentResolver接口提供给应用程序。如果你需要在多个应用程序之间共享数据内容提供商只需要做上面那一步。例如,联系人数据被多个应用程序使用,必须存储在一个内容提供者。如果你不需要共享数据在多个应用程序可以直接使用一个数据库

当一个请求通过ContentResolver系统检查给定的URI的权威和将请求传递给内容提供商注册权威。内容提供者可以解释其他URI然而它希望。UriMatcher类有助于解析uri。需要实现的主要方法有5个:增删改查和系统识别类型(getType这个可以不实现它的方法)

该类负责跨进程调用所以子类不需要担心处理一个请求。

ContentProvider四大组件之一, 也要在清单文件中申明。

接下来通过学习黑马教程的一个例子,我们来了解一下内容提供者:(非常感谢黑马)

public class PersonContentProvider extends ContentProvider {
	
	private static final String AUTHORITY = "com.itheima28.sqlitedemo.providers.PersonContentProvider";
	private static final int PRESON_INSERT_CODE = 0;	// 操作person表添加的操作的uri匹配码
	private static final int PERSON_DELETE_CODE = 1;
	private static final int PERSON_UPDATE_CODE = 2;
	private static final int PERSON_QUERY_ALL_CODE = 3;
	private static final int PERSON_QUERY_ITEM_CODE = 4;
	
	private static UriMatcher uriMatcher;			//用于匹配Uri
	private PersonSQLiteOpenHelper mOpenHelper;		// person表的数据库帮助对象
	
	static {
		//不匹配
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		
		// 添加一些uri(分机号),在原有的基础上追加uri
		//"person/*"代表对该表名进行增删改查
		// content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/insert
		uriMatcher.addURI(AUTHORITY, "person/insert", PRESON_INSERT_CODE);
		
		// content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/delete
		uriMatcher.addURI(AUTHORITY, "person/delete", PERSON_DELETE_CODE);

		// content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/update
		uriMatcher.addURI(AUTHORITY, "person/update", PERSON_UPDATE_CODE);
		
		// content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/queryAll
		uriMatcher.addURI(AUTHORITY, "person/queryAll", PERSON_QUERY_ALL_CODE);
		
		// content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/query/#
		uriMatcher.addURI(AUTHORITY, "person/query/#", PERSON_QUERY_ITEM_CODE);
	}

	@Override
	public boolean onCreate() {
		mOpenHelper = new PersonSQLiteOpenHelper(getContext());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteDatabase db = mOpenHelper.getReadableDatabase();
		switch (uriMatcher.match(uri)) {
		case PERSON_QUERY_ALL_CODE:  // 查询所有人的uri
			if(db.isOpen()) {
				Cursor cursor = db.query("person", projection, selection, selectionArgs, null, null, sortOrder);
				return cursor;
				// db.close(); 返回cursor结果集时, 不可以关闭数据库
			}
			break;
		case PERSON_QUERY_ITEM_CODE:		// 查询的是单条数据, uri末尾出有一个id
			if(db.isOpen()) {
				
				long id = ContentUris.parseId(uri);
				
				Cursor cursor = db.query("person", projection, "_id = ?", new String[]{id + ""}, null, null, sortOrder);

				return cursor;
			}
			break;
		default:
			throw new IllegalArgumentException("uri不匹配: " + uri);
		}
		return null;
	}

	@Override
	public String getType(Uri uri) {
		switch (uriMatcher.match(uri)) {
		case PERSON_QUERY_ALL_CODE: // 返回多条的MIME-type
			return "vnd.android.cursor.dir/person";
		case PERSON_QUERY_ITEM_CODE: // 返回单条的MIME-TYPE
			return "vnd.android.cursor.item/person";
		default:
			break;
		}
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		
		switch (uriMatcher.match(uri)) {
		case PRESON_INSERT_CODE:	// 添加人到person表中
			SQLiteDatabase db = mOpenHelper.getWritableDatabase();
			
			if(db.isOpen()) {
				long id = db.insert("person", null, values);
				db.close();
				return ContentUris.withAppendedId(uri, id);
			}
			break;
		default:
			throw new IllegalArgumentException("uri不匹配: " + uri);
		}
		return null;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		switch (uriMatcher.match(uri)) {
		case PERSON_DELETE_CODE:	// 在person表中删除数据的操作
			SQLiteDatabase db = mOpenHelper.getWritableDatabase();
			if(db.isOpen()) {
				int count = db.delete("person", selection, selectionArgs);
				db.close();
				return count;
			}
			break;
		default:
			throw new IllegalArgumentException("uri不匹配: " + uri);
		}
		return 0;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		switch (uriMatcher.match(uri)) {
		case PERSON_UPDATE_CODE: // 更新person表的操作
			SQLiteDatabase db = mOpenHelper.getWritableDatabase();
			if(db.isOpen()) {
				int count = db.update("person", values, selection, selectionArgs);
				db.close();
				return count;
			}
			break;
		default:
			throw new IllegalArgumentException("uri不匹配: " + uri);
		}
		return 0;
	}

}

申明:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.itheima28.sqlitedemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.itheima28.sqlitedemo" >
    </instrumentation>
    <!-- 内容提供者也要申明 -->
    <permission android:name="aa.bb.cc.read" ></permission>
    <permission android:name="aa.bb.cc.write" ></permission>

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <uses-library android:name="android.test.runner" />

        <activity
            android:name="com.itheima28.sqlitedemo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
		<!-- 申明内容提供者,authorities和Permission可以随意定义,当然,定义好后接收内容提供者的软件要有定义好的权限申明 -->
        <provider
            android:name=".providers.PersonContentProvider"
            android:authorities="com.itheima28.sqlitedemo.providers.PersonContentProvider"
            android:readPermission="aa.bb.cc.read"
            android:writePermission="aa.bb.cc.write" >
        </provider>
    </application>

</manifest>

接收内容提供者的软件使用时,需要匹配好Uri,获得内容提供者访问对象,然后可以直接增删改查:

public void testInsert() {
		Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/insert");
		
		// 内容提供者访问对象
		ContentResolver resolver = getContext().getContentResolver();
		
		ContentValues values = new ContentValues();
		values.put("name", "fengjie");
		values.put("age", 90);
		
		uri = resolver.insert(uri, values);
		Log.i(TAG, "uri: " + uri);
		long id = ContentUris.parseId(uri);
		Log.i(TAG, "添加到: " + id);
	}
	
	public void testDelete() {
		Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/delete");
		
		// 内容提供者访问对象
		ContentResolver resolver = getContext().getContentResolver();
		
		String where = "_id = ?";
		String[] selectionArgs = {"21"};
		int count = resolver.delete(uri, where, selectionArgs);
		Log.i(TAG, "删除行: " + count);
	}
	
	public void testUpdate() {
		Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/update");
		
		// 内容提供者访问对象
		ContentResolver resolver = getContext().getContentResolver();
		
		ContentValues values = new ContentValues();
		values.put("name", "lisi");
		
		int count = resolver.update(uri, values, "_id = ?", new String[]{"20"});
		Log.i(TAG, "更新行: " + count);
	}
	
	public void testQueryAll() {
		Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/queryAll");
		
		// 内容提供者访问对象
		ContentResolver resolver = getContext().getContentResolver();
		
		Cursor cursor = resolver.query(uri, new String[]{"_id", "name", "age"}, null, null, "_id desc");
		
		if(cursor != null && cursor.getCount() > 0) {
			
			int id;
			String name;
			int age;
			while(cursor.moveToNext()) {
				id = cursor.getInt(0);
				name = cursor.getString(1);
				age = cursor.getInt(2);
				Log.i(TAG, "id: " + id + ", name: " + name + ", age: " + age);
			}
			cursor.close();
		}
	}
	
	public void testQuerySingleItem() {
		Uri uri = Uri.parse("content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/query/#");
		
		// 在uri的末尾添加一个id content://com.itheima28.sqlitedemo.providers.PersonContentProvider/person/query/20
		uri = ContentUris.withAppendedId(uri, 20);
		
		// 内容提供者访问对象
		ContentResolver resolver = getContext().getContentResolver();
		
		Cursor cursor = resolver.query(uri, new String[]{"_id", "name", "age"}, null, null, null);
		
		if(cursor != null && cursor.moveToFirst()) {
			int id = cursor.getInt(0);
			String name = cursor.getString(1);
			int age = cursor.getInt(2);
			cursor.close();
			Log.i(TAG, "id: " + id + ", name: " + name + ", age: " + age);
		}
	}

权限申明与内容提供者相呼应:

<uses-permission android:name="aa.bb.cc.read"/>
    <uses-permission android:name="aa.bb.cc.write"/>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值