android安全:flag FLAG_RECEIVER_REGISTERED_ONLY的意义


尊重原创作者,转载请注明出处:

http://blog.csdn.net/gemmem/article/details/8859493


       做过时钟widget的朋友应该对ACTION_TIME_TICK都很熟悉,大家都用这个广播来更新UI界面上的时间,但是新版本的android中,却对TIME_TICK广播做了限制,系统不再允许在AndroidManifest.xml里面静态注册receiver来接受TIME_TICK广播了,程序员们被迫采用动态注册的方式来监听TIME_TICK广播。不知道大家碰到这个情况时是什么感想?

也许你当时在埋怨google害得你改代码,而且动态注册容易失效,因为进程可能会因为内存不足而被kill掉。

这不是给开发者添乱吗?

google为什么突然不允许采用xml方式注册TIME_TICK了呢?


TIME_TICK广播是alarmManagerService发送的,我们还是先看看源码:

 AlarmManagerService.java

    public AlarmManagerService(Context context) {
        mContext = context;
        mDescriptor = init();

        // We have to set current TimeZone info to kernel
        // because kernel doesn't keep this after reboot
        String tz = SystemProperties.get(TIMEZONE_PROPERTY);
        if (tz != null) {
            setTimeZone(tz);
        }

        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
        
        mTimeTickSender = PendingIntent.getBroadcast(context, 0,
                new Intent(Intent.ACTION_TIME_TICK).addFlags(
                        Intent.FLAG_RECEIVER_REGISTERED_ONLY), 0);
        Intent intent = new Intent(Intent.ACTION_DATE_CHANGED);

关键代码如下:

        mTimeTickSender = PendingIntent.getBroadcast(context, 0,
                new Intent(Intent.ACTION_TIME_TICK).addFlags(
                        Intent.FLAG_RECEIVER_REGISTERED_ONLY), 0);

原来google在intent中加入了FLAG_RECEIVER_REGISTERED_ONLY这个flag,这就是为什么xml注册会报错的原因。


我们再来看看广播ACTION_SCREEN_ON/OFF

void com.android.server.PowerManagerService.initInThread()

void initInThread() {  
    ……  
    mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);  
    mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);  
    mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);  
    mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);  
    ……  
}  

再来看一个广播,ACTION_BATTERY_CHANGED

电池电量发生变化的时候,系统发送此广播

void com.android.server.BatteryService.sendIntent()

private final void sendIntent() {  
    //  Pack up the values and broadcast them to everyone  
    Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);  
    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY  
            | Intent.FLAG_RECEIVER_REPLACE_PENDING);  
    ……  
}  

看到没有?它们都加了flag FLAG_RECEIVER_REGISTERED_ONLY。

也就是说,这些系统广播都只能动态注册。

下面说说google这样做的目的:

很多病毒程序为了保证自己被终止后能够再次运行,都会在xml中注册一些系统广播,企图利用这些系统高频广播来实现自启动。

比如在老版本的android系统中,病毒程序可以通过监听TIME_TICK来启动自己的service后台运行,做一些隐秘的工作,而且就算自己被kill掉了,也能很快重新启动。

而一旦这些系统广播加了flag FLAG_RECEIVER_REGISTERED_ONLY,这些病毒程序就没辙了。

google的这一改动无疑提升了android系统的安全性。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值