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

更新时间修改意见
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());
    
    ContentResolver
    cr = getContentResolver();
    cr.registerContentObserver(MyContentProvider.CONTENT_BOOKS_URI, true, mContentObserver);
  3. 当程序退出或者不需要再监听Uri的变化时,要主动取消对Uri的监听,

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

6.2 ContentProvider的配合

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

@Override
public 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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值