自定义权限

在清单文件中通过进行声明,然后通过引用自己声明的权限(可不引用)。示例:

android:name="com.baigle.imitatehandler.TEST"

android:protectionLevel="signature" />

protectionLevel

在自定义权限时,通常会指定protectionLevel属性,常用的如下:

normal:默认的,应用安装前,用户可以看到相应的权限,但无需用户主动授权。

dangerous:normal安全级别控制以外的任何危险操作。需要dangerous级别权限时,Android会明确要求用户进行授权。常见的如:网络使用权限,相机使用权限及联系人信息使用权限等。

signature:它要求权限声明应用和权限使用应用使用相同的keystore进行签名。如果使用同一keystore,则该权限由系统授予,否则系统会拒绝。并且权限授予时,不会通知用户。它常用于应用内部。例如:

android:name="com.baigle.imitatehandler.TEST"

android:protectionLevel="signature" />

android:name="com.baigle.imitatehandler.OtherActivity"

android:label="@string/app_name"

android:permission="com.baigle.imitatehandler.TEST" >

上面把protectionLevel声明为signature。如果别的应用使用的不是同一个签名文件,就没办法使用该权限,从而保护了自己的接收者。

BroadcastReceiver

对于广播接收者来说,别的应用也可以监听并触发我们的广播接收者。如果广播接收者注册在清单文件中,只需要在中配置android:exported="false"属性。这样,系统中的其它应用就无法触及到该receiver了。

但如果receiver是动态注册的,就需要创建自己的使用权限,并且将protectionLevel设置为signature。这样,当别的应用和receiver所在的应用使用的签名不一样时,便不会启动该receiver。例如:

注册广播接收者

BroadcastReceiver receiver = new OtherActivity();

IntentFilter filter = new IntentFilter("action1");

filter.addCategory(Intent.CATEGORY_DEFAULT);

//注册receiver时,直接指定发送者应该具有的权限。不然外部应用依旧可以触及到receiver

registerReceiver(receiver, filter, permission, null);

在注册的时候,最关键的一点是用registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)进行注册,而不是平常用的是registerReceiver(BroadcastReceiver, IntentFilter)。相较于后者,前者在注册的时候要求了发送者必须具有的权限。如果发送者没有该权限,那么发送者发送的广播即使经过IntentFilter的过滤,也不会被receiver接收。此时如果再自定义一个权限,并且将权限的protectionLevel设置为signature,那么外部应用便无法使用该权限,也就无法触及到该receiver。上面的permission便是这样的一个权限,声明如下:

android:name="com.baigle.imitatehandler.TEST"

android:protectionLevel="signature" />

发送广播的代码如下:

Intent intent = new Intent("action1");

intent.putExtra("text", "receiver");

intent.addCategory(Intent.CATEGORY_DEFAULT);

// 也可以使用sendBroadcast(intent);进行发送

sendBroadcast(intent, permission);

有序广播

通过sendBroadcast发送的广播都是无序广播,所有receiver的接收顺序和执行顺序都是无法确定,它们什么时候能运行完毕也是无法确定,

同时也无法在receiver之间进行通信。从而也无法使用getResultCode(),setResult()及abortBroadcast()

一系列的方法。

通过sendOrderedBroadcast()发送的广播便是有序广播。

特点

有序广播有如下特点:

1,所有的receiver依次执行。按优先级高低进行排序,优先级高的receiver先执行,直到最后。但优先级相同的receiver执行顺序不确定。

2,高优先级的receiver可以使用setResult()等方法向其后的receiver传递数据。

3,低优先级的receiver可以通过getResult()等方法来获取高优先级receiver通过setResult()等方法传递的数据。

4,所有的receiver都可以调用abortBroadcast()等方法中止广播,使广播不再往比它优先级低的receiver上传递。

5,优先级的注册方法有两种,在清单文件中可以通过为intent-filter中添加android:priority属性。在代码中,可以通过IntentFilter.setPriority()进行设置。优先级最低是-999。

功能

利用有序广播的上述特点,可以实现一些功能。比如当界面显示时不执行某个操作,而当界面不显示时执行某个操作。

具体思路:将执行操作放在一个低优先级的receiver中,同时在界面中注册一个高优先级的receiver,并且两个receiver的intent

一样。当界面接收到广播时,直接取消广播或者通知低优先的广播不执行操作。这里最主要的就是界面中的广播接收者要放在哪个方法中进行注册,一般是放在

onStart()和onStop()中的。因为这两个方法确定了界面可见的边界

注册和取消注册的代码略,只是在注册时要通过IntentFilter.setPriority()方法设置界面receiver的优先级,一般设置成1000。具体的接收者如下:

private class InterceptReceiver extends BroadcastReceiver {

//界面显示时,如果有广播,会执行到该方法。

public void onReceive(Context context, Intent intent) {

//setResultCode(Activity.RESULT_CANCELED);//改变resultCode的值

abortBroadcast();//或者直接取消广播

}

}

执行操作的receiver一般要根据resultCode的值判断是否应该进行某种操作。如下:

public void onReceive(Context context, Intent intent) {

int code = getResultCode();

if (code == Activity.RESULT_OK) {//do something

System.out.println("non canceled");

} else {//do nothing

System.out.println("canceled");

}

}

发送广播也没什么问题,只是在发送的时候将resultCode的值初始值设置为Activity.RESULT_OK,这主要是为了和执行操作的receiver相对应。如:

// 设置resultCode的初始值为RESULT_OK

sendOrderedBroadcast(intent, null, null, null,

Activity.RESULT_OK, null, null);

更多相关文章

  1. 广播
  2. android:priority
  3. Android工程中怎样使用隐藏API
  4. Android之Widget (微件、小组件)
  5. Android(安卓)6.0动态权限及跳转GPS设置界面
  6. Android(安卓)Launcher 应用的安装、更新、移除介绍
  7. 曾经的笔记——android的学习笔记(广播接收者)
  8. Android(安卓)Studio集成友盟SDK出现的问题解决及原因分析
  9. Android使用广播(BroadCast)实现强制下线的方法

随机推荐

  1. (转)运维角度浅谈MySQL数据库优化
  2. 删除2行1 Sql语句mysql
  3. 新导入项目数据库导入失败
  4. msql,触发器无事物回滚,插入之前满足条件
  5. 我的MYSQL学习心得(十一) 视图
  6. Excel数据快速导入mysql的几个办法
  7. ORACLE-SQL:定义并使用多字符串变量
  8. Oracle的PL/SQL块中select * from 查询结
  9. MySQL数据库SQL语法
  10. mysql5.5 允许远程访问