实例教程九:采用ContentProvider对外共享数据

比较不错的帖子:

植物大战僵尸,又见植物大战僵尸!(分享)
http://www.eoeandroid.com/thread-211063-1-1.html

Android 图片剪辑功能案例
http://www.eoeandroid.com/thread-211095-1-1.html

手机铃声软件-android源代码
http://www.eoeandroid.com/thread-211143-1-1.html

继上一章,在db应用程序中,添加ContentProvider类

package cn.itcast.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;

public class PersonProvider extends ContentProvider {
        /**
         * Uri代表了要操作的数据
         * Uri主要包含2部分信息:1.需要操作的ContentProvider 2.对ContentProvider中的什么数据进行操作
         * 一个Uri由以后几部分组成:
         * 例:content://cn.itcast.provider.personprovider/person/10
         * content:// --scheme
         * cn.itcast.provider.personprovider --主机名或authority
         * person/10 --路径
         * 10 --ID
         * ContentProvider(内容提供者)的scheme已经由Android所规定,scheme为:content//主机名
         * (或叫Authority)用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
         * 路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
         * 要操作person表中id为10的记录,可以构建这样的路径:/person/10
         * 要操作person表中id为10的记录的name字段,可以构建这样的路径:/person/10/name
         * 要操作person表中所有记录,可以构建这样的路径:/person
         * 要操作xxx表中的记录,可以构建这样的路径:/xxx
         * 当然要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式,如下:
         * 要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
         * 如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
         * Uri uri = Uri.parse("content://cn.itcast.provider/person");
         */
        
        private DBOpenHelper dbOpenHelper;
        //UriMatcher添加的NO_MATCH,代表若不匹配,返回是哪个值
        private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
        private static final int PERSONS = 1;
        private static final int PERSON = 2;
        static{
                MATCHER.addURI("cn.itcast.providers.personprovider", "person", PERSONS);
                MATCHER.addURI("cn.itcast.providers.personprovider", "person/#", PERSON);
        }

        @Override
        public boolean onCreate() { //只会被调用 一次,适合做数据的初始化操作
                dbOpenHelper = new DBOpenHelper(this.getContext());                
                return false;
        }

        @Override
        public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) { //可以供外部应用查询内容提供者提供的数据
                SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
                Cursor cursor = null;
                switch (MATCHER.match(uri)) {
                case 1:
                        cursor = db.query("person", projection, selection, selectionArgs, 
                                        null, null, sortOrder);        
                        break;
                        
                case 2:
                        int rowId = (int) ContentUris.parseId(uri);
                        String where = "personId=?" + rowId;
                        if(selection != null && !"".equals(selection.trim())){
                                where += " and" + selection;
                        }
                        cursor = db.query("person", projection, where, selectionArgs, 
                                        null, null, sortOrder);        
                        break;
                        
                default:
                        throw new IllegalArgumentException("this is Unknown Uri:" + uri);
                }
                return cursor;
        }
        
        /**
         * 2种方法
         * 1.查询所有 /person
         * 2.查询指定的ID /person/10
         * 该方法用于返回当前Uri所代表数据的MIME类型,如果操作的数据属于集合类型
         * 那么,MIME类型字符串应该以vnd.android.cursor.dir/开头
         * 例:要得到所有person记录的Uri为content://cn.itcast.provider.personprovider/person
         * 那么返回的MIME类型字符串应该为:vnd.android.cursor.dir/person
         * 如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该为:
         * vnd.android.cursor.item/开头
         * 例:得到Id为10的person记录,Uri为content://cn.itcast.provider.personprovider/person/10
         * 那么 返回的MIME类型字符串应该为vnd.android.cursor.item/person
         */
        @Override
        public String getType(Uri uri) { //返回你现在要操作的数据的内容类型
                switch (MATCHER.match(uri)) {
                case 1:
                        return "vnd.android.cursor.dir/person";
                        
                case 2:
                        return "vnd.android.cursor.item/person";
                        
                default:
                        throw new IllegalArgumentException("this is Unknown Uri:" + uri);
                }
        }
        
        /**
         * 2种方法
         * 1.删除所有 /person
         * 2.删除指定的ID /person/10
         */
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
                SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
                int num = 0;
                switch (MATCHER.match(uri)) {
                case 1:
                        num = db.delete("person", selection, selectionArgs);                        
                        break;
                        
                case 2:
                        int rowId = (int) ContentUris.parseId(uri);
                        String where = "personId=?" + rowId;
                        if(selection != null && !"".equals(selection.trim())){
                                where += " and" + selection;
                        }
                        num = db.delete("person", where, selectionArgs);        
                        break;
                        
                default:
                        throw new IllegalArgumentException("this is Unknown Uri:" + uri);
                }
                return num;
        }        

        @Override
        public Uri insert(Uri uri, ContentValues values) {
                SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
                switch (MATCHER.match(uri)) {
                case 1:
                        long rowId = db.insert("person", "name", values); //如果主键是整数则rowId=主键
                        // content://cn.itcast.provides.personprovider/person/10
                        //第一种写法
                        //Uri insertUri = Uri.parse("content://cn.itcast.providers.personprovider/person/" + rowId);
                        //第2种写法
                        Uri insertUri = ContentUris.withAppendedId(uri, rowId);
                        return insertUri;

                default:
                        throw new IllegalArgumentException("this is Unknown Uri:" + uri);
                }
        }        

        /**
         * 2种方法
         * 1.更新所有 /person
         * 2.更新指定的ID /person/10
         */
        @Override
        public int update(Uri uri, ContentValues values, String selection,
                        String[] selectionArgs) {
                SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
                int num = 0;
                switch (MATCHER.match(uri)) {
                case 1:
                        num = db.update("person", values, selection, selectionArgs);                        
                        break;
                        
                case 2:
                        int rowId = (int) ContentUris.parseId(uri);
                        String where = "personId=?" + rowId;
                        if(selection != null && !"".equals(selection.trim())){
                                where += " and" + selection;
                        }
                        num = db.update("person", values, where, selectionArgs);
                        break;
                        
                default:
                        throw new IllegalArgumentException("this is Unknown Uri:" + uri);
                }
                return num;
        }

}

新建一个Other应用程序,添加调用ContentProvider的类

package cn.itcast.test;

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 AccessContentProviderTest extends AndroidTestCase {
        private static final String TAG = "AccessContentProviderTest";
        
        public void testInsert() throws Exception{
                Uri uri = Uri.parse("content://cn.itcast.providers.personprovider/person");
                //访问内容提供者需要ContentResolver
                ContentResolver resolver = this.getContext().getContentResolver();
                ContentValues values = new ContentValues();
                values.put("name", "laoLi");
                values.put("phone", "1658246");
                values.put("amount", "5000");                
                resolver.insert(uri, values);
        }
        
        public void testDelete() throws Exception{
                Uri uri = Uri.parse("content://cn.itcast.providers.personprovider/person/20");
                //访问内容提供者需要ContentResolver
                ContentResolver resolver = this.getContext().getContentResolver();
                resolver.delete(uri, null, null);
        }
        
        public void testUpdate() throws Exception{
                Uri uri = Uri.parse("content://cn.itcast.providers.personprovider/person/19");
                ContentResolver resolver = this.getContext().getContentResolver();
                ContentValues values = new ContentValues();
                values.put("name", "Sam");
                resolver.update(uri, values, null, null);
        }
        
        public void testQuery() throws Exception{
                Uri uri = Uri.parse("content://cn.itcast.providers.personprovider/person/19");
                ContentResolver resolver = this.getContext().getContentResolver();
                Cursor cursor = resolver.query(uri, null, null, null, "personId asc");
                while(cursor.moveToNext()){
                        String name = cursor.getString(cursor.getColumnIndex("name"));
                        Log.i(TAG, name);
                }
        }
}
原文地址:https://www.cnblogs.com/vus520/p/2746035.html