对发送、接收广播 添加 自定义的权限

在写之前,我们先回顾一下权限问题。

<!-- 如果不使用,在试图连接到网络时应用程序会崩溃。 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 如果没有这项权限,应用程序将在系统启动时被忽略  从而不会运行自身的启动代码,从而还没有任何错误提示 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!--  用户接收网络状态更新所需的权限-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

权限的作用:应用程序只有在获取到相应权限后,才可访问系统的某些特定的受限功能(比如:连接网络、发短信、打电话等),用户需要在安装时就指定该应用程序能否使用这些权限。程序开发者则需要在manifest文件中罗列出所有该程序需要的权限。


我们要解决的问题:现在更新时间轴receiver,但我们希望针对收发这条广播设定相应的权限。否则,其他程序只要知道action事件的名字,即可伪造出我们的广播并发送,从而导致一些不可预料的问题。为修补此项安全漏洞,我们需要定义出自己的权限列表并询问用户是否将其赋予给应用程序。这样,就需要对发布者和订阅者双方权限做强化限制。

第一步:在Manifest文件中声明权限

<permission android:name="com.example.SNED_TIMELINE_NOTIFICATIONS"
       
        android:label="@string/send_timeline_notifications_permission_label"
         android:description="@string/send_timeline_notifications_permissin_description"
        android:permissionGroup="android.permission-group.PERSONAL_INFO"
        android:protectionLevel="normal"/>

    <permission
        android:name="com.example.RECEIVE_TIMELINE_NOTIFICATIONS"
        android:label="@string/receive_timeline_notifications_permission_label"
        android:description="@string/receive_timeline_notifications_permission_description"
        android:permissionGroup="android.permission-group.PERSONAL_INFO"
        android:protectionLevel="normal"></permission>

<uses-permission android:name="com.example.SNED_TIMELINE_NOTIFICATIONS"/>
<uses-permission android:name="com.example.RECEIVE_TIMELINE_NOTIFICATIONS"/>

    我们添加了两项权限,也为应用程序申请了这两项权限。接下来,我们需要保证广播的发布者与订阅者能够分别使用自己的权限。

第二步:为更新服务应用权限机制。
    更新服务会在每次状态更新时广播一条intent,但我们不希望所有人都可以收到这条intent.因此在下边代码中,我们   限制只有获得授权的receiver才可以收到这条intent.

private class Updater extends Thread{
public Updater() {
super("UpdateService--Updater");
}

@Override
public void run() {
//获取数据,如果有新数据,则发送广播
intent = new Intent("com.example.NEW_STATUS");
              intent.putExtra(NEW_STATUS_EXTRA_COUNT, newUpdates);

//receiver必须拥有的权限名字,它必须要与之前指定的manifest文件中的权限名字一致
//为增强receiver的权限,我们直接将权限名称作为sendBroadcast()调用的第二个参数。
//如果receiver没有被用户赋予此特殊权限,就不会被告知也无从知道消息被无声无息丢弃。
updateService.sendBroadcast(intent, "com.example.RECEIVE_TIMELINE_NOTIFICATIONS");
}

Log.d(TAG, "Updater RAN.");
Thread.sleep(DELAY);

} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
updateService.runFlag = false;
}

}
}

}

第三步:需要在receiver端做检查,看广播者是否允许与receiver端交谈。为此,在注册receiver时为它添加上sender端所需要拥有的广播权限。

public class TimelineActivity3 extends BaseActivity{


@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();


// 注册receiver对象
registerReceiver(receiver, filter, "com.example.SNED_TIMELINE_NOTIFICATIONS",null);
}
  
     将权限名字定义为一个常量字符串,它的值必须与manifest中定义的权限名字必须一致。在注册TimelineReceiver的anResume()方法中,需要添加新的参数一标明:发送者只有拥有了该项权限,才可以发送出此种类型的广播。



    

猜你喜欢

转载自zhangjie0919.iteye.com/blog/1853450