博客
关于我
Android学习笔记之——发送broadcast
阅读量:508 次
发布时间:2019-03-07

本文共 11021 字,大约阅读时间需要 36 分钟。

之前博文《》已经介绍了broadcast的接收的机制。本博文学习一下如何取发布broadcast。

 

目录


 

发送标准广播

在发送广播之前,我们还是需要先定义一个广播接收器来准备接收此广播才行,不然发出去也是白发。因此新建一个MyBroadcastReceiver的类,代码如下所示:

package com.example.broadcasttest;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.widget.Toast;public class MyBroadcastReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        // TODO: This method is called when the BroadcastReceiver is receiving        // an Intent broadcast.        Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();    }}

然后在AndroidManifest.xml中对这个广播接收器进行修改:

这里的action就是发布这个工程的消息了

定义完接收机后,来定义一下发布。接下来修改activity_main.xml中的代码,如下所示:

在布局文件中定义了一个按钮,用于作为发送广播的触发点。然后修改MainActivity中的代码,如下所示:

package com.example.broadcasttest;import androidx.appcompat.app.AppCompatActivity;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MainActivity extends AppCompatActivity {    //完成该activity各种初始化操作,如加载布局、绑定事件等    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button button= (Button) findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //构建一个intent对象,将要发送的广播加入                Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");                //调用setComponent方法指定广播接收器(模拟器需要这一步才可以实现成功)                intent.setComponent(new ComponentName("com.example.broadcasttest","com.example.broadcasttest.MyBroadcastReceiver"));                sendBroadcast(intent);//调用了Context的sendBroadcast() 方法将广播发送出去            }        });    }}

注意:这里在用sendBroadcast(intent)把广播发送出去之前调用了 setComponent方法指定广播接收器,效果图如下(此处我是模拟器测试需要调用该方法,但是真机测试没有该方法也能接收到)

结果如下图所示

broadcast和activity一样都是通过intent进行传递的~

发送有序广播

广播是一种可以跨进程的通信方式,在一个应用程序内发出的广播,其他的应用程序应该也是可以收到的。

新建AnotherBroadcastReceiver,用于接收上一part中自定义的广播 ,代码如下所示:

package com.example.broadcasttest;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.widget.Toast;public class AnotherBroadcastReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        // TODO: This method is called when the BroadcastReceiver is receiving        // an Intent broadcast.//        throw new UnsupportedOperationException("Not yet implemented");        Toast.makeText(context, "received in AnotherBroadcastReceived", Toast.LENGTH_SHORT).show();                    }}

仍然是在广播接收器的onReceive() 方法中弹出了一段文本信息。然后在AndroidManifest.xml中对这个广播接收器进行修改,代码如下所示:

对应的mainactivity

package com.example.broadcasttest;import androidx.appcompat.app.AppCompatActivity;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MainActivity extends AppCompatActivity {    //完成该activity各种初始化操作,如加载布局、绑定事件等    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button button= (Button) findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //构建一个intent对象,将要发送的广播加入                Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");                //调用setComponent方法指定广播接收器(模拟器需要这一步才可以实现成功)                intent.setComponent(new ComponentName("com.example.broadcasttest","com.example.broadcasttest.MyBroadcastReceiver"));                sendBroadcast(intent);//调用了Context的sendBroadcast() 方法将广播发送出去                Intent intent1 = new Intent("com.example.broadcasttest.MY_BROADCAST");                intent1.setComponent(new ComponentName("com.example.broadcasttest","com.example.broadcasttest.AnotherBroadcastReceiver"));                sendBroadcast(intent1);            }        });    }}

AnotherBroadcastReceiver同样接收的是com.example.broadcasttest.MY_BROADCAST 这条广播。运行代码会发现,点击一下按钮,会出现两次提醒信息

发送有序广播只需要改动一行代码,即将sendBroadcast() 方法改成sendOrderedBroadcast() 方法

package com.example.broadcasttest;import androidx.appcompat.app.AppCompatActivity;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MainActivity extends AppCompatActivity {    //完成该activity各种初始化操作,如加载布局、绑定事件等    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button button= (Button) findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //构建一个intent对象,将要发送的广播加入                Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");                //调用setComponent方法指定广播接收器(模拟器需要这一步才可以实现成功)                intent.setComponent(new ComponentName("com.example.broadcasttest","com.example.broadcasttest.MyBroadcastReceiver"));//                sendBroadcast(intent);//调用了Context的sendBroadcast() 方法将广播发送出去                sendOrderedBroadcast(intent, null);                //sendOrderedBroadcast() 方法接收两个参数,                // 第一个参数仍然是Intent ,                // 第二个参数是一个与权限相关的字符串,这里传入null 就行了                Intent intent1 = new Intent("com.example.broadcasttest.MY_BROADCAST");                intent1.setComponent(new ComponentName("com.example.broadcasttest","com.example.broadcasttest.AnotherBroadcastReceiver"));                sendOrderedBroadcast(intent1, null);            }        });    }}

然后通过AndroidManifest.xml中的代码设定接收的先后顺序。通过android:priority 属性给广播接收器设置了优先级,优先级比较高的广播接收器就可以先收到广播。

设置了优先权后,就可以决定广播的优先权了哈~

 

使用本地广播

前面发送和接收的广播全部属于系统全局广播,即发出的广播可以被其他任何应用程序接收到,并且也可以接收来自于其他任何应用程序的广播。这样就很容易引起安全性的问题,比如说发送的一些携带关键性数据的广播有可能被其他的应用程序截获,或者其他的程序不停地向我们的广播接收器里发送各种垃圾广播。为了能够简单地解决广播的安全性问题,Android引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播,这样所有的安全性问题就都不存在了。

本地广播主要就是使用了一个LocalBroadcastManager来对广播进行管理,并提供了发送广播和注册广播接收器的方法。修改MainActivity中的代码,如下所示:

package com.example.broadcasttest;import androidx.appcompat.app.AppCompatActivity;import androidx.localbroadcastmanager.content.LocalBroadcastManager;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MainActivity extends AppCompatActivity {    private IntentFilter intentFilter;    private LocalReceiver localReceiver;    private LocalBroadcastManager localBroadcastManager;    //完成该activity各种初始化操作,如加载布局、绑定事件等    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        localBroadcastManager= LocalBroadcastManager.getInstance(MainActivity.this);//先获取一个实例        Button button= (Button) findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {//                Intent intent1 = new Intent("com.example.broadcasttest.MY_BROADCAST");//                intent1.setComponent(new ComponentName("com.example.broadcasttest","com.example.broadcasttest.AnotherBroadcastReceiver"));//                sendOrderedBroadcast(intent1, null);//                //构建一个intent对象,将要发送的广播加入                Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");//注意要发送的名称跟下面的匹配//                //调用setComponent方法指定广播接收器(模拟器需要这一步才可以实现成功)//                intent.setComponent(new ComponentName("com.example.broadcasttest","com.example.broadcasttest.MyBroadcastReceiver"));                localBroadcastManager.sendBroadcast(intent); //发送本地广播                //调用的是LocalBroadcastManager的sendBroadcast() 方法来发送广播                sendBroadcast(intent);//调用了Context的sendBroadcast() 方法将广播发送出去//                sendOrderedBroadcast(intent, null);//                //sendOrderedBroadcast() 方法接收两个参数,//                // 第一个参数仍然是Intent ,//                // 第二个参数是一个与权限相关的字符串,这里传入null 就行了            }        });        //注册一个本地广播监听器        intentFilter=new IntentFilter();        intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");//这个action是上面发送的        localReceiver = new LocalReceiver();        localBroadcastManager.registerReceiver(localReceiver, intentFilter);//通过上面定义的实例来注册广播接收器    }    @Override    protected void onDestroy() {        super.onDestroy();        localBroadcastManager.unregisterReceiver(localReceiver);    }    //定义这个localreceiver的类来接收local的广播    class LocalReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();        }    }}

本地广播是无法通过静态注册的方式来接收的。其实这也完全可以理解,因为静态注册主要就是为了让程序在未启动的情况下也能收到广播,而发送本地广播时,我们的程序肯定是已经启动了,因此也完全不需要使用静态注册的功能。

 

 

 

参考资料

 

 

 

 

 

 

 

 

 

 

转载地址:http://udajz.baihongyu.com/

你可能感兴趣的文章
MySQL、Redis高频面试题汇总
查看>>
MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
查看>>
mysql一个字段为空时使用另一个字段排序
查看>>
MySQL一个表A中多个字段关联了表B的ID,如何关联查询?
查看>>
MYSQL一直显示正在启动
查看>>
MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
查看>>
MySQL万字总结!超详细!
查看>>
Mysql下载以及安装(新手入门,超详细)
查看>>
MySQL不会性能调优?看看这份清华架构师编写的MySQL性能优化手册吧
查看>>
MySQL不同字符集及排序规则详解:业务场景下的最佳选
查看>>
Mysql不同官方版本对比
查看>>
MySQL与Informix数据库中的同义表创建:深入解析与比较
查看>>
mysql与mem_细说 MySQL 之 MEM_ROOT
查看>>
MySQL与Oracle的数据迁移注意事项,另附转换工具链接
查看>>
mysql丢失更新问题
查看>>
MySQL两千万数据优化&迁移
查看>>
MySql中 delimiter 详解
查看>>
MYSQL中 find_in_set() 函数用法详解
查看>>
MySQL中auto_increment有什么作用?(IT枫斗者)
查看>>
MySQL中B+Tree索引原理
查看>>