Android 组件ContentProvider(一)内容提供器

Android 组件ContentProvider(一)内容提供器


1. ContentProvider内容提供器

内容提供器可以让不同的应用程序之间实现数据共享的功能,允许一个程序访问另外一个程序中的数据,同时保证被访问数据的安全性,而之前的数据持久化而保存的数据只能是能被当前的应用程序使用。
文件存储和SharedPreferences存储可以实现全局读写操作模式,内容提供器可以选择对一部分数据进行共享,从而保证隐私数据不会有泄露的风险。

2. 运行时权限

说到内容提供器,在Android系统中本身就提供了很多的内容提供器,比如联系人,短信,日历等,既要是实现一个应用程序访问另一个应用程序的共享数据,又要保证数据的隐私安全,就不得不涉及到访问的权限,运行时权限是Android6.0加入的改进的权限申请机制,运行时权限功能避免用户一次性授权所有申请权限,可以在使用的过程中再进一步授权。这个可分为两类:1、普通权限;2、危险权限。
Android应用程序清单里添加权限。
在Intent中添加申请权限。

3. 访问其他程序中的数据

内容提供器提供的两种方法:1、现有的内容提供器;2、自定义的内容提供器。

a. ContentResolver

应用程序想要访问内容提供器中的共享数据,就要使用ContentResolver这个类,通过Context中的getContentResolver()方法获取该类的实例。
ContentResolver类提供一些方法进行CRUD数据操作。在这些操作中ContentResolver是不接收表名的参数的,而是接收Uri参数代替,URI给内容提供器中的数据建立了唯一标识符 。
i. Uri包括authority和path。authority是对不同应用程序做区分(会使用包名来进行命名),path是对同一应用程序不同的表做区分,有的还会存在id。”content:”是用来标识数据是由Content Provider管理的 schema。
Uri uri=Uri.parse(“content://com.example.app.provider/table1”)
Cursor cursor = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);
ii. ContentValues 添加数据。这个和SQLite的添加数据方式一样。

b. 自定义内容提供器

通过上面的学习我们知道,向外访问其他应用程序的数据,只需获取该程序的内容URI,再利用ContentResolver进行CRUD操作就可以了。
那问题来了,那些 提供外部访问接口的应用程序是怎么实现这个功能的呢?怎么保证数据安全隐私不被泄露呢?
实现跨程序共享数据的功能,要新建一个类去继承ContentProvider类创建自己的内容提供器,并重写类中6个抽象方法。

//创建UriMatcher类,利用match()方法来匹配传入的URI的功能,
// static中先定义了可以被访问的数据的路径
            public static final String AUTHORITY = "com.example.databasetest.provider";
            private static UriMatcher uriMatcher;
            static {
                uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
                uriMatcher.addURI("AUTHORITY", "book", BOOK_DIR);
                uriMatcher.addURI("AUTHORITY", "book/#", BOOK_ITEM);
                uriMatcher.addURI("AUTHORITY", "category", CATEGORY_DIR);
                uriMatcher.addURI("AUTHORITY", "table2/#", CATEGORY_ITEM);
            }

        //继承ContentProvider类要重写的6个方法,方法里访问数据的操作和SQLite里的操作一样
            @Override
            public boolean onCreate(){
                return false;
            }       
            @Override
            public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
                SQLiteDatabase db = dbHelper.getReadableDatabase();
                Cursor cursor = null;
                switch (uriMatcher.match(uri)) {
                    case BOOK_DIR:
                        cursor = db.query("Book", projection, selection, selectionArgs, null, null, sortOrder);
                        break;
                    case BOOK_ITEM:
        //getPathSegments()将URI分成列表第0个位置存放Uri路径,第1个存放id
                        String bookId = uri.getPathSegments().get(1);
                        cursor = db.query("Book", projection, "id=?", new String[]{bookId}, null, null, sortOrder);
                        break;
                    case CATEGORY_DIR:
                        cursor = db.query("Category", projection, selection, selectionArgs, null, null, sortOrder);
                        break;
                    case CATEGORY_ITEM:
                        String categoryId = uri.getPathSegments().get(1);
                        cursor = db.query("Category", projection, "id=?", new String[]{categoryId}, null, null, sortOrder);
                        break;
                    default:
                        break;
                }
                return cursor;
            }

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

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

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

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

URI所对应的MIME字符串3部分组成:vnd开头;Uri以路径结尾 android.cursor.dir/,如以id结尾 android.cursor.item/;最后接上vnd.<authority>.<path>。如vnd.android.cursor.dir/vnd.com.example.app.provider.table1

c. AndroidManifest.xml注册provider

        <provider
            android:name=".DatabaseProvider"
            android:authorities="com.example.databasetest.provider"
            android:enabled="true"
<!--允许外部应用程序访问这个内容提供器-->
            android:exported="true" >
        </provider>

d. 获取内容提供器中的数据就要使用到ContentResolver中的CRUD操作

Uri uri = Uri.parse("content://com.example.databasetest.provider/book");
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);
        if (cursor != null) {
            while (cursor.moveToNext()) {
                String name = cursor.getString(cursor.getColumnIndex("name"));
                String author = cursor.getString(cursor.getColumnIndex("author"));
                int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                double price = cursor.getDouble(cursor.getColumnIndex("price"));
            }
            cursor.close();
//更新数据和SQLite中使用到的更新的方法和相似,
        Uri uri = Uri.parse("content://com.example.databasetest.provider/book");
        ContentValues values = new ContentValues();
        values.put("name", "aaaa");
        values.put("author", "jack");
        values.put("pages", 1040);
        values.put("price", 111);
        Uri newUri = getContentResolver().insert(uri, values);
        newId = newUri.getPathSegments().get(1);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值