Andorid 8.0 对广播的使用做了变更。

当广播接收器使用静态注册方式使用时,除了一些例外,这个接收器接收不到隐式广播。 注意这个“隐式”是重点。

看了网上几篇文章,对这个变更理解有误。错误的理解是:8.0后,广播接收器使用静态注册,是无法使用的。
实时并非如此。

先看一个例子:

首先,定义一个简单的广播接收器:

public class MyReceiver extends BroadcastReceiver {

    @Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,context.toString(),Toast.LENGTH_SHORT).show();
}
}

它对接收到广播的行为就是打印一句话。

第二,我们将他注册到Manifest文件中。

        <receiver android:name=".broadcast.MyReceiver">
<intent-filter>
<action android:name="com.demo.recriver"/>
</intent-filter>
</receiver>

最后,在Activity中发送一个广播,intent通过设置Action为com.demo.recriver的形式发送隐式广播。

public class MainActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = Intent intent = new Intent("com.demo.recriver");//隐式intent,发送隐式广播
sendBroadcast(intent);
}
}

运行这个demo,发现在8.0以下的手机上,会有Toast显示,8.0以上的手机不会弹出,说明没有接收到广播。

原因在于这个广播 是“隐式” 发送的,8.0中,静态注册的广播接收者无法接受 隐式 广播。

为了解决这个问题,有两个方法:

1 在Activity或其他组件中动态注册广播

2 发送显示广播

对于1 ,如果想广播让接收者工作,必须要在某个Activity或者其他组件中调用registerReceiver()进行注册,在onDestroy()时还要反注册,代码稍显复杂,而且静态注册的广播接收者仍处于不可用的状态。不合理。

而后一种方法 ,因为sendBroaccast是自己主动发送的,明显知道要哪个broadcastReceiver来进行处理,直接发送显示广播即可。

具体的代码如下,将MainActivity做修改:

public class MainActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
intent.setComponent(new ComponentName(MainActivity.this,MyReceiver.class));//显示指定组件名称
sendBroadcast(intent);
}
}

实际上,这种写法与更常见的以下写法相同:

public class MainActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(MainActivity.this,MyReceiver.class);//显示指定组件名
sendBroadcast(intent);
}
}

运行,发现可以弹出Toast,静态注册的BroadcastReceiver接收到了广播。证明静态注册是可以接收到广播的。

顺便插一句:

Intent指定action, 这个Intent则为隐式Intent,使用它发送的广播则为隐式广播。隐式广播接收者是通过IntentFilter去查找的。
Intent指定了组件名称,这个Intent为显式Intent,用他发送的广播为显式广播。广播接收者直接就是指定的组件名称对应的广播接收者。

猜测显式Intent不使用IntentFilter去查找组件(Activtiy,Service,BroadcastReceiver),这点读者有兴趣可以验证是否正确。

再来看一下Intent的setComponent()方法:

Intent设置了组件名称(比如 new Intent(MainActivity.this,MyReceiver.class);)则通过IntentFilter匹配所需要的action,data,type,category信息会被忽略。

如果刚才的例子做如下改动:

public class MainActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
intent.setAction("com.abcdefg.hijklmn");//指定action--不存在的action
intent.setComponent(new ComponentName(MainActivity.this,MyReceiver.class));//同时显式指定组件名
sendBroadcast(intent);
}
}

同时指定了隐式的action 以及显式的组件名称,action是一个不存在的action。这时仍可以接收到广播。
虽然通过action不可能匹配到一个广播接收者,但显示设置了组件,action就被忽略了。

扯远了。回到最初的那个话题。8.0以后,静态注册的广播接受者是可以接收到广播的,只要广播是通过显示方式发送的。

关于Android8.0 静态注册广播 行为变更的说明。的更多相关文章

  1. Android静态注册广播无法接收的问题(8.0+版本)

    如果你静态注册的广播无法接收到消息,请先检查下:你的安卓版本是不是8.0+ * 前言** Google官方声明:Beginning with Android 8.0 (API level 26), t ...

  2. Android 8.0新特性-取消大部分静态注册广播

    今天楼主在写一个广播的demo,功能非常的简单,就是一个应用发送一个自定义的广播,同时在这个应用里面定义了一个广播接受者,并且在AndroidManifest文件中进行静态的注册.Demo看上去非常的 ...

  3. BroadcastReceiver的两种注册方式之------静态注册

    activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...

  4. Android8.0 后台服务保活的一种思路

    原文地址:Android8.0 后台服务保活的一种思路 | Stars-One的杂货小窝 项目中有个MQ服务,需要一直连着,接收到消息会发送语音,且手机要在锁屏也要实现此功能 目前是使用广播机制实现, ...

  5. Android中的BroadCast静态注册与动态注册

    1.静态注册 新建MyBroadcast类继承BroadcastReceiver,实现onReceive方法 /** * Author:JsonLu * DateTime:2015/9/21 16:4 ...

  6. Android 8.0的平台上,应用不能对大部分的广播进行静态注册

    引言在Android 8.0的平台上,应用不能对大部分的广播进行静态注册,也就是说,不能在AndroidManifest文件对有些广播进行静态注册,这里必须强调是有些广播,因为有些广播还是能够注册的. ...

  7. 关于静态注册BroadcastReceiver接收不到广播的问题

    1.背景&解决方法 最近碰到一个需求,app监听特定的广播,接收到广播后启动自己再进行处理.需求很简单,静态注册就好,不过,在自测的时候遇到一个问题,app安装后没启动过的状态下,什么广播都收 ...

  8. BroadcastReceiver(广播)的静态注册和动态注册 --Android开发

    BroadcastReceiver是安卓四大组件之一,本例通过代码的方式演示静态注册和动态注册. 1.静态注册 静态注册只需要AndroidManifest.xml中进行配置: AndroidMani ...

  9. Android高版本收不到静态注册的广播

    Beginning with Android 8.0 (API level 26), the system imposes additional restrictions on manifest-de ...

随机推荐

  1. 工业网络安全 智能电网,SCADA和其他工业控制系统等关键基础设施的网络安全(总结)

    1.工业网络的安全势必是未来安全方向必须要做的一个重要的方面 工业网络的概念:简单的说就是控制控制系统的网络,其可以进行基于网络的数字通信. 关键的基础设施:包括直接操作任何系统的设施 了解工业网络的 ...

  2. CentOS上使用ntfs-3g挂载NTFS分区

    U盘做过系统盘,是NTFS格式的,Centos7竟然不识别,而且因为一些原因,我的服务器没有联网,只能用U盘 查过资料才知道Centos7上默认是不支持挂载NTFS格式的分区的,需要安装ntfs-3g ...

  3. tomcat运行一段时间出“org.apache.coyote.http11.Http11Processor.service Error parsing HTTP request header”

    试了好多种方法,貌似还是没有解决问题,不过也学到了点东西,记录下备忘吧. 异常详情: 1.首先看到最多的就是说在server.xml中的Connector中添加maxHttpHeaderSize=&q ...

  4. 使用Cloudera Manager搭建YARN集群及YARN HA

    使用Cloudera Manager搭建YARN集群及YARN HA 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.使用Cloudera Manager搭建YARN集群 1& ...

  5. git---怎样将分支上的一个单文件合并到主分支上(master)

    一.首先切换到主分支  注意将分支上的数据全部提交 以免造成数据冲突或丢失 git checkeout master 二.选择要合并的文件 git checkout --patch 分支名称  要合并 ...

  6. IDEA 使用教程(破解2019.1.1)

    2019-08-02更新 最新破解方法: ZKVVPH4MIO-eyJsaWNlbnNlSWQiOiJaS1ZWUEg0TUlPIiwibGljZW5zZWVOYW1lIjoi5o6I5p2D5Luj ...

  7. 利用Python3的requests和re库爬取猫眼电影笔记

    以下笔记,作为参考借鉴,如有疑问可以联系我进行交流探讨! 代码思路很简单,简单概括为:   首先利用requests的get方法获取页面的html文件,之后对得到的html文件进行相对应的正则处理,然 ...

  8. HihoCoder1236 Scores

    Scores 求五维偏序(≤).强制在线. \(n,q\le 50000\) 烂大街的题解 考虑如果我们能用bitset找到每一维有哪些比询问点小,然后把每一维的结果取交集,得到的就是答案了. 然后对 ...

  9. DOS窗口操作MySQL数据库

    本周学习内容: 1.学习MySQL数据库.Linux私房菜: 2.等级评测培训: 3.练习MySQL数据库.练习CentOS7: 实验内容: 1.使用DOS窗口进入MySQL数据库 2.解决MySQL ...

  10. learning java AWT Pannel

    import java.awt.*; public class PanelTest { public static void main(String[] args) { var f = new Fra ...