Android中的ContentProvider小结

本文详细介绍了Android中的ContentProvider,包括其作用、相关概念如Uri和SQLite,以及如何构建本应用的ContentProvider,包括创建数据库、数据管理类和在AndroidManifest中注册。此外,还讲解了其他应用如何通过ContentResolver进行数据操作。
摘要由CSDN通过智能技术生成

ContentProvider作用

  • 为存储和获取数据提供了统一的接口

  • 实现了不用应用间的数据共享

  • Android为常用数据(如声音、图片、视频和通讯录等)提供的默认的ContentProvider支持

相关概念介绍

ContentProvider简介

为了实现向其他应用共享数据,需要继承一个抽象类ContentProvider,并实现如下几个抽象方法。

public class MyProvider extends ContentProvider {
    @Override
    public boolean onCreate() {
        return false;
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        return null;
    }

    @Nullable
    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

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

看到这些抽象方法的参数是不是和数据库的相关操作很像。因此一般情况下,我们都是用数据库来存储数据

Uri简介

  1. 概念:通用资源标示符(Uniform Resource Identifier)

  2. 组成部分:

    • scheme 访问资源的命名机制

    • authority 存放资源的主机名

    • path 资源自身的名称

  3. 格式:scheme://authority/path,其中authority还包括host的port。例如:

    content://com.cydia.test:200/login/username

    • content为scheme
    • com.cydia.test:200为authority(com.cydia.test为host,200为port)
    • login/username为path。

Sqlite简介

参考文章《Android中的数据库应用小结》

本应用内的provider构建

众所周知,ContentProvider是用来向其他应用共享本应用内的数据,因此,我们首先需要确定数据在本应用内的存储方式。而考虑到继承ContentProvider需要实现的抽象方法(与sqlite的操作方法太相似),我们使用sqlite来存储数据。

创建数据库: MySqliteHelper

public class MySqliteHelper extends SQLiteOpenHelper {

    public static final String DB_NAME = "cydia.db";
    public static final int DB_VERSION = 3;

    public static final String TABLE_NAME = "bookstore";
    public static final String COLUMN_ID = "id";
    public static final String COLUMN_NAME = "name";
    public static final String COLUMN_AUTHOR = "author";
    public static final String COLUMN_PRICE = "price";
    public static final String COLUMN_PAGES = "pages";

    public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
            COLUMN_ID + " integer primary key autoincrement," +
            COLUMN_NAME + " text NOT NULL," +
            COLUMN_AUTHOR + " text," +
            COLUMN_PRICE + " real," +
            COLUMN_PAGES + " integer)";

    public MySqliteHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }
}

创建数据管理类: DBManager

public class DBManager {

    private volatile static DBManager sInstance;

    private SQLiteDatabase db;

    private DBManager(Context context) {
        MySqliteHelper helper = new MySqliteHelper(context);
        db = helper.getWritableDatabase();
    }

    public static DBManager getInstance(Context context) {
        if (sInstance == null) {
            synchronized (DBManager.class) {
                if (sInstance == null) {
                    sInstance = new DBManager(context);
                }
            }
        }
        return sInstance;
    }

    public long add(ContentValues contentValues) {
        return db.insert(MySqliteHelper.TABLE_NAME, null, contentValues);
    }

    public int delete(String whereClause, String[] whereArgs) {
        return db.delete(MySqliteHelper.TABLE_NAME, whereClause, whereArgs);
    }

    public int update(ContentValues contentValues, String whereClause, String[] whereArgs) {
        return db.update(MySqliteHelper.TABLE_NAME, contentValues, whereClause, whereArgs);
    }

    public Cursor query(String[] columns, String selection,
                        String[] selectionArgs, String groupBy, String having,
                        String orderBy) {
        return db.query(MySqliteHelper.TABLE_NAME, columns, selection,
                selectionArgs, groupBy, having,
                orderBy);
    }

    public void closeDB() {
        db.close();
    }
}

继承ContentProvider类

public class MyProvider extends ContentProvider {

    private Context context;

    private ContentResolver contentResolver;

    private static final String AUTHORITY = "com.pptv.test";

    private static final int ALL_BOOKS = 1;

    private static final int SINGLE_BOOK = 1;

    //匹配Uri
    private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    static {
        //匹配Uri为content://com.pptv.test/bookstore 返回整数1
        uriMatcher.addURI(AUTHORITY, MySqliteHelper.TABLE_NAME, ALL_BOOKS);

        //匹配Uri为content://com.pptv.test/bookstore/# 返回整数2,注#为通配符
        //如content://com.pptv.test/bookstore/1 就返回2
        uriMatcher.addURI(AUTHORITY, MySqliteHelper.TABLE_NAME + "/#", SINGLE_BOOK);
    }

    @Override
    public boolean onCreate() {
        context = getContext();
        contentResolver = context.getContentResolver();
        return true;
    }

    @Nullable
    @Override
    public String getType(Uri uri) {
        if (uriMatcher.match(uri) == ALL_BOOKS) {
            return "vnd.android.cursor.dir/" + MySqliteHelper.TABLE_NAME;
        } else if(uriMatcher.match(uri) == SINGLE_BOOK) {
            return "vnd.android.cursor.item/" + MySqliteHelper.TABLE_NAME;
        }
        return null;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        Uri ret = null;
        if (uriMatcher.match(uri) == ALL_BOOKS) {
            //uri为 content://com.pptv.test/bookstore 可以执行插入操作
            long id = DBManager.getInstance(context).add(values);
            ret = ContentUris.withAppendedId(uri, id);
            contentResolver.notifyChange(ret, null);
        }
        //content://com.pptv.test/bookstore/4 没有插入权限
        return ret;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int id = 0;
        if (uriMatcher.match(uri) == ALL_BOOKS) {
            //content://com.pptv.test/bookstore 删除满足条件的所有记录
            id = DBManager.getInstance(context).delete(selection, selectionArgs);
            contentResolver.notifyChange(uri, null);
        } else if(uriMatcher.match(uri) == SINGLE_BOOK) {
            //content://com.pptv.test/bookstore/4 删除id=4的记录
            long deleted_id = ContentUris.parseId(uri);
            id = DBManager.getInstance(context).delete(MySqliteHelper.COLUMN_ID + "=?",
                    new String[]{deleted_id +""});
            contentResolver.notifyChange(uri, null);
        }
        return id;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        int id = 0;
        if (uriMatcher.match(uri) == ALL_BOOKS) {
            //content://com.pptv.test/bookstore 更新满足条件的所有记录
            id = DBManager.getInstance(context).update(values, selection, selectionArgs);
            contentResolver.notifyChange(uri, null);
        } else if(uriMatcher.match(uri) == SINGLE_BOOK) {
            //content://com.pptv.test/bookstore/4 更新id=4的记录
            long update_id = ContentUris.parseId(uri);
            id = DBManager.getInstance(context).update(values, MySqliteHelper.COLUMN_ID + "=?",
                    new String[]{update_id +""});
            contentResolver.notifyChange(uri, null);
        }
        return id;
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        Cursor cursor = null;
        if (uriMatcher.match(uri) == ALL_BOOKS) {
            //content://com.pptv.test/bookstore 查找满足条件的所有记录
            cursor = DBManager.getInstance(context).query(projection, selection, selectionArgs,
                    null, null, sortOrder);
            cursor.setNotificationUri(contentResolver, uri);
        } else if(uriMatcher.match(uri) == SINGLE_BOOK) {
            //content://com.pptv.test/bookstore/4 查找id=4的记录
            long select_id = ContentUris.parseId(uri);
            cursor = DBManager.getInstance(context).query(projection, MySqliteHelper.COLUMN_ID + "=?",
                    new String[]{select_id +""},
                    null, null, sortOrder);
            cursor.setNotificationUri(contentResolver, uri);
        }
        return cursor;
    }

}

UriMatcher的作用在于,控制不同Uri的操作权限以及操作内容
比如上述code所示:content://com.pptv.test/bookstore 执行查找其返回所有符合条件的记录,而content://com.pptv.test/bookstore/4 执行查找方法,其仅仅返回id为4的记录

在AndroidManifest中注册provider

    <provider
        android:name=".provider.MyProvider"
        android:authorities="com.pptv.test"
        android:enabled="true"
        android:exported="true" />
  • android:authorities 访问这个provider的权限,需要和MyProvider中定义的AUTHORITY保持一致。
  • android:enabled 指定这个内容提供器是否能够被系统安装
  • android:exported 指定该内容提供器是否能够被其他的应用程序组件使用

其他应用使用Provider来访问数据

获取一个ContentResolver类

直接使用Content类的getContentResolver()方法就能获取到。

通过ContentResolver执行增删改查操作

ContentResolver的主要方法:

返回值函数声明
final Uriinsert(Uri url, ContentValues values)
final intdelete(Uri url, String where, String[] selectionArgs)
final intupdate(Uri uri, ContentValues values, String where, String[] selectionArgs)
final Cursorquery(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)

例如:查询所有的数据

    private String getData(){
        StringBuilder sb =new StringBuilder();
        ContentResolver cr = this.getContentResolver();
        Uri uri = Uri.parse("content://com.pptv.test/bookstore");
        Cursor cursor = cr.query(uri, null, null,null,null);
        if(cursor != null){
            Log.i(TAG, "cursor != null");
            while(cursor.moveToNext()){
                String name = cursor.getString(cursor.getColumnIndex("name"));
                String author = cursor.getString(cursor.getColumnIndex("author"));
                float price = cursor.getFloat(cursor.getColumnIndex("price"));
                int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                sb.append("name = " + name + ", ")
                        .append("author = " + author + ", ")
                        .append("price = " + price + " ,")
                        .append("pages = " + pages + "\n");
            }
            cursor.close();
        }
        return sb.toString();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值