四大组件之ContentProvider(四)-ContentProvider的权限使用和监听

来源:互联网 发布:阿里云蜘蛛池 编辑:程序博客网 时间:2024/06/06 03:33
更新时间 修改意见 2016-08-02 陈敏

第5节 ContentProvider的使用权限

ContentProvider可以被其他应用使用(就像一个公共网站,可以被任何人访问);也可以被设置成只被自己所在的应用使用(就像一个内部网站,只能在公司内部访问)。

这只需要在应用的AndroidManifest.xml文件中,给ContentProvider设置上android:exported属性,

<provider    android:name=".MyContentProvider"    android:authorities="com.anddle.mycontentprovider"    android:enabled="true"    android:exported="true" />
  1. android:exported属性设置成true:可被其他应用使用;
  2. android:exported属性设置成false:只能被自己所在的应用使用;

在对其他应用开放ContentProvider的时候,也可以设置上访问权限,只对部分应用开放使用的权限。

5.1 ContentProvider设置权限

  1. AndroidManifest.xml文件中,对要设置权限的ContentProvider设置上android:permission属性,该属性值可以任意指定一个字符串。通常使用程序的包名作为其中的一部分,这样可以避免和其他应用中的权限声明冲突。例如"com.anddle.provideraccess

    <provider    android:name=".MyContentProvider"    android:authorities="com.anddle.mycontentprovider"    android:enabled="true"    android:exported="true"    android:permission="com.anddle.provideraccess" />
  2. AndroidManifest.xml文件中,与同级的位置,对外声明前面使用的标签,表示这个应用发布了一个叫做com.anddle.provideraccess的权限,

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.anddle.lifetime">    <permission        android:name="com.anddle.provideraccess"        android:label="provider pomission"        android:protectionLevel="normal" />   <application        ....../></manifest>

    其中android:name属性的值,就是<provider/>标签中设置的android:permission的值。

5.2 使用带权限的ContentProvider

假如应用B要使用应用A中带权限的ContentProvider,需要在应用B的AndroidManifest.xml中加入权限的使用,

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.anddle.calculator">    <uses-permission android:name="com.anddle.provideraccess"/>    <application            ....../></manifest>

其中,<uses-permission/>标签中设置的android:name的值,就是应用A中对外声明的那个provider的权限值。

5.3 进一步的权限设置

应用A的ContentProvider还可以将访问的权限进一步细化,分成允许读取和允许写入两种。

ContentProvider设置了读取的权限,那么其他组件想读取到该ContentProvider的内容时,就必须声明使用的权限。

ContentProvider设置了写入的权限,那么其他组件想写入该ContentProvider的内容时,就必须声明使用的权限。

  1. 声明“读取”权限,

    <provider    android:name=".MyContentProvider"    ......    android:readPermission="com.anddle.provideraccess.read" />

    发布“读取”权限,

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.anddle.lifetime">    <permission        android:name="com.anddle.provideraccess.read"        android:label="provider pomission"        android:protectionLevel="normal" />   <application        ....../></manifest>
  2. 声明“写入”权限,

    <provider    android:name=".MyContentProvider"    ......    android:writePermission="com.anddle.provideraccess.write" />

    发布“写入”权限,

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.anddle.lifetime">    <permission        android:name="com.anddle.provideraccess.write"        android:label="provider pomission"        android:protectionLevel="normal" />   <application        ....../></manifest>

需要注意的是,android:writePermissionandroid:readPermission权限的优先级比android:permission的优先级高,只要设置了高优先级的,那么其他应用要使用高优先级的功能,就要声明高优先级的权限。

例如,一个ContentProvider同时设置了android:readPermissionandroid:permission权限,第三方应用如果只请求了android:permission权限,是没有办法进行读取操作的。


/*******************************************************************/
* 版权声明
* 本教程只在CSDN和安豆网发布,其他网站出现本教程均属侵权。
/*******************************************************************/

第6节 ContentProvider的监听

ContentProvider中存储的数据内容发生变化时,是可以被关注了这些消息的查询者监听到的。

6.1 调用者监听的方法

  1. 继承ContentObserver,创建监听器类,

    public class MyObserver extends ContentObserver {    public MyObserver(Handler handler) {        super(handler);    }    @Override    public void onChange(boolean selfChange) {        super.onChange(selfChange);        //添加变化的处理逻辑    }}
  2. 注册对指定Uri的监听函数,一旦该Uri指向的内容发生改变,将通知到MyObserver

    mContentObserver = new MyObserver(new Handler());ContentResolvercr = getContentResolver();cr.registerContentObserver(MyContentProvider.CONTENT_BOOKS_URI, true, mContentObserver);
  3. 当程序退出或者不需要再监听Uri的变化时,要主动取消对Uri的监听,

    ContentResolvercr = getContentResolver();cr.unregisterContentObserver(mContentObserver);

6.2 ContentProvider的配合

ContentProvider里,每当特定Uri上的数据发生变化,要触发对调用者的通知。通知使用ContentResolvernotifyChange()方法触发,

@Overridepublic Uri insert(Uri uri, ContentValues values) { Uri result = null;
 switch (sUriMatcher.match(uri)) {     case BOOKS: {           SQLiteDatabase db = mDBHelper.getWritableDatabase();           long id = db.insert(DBHelper.TABLE_NAME, null, values);           if(id > 0) {               result = ContentUris.withAppendedId(CONTENT_BOOKS_URI, id);               getContext().getContentResolver().notifyChange(uri, null);           }     }     break;     ......     default:         throw new IllegalArgumentException("Unknown URI " + uri); } return result;}

/*******************************************************************/
* 版权声明
* 本教程只在CSDN和安豆网发布,其他网站出现本教程均属侵权。
/*******************************************************************/

1 0
原创粉丝点击