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

来源:互联网 发布:mac在命令行使用mysql 编辑:程序博客网 时间:2024/04/25 07:50

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
原创粉丝点击