关于系统发送的广播应用接收不到的问题

原文链接:https://juejin.im/post/5a8ae9ddf265da4e896ad966

##问题解决记录

最近发现了一个问题,我们的APK只能够接收待机下去的广播,而接收不到待机起来的广播。这就很奇怪了,于是便找到了系统发送待机和待机起来广播的相关类。 frameworks\base\services\java\com\android\server\power\Notifier.java 从里面找到下面这段代码,可以看到对于开机和待机广播发送的代码其实是一样的。

mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
复制代码

既然如此,按理说我们的应用是可以接到到两个广播才对啊,不然就应该两个都收不到。于是便进一步分析自己的应用。分析后来发现,接受待机广播是静态注册的,而接收待机起来的广播是动态注册的。这时候可以注意到,两个 TAG 里面有一个Intent.FLAG_RECEIVER_REGISTERED_ONLY

我们查了一下,发现如果发送广播时设置了这个标志,那只会调用静态注册了的接收器——BroadcastReceiver组件不会被启动。所以这里就很明白了,因为我们需要比较快的接收到待机广播,从而做出处理,所以这里我们采用了优先级较高的动态注册,这样会一定程度上的防止接收不到广播的问题。那么要解决这个问题,只要在发送待机起来广播的时候把相应的TAG去掉就好,所以修改后代码如下: mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);

关于广播接收器的一些参考资料

广播接收器注册的两种形式

  • 静态注册 非常驻型广播,也就是说广播跟随activity的生命周期。注意: 在activity结束前,移除广播接收器。
  • 动态注册 常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行

广播的类型:

  1. 有序广播

    1. 优先级高的先接收
    2. 同优先级的广播接收器,动态优先于静态
    3. 同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后注册的。
  2. 普通广播

    1. 无视优先级,动态广播接收器优先于静态广播接收器
    2. 同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后注册的。
展开阅读全文

关于发送标准广播无法接收问题

01-03

activity——main.xmlrnrnrnrn rnrnrnMainActivity.javarnpackage com.example.lazdex.bt;rnrnimport android.content.BroadcastReceiver;rnimport android.content.Context;rnimport android.content.Intent;rnimport android.content.IntentFilter;rnimport android.net.ConnectivityManager;rnimport android.net.NetworkInfo;rnimport android.support.v7.app.AppCompatActivity;rnimport android.os.Bundle;rnimport android.view.View;rnimport android.widget.Button;rnimport android.widget.Toast;rnrnpublic class MainActivity extends AppCompatActivity rnrn @Overridern protected void onCreate(Bundle savedInstanceState) rn super.onCreate(savedInstanceState);rn setContentView(R.layout.activity_main);rn Button button=(Button)findViewById(R.id.button);rn button.setOnClickListener(new View.OnClickListener() rn @Overridern public void onClick(View view) rn Intent intent=new Intent("com.example.broadcasttest.MY_BROADCAST");rn sendBroadcast(intent);rn rn );rn rnrnBR.javarnpackage com.example.lazdex.bt;rnrnimport android.content.BroadcastReceiver;rnimport android.content.Context;rnimport android.content.Intent;rnimport android.widget.Toast;rnrnpublic class BR extends BroadcastReceiver rnrn @Overridern public void onReceive(Context context, Intent intent) rn // TODO: This method is called when the BroadcastReceiver is receivingrn // an Intent broadcast.rn Toast.makeText(context,"Boot Complete",Toast.LENGTH_LONG).show();rn rnrnAndroidManifest.xmlrnrnrn rn rn rn rn rn rn rn rn rn rn rn rn rn rn rnrnrnMBR.javarnpackage com.example.lazdex.bt;rnrnimport android.content.BroadcastReceiver;rnimport android.content.Context;rnimport android.content.Intent;rnimport android.widget.Toast;rnrnpublic class MBR extends BroadcastReceiver rnrn @Overridern public void onReceive(Context context, Intent intent) rn // TODO: This method is called when the BroadcastReceiver is receivingrn // an Intent broadcast.rn Toast.makeText(context,"received in MBR",Toast.LENGTH_SHORT).show();rn rnrn在仿真时始终无法接收到广播,没找到原因,求大神指点 论坛

没有更多推荐了,返回首页