Broadcast Receiver 广播机制

1、什么是安卓的Broadcast?
安卓的四大组件之一,是一种广泛应用在应用程序之间传输信息的机制。

2、什么是安卓的BroadcastReceiver?
是对发送出来的广播进行过滤接收并响应的一类组件,它就是用来接收来自系统和应用中的广播。例如系统的广播有开机广播: 系统在开机时候会发送开机广播,程序接收到之后,能进行开机自启动。 网络状态改变广播: 3g变wifi、网络断开等。电量改变广播等等。。。
(1).同一app内部的同一组件内的消息通信(单个或多个线程之间);
(2).同一app内部的不同组件之间的消息通信(单个进程);
(3).同一app具有多个进程的不同组件之间的消息通信;
(4).不同app之间的组件之间消息通信;
(5).Android系统在特定情况下与App之间的消息通信。

3、Anroid为什么要这样设计?
大大减少开发工作量和开发周期。作为开发者,只需要掌握BroadcastReceiver

4、怎么理解Broadcast和BroadcastReceiver ?
Broadcast就像现实中的广播电台,他发广播信号来,然后我们用收音机来接收,然后处理,并且播放出声音, BroadcastReceiver就相当于那台收音机。

5、使用方法
发送:
把信息装入一个Intent对象(如:Action、Category),通过调相应的方法将Intent对象以广播的方式发送出去:
sendBroadcast();
sendOrederBroadcast();
sendStickyBroadcast();
接收:
当Intent发送之后,所有已经注册vedBroadcastReceiver会检查注册时的IntentFilter是否与发送的Intent相匹配,若匹配则就会调用BroadcastReceiver的onReceiver()方法。所以当我们定义一个BroadcastReceiver的时候,都需要实现onReceiver()方法。
注意:
BroadcastReceiver需要注册
静态注册
代码动态注册

6、注意!
BroadReceiver生命周期只有十秒左右,不能直接执行耗时操作,不然会出现ANR(应用程序无响应),也不能用子线程来做,因为每次广播来的时候都会创建一个Reveiver对象,并且调用onReceiver,执行完之后 ,对象会立刻被销毁,子线程也没了
要做耗时操作的话,应该通过发送Intent给Service,由Service来完成。
动态注册广播接受者的话要在Destory回调事件进行unregister

7、广播的分类
普通广播 (Normal broadcast)
- 所有监听该广播接受者都可以监听到该广播
- 同级别接收先后顺序是随机的(无序)
- 级别低的后收到广播
- 接收器不能截断广播的继续传播,也不能处理广播
- 同级别动态注册高于静态注册

有序广播 (Oredered broadcast)
- 按照接收者的优先顺序来接收广播,优先级别在intent-filter中的priority中声明,-1000到1000之间,值越大优先级越高,可以终止广播的继续传播,接受者可以修改intent的内容。
- 同级别接收顺序是随机的
- 级别低的后收到
- 能截断广播的继续传播,高级别的广播接收器接收广播后能决定时候截断。
- 能处理广播
- 同级别动态注册高于静态注册

异步广播 (粘滞性滞留广播) ps:已被弃用
- 不能处理结果给下一个接收者,无法终止广播。
- 一直存在
- 可以先发送广播,再注册接收器
- 需要在清单文件添加android.permission.BROADCAST_STICKY权限





动态注册(在代码中注册广播接收器)

registerReceiver(networkChangeReceiver,intentFilter);

实例

MainActivity.class:

public class MainActivity extends AppCompatActivity {

    private IntentFilter intentFilter;
    private NetworkChangeReceiver networkChangeReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intentFilter = new IntentFilter();
        //当网络发生变化时,系统发出的值就是 android.net.conn.CONNECTIVITY_CHANGE,也就是说我们的
        //广播接收器想要监听什么广播
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        //实例化一个广播接收器
        networkChangeReceiver = new NetworkChangeReceiver();
        //注册广播  第一个参数是我们要处理广播的广播接收器,第二个参数是意图过滤器
        registerReceiver(networkChangeReceiver,intentFilter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消注册
        unregisterReceiver(networkChangeReceiver);
    }

    //一个广播接收器
    class NetworkChangeReceiver extends BroadcastReceiver{

        //每当网络状态发生变化时,onReceive()方法就会得到执行
        @Override
        public void onReceive(Context context, Intent intent) {
            //网络连接服务类
            ConnectivityManager connectivityManager = (ConnectivityManager)
                    getSystemService(Context.CONNECTIVITY_SERVICE);
            //获得网络连接实例
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            if(networkInfo!=null&&networkInfo.isAvailable()){
                Toast.makeText(context,"network is available",Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(context,"network is unavailable",Toast.LENGTH_SHORT).show();
            }
        }
    }
}

这里写图片描述





静态注册(在AndroidManifest.xml中注册广播接受器)

<receiver
    android:name=".MyBroadcastReceiver"
    android:enabled="true"
    android:exported="true">
        <intent-filter android:priority="1000">
            <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
        </intent-filter>
</receiver>

enabled:表示是否启用这个播放器
exported:用于指示该服务是否能够被其他应用程序组件调用或跟它交互。

实例

MainActivity.class:

public class MainActivity extends AppCompatActivity {

    public static TextView textMessage;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textMessage = (TextView) findViewById(R.id.message);
    }
}

MyBroadcastReceiver.class:

public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        Toast.makeText(context,"收到一条短信",Toast.LENGTH_SHORT).show();
        StringBuilder builder = new StringBuilder();
        //pdus是一个object类型的数组,每一个object都是一个byte[]字节数组,每一项为一条短信。
        Object[] pduses= (Object[])intent.getExtras().get("pdus");
        for(Object pdus: pduses){
            byte[] pdusmessage = (byte[])pdus;
            SmsMessage sms = SmsMessage.createFromPdu(pdusmessage);
            String mobile = sms.getOriginatingAddress();//发送短信的手机号码
            String content = sms.getMessageBody(); //短信内容
            Date date = new Date(sms.getTimestampMillis());
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = format.format(date);  //得到发送时间
            builder.append("号码: "+mobile+"\n内容: "+content+"\n时间: "+time+"\n");
        }
        MainActivity.textMessage.setText(builder.toString());
    }
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ukulele.broadcasttest">

    <uses-permission android:name="android.permission.RECEIVE_SMS" /><!--接收短信权限-->

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>

这里写图片描述





Normal Broadcast 普通广播

 sendBroadcast(intent);//发送广播

实例:

MainActivity.class:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.seond_broadcast);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent("com.example.broadcasttest.My_NORMAL_BROADCAST");
                intent.putExtra("msg","普通广播");
                sendBroadcast(intent);
            }
        });
    }
}

MyNormalBroadcast.class:

public class MyNormalBroadcast extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
         Log.d("MyNormalBroadcast ",intent.getStringExtra("msg"));
    }
}

AndroidManifest.xml:

<receiver
            android:name=".MyNormalBroadcast"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.broadcasttest.My_NORMAL_BROADCAST"/>
            </intent-filter>
        </receiver>

intent-filter android:priority=”1000” 普通广播也可设置先后顺序

logcat:

MyNormalBroadcast : 普通广播




Oredered Broadcast 有序广播

sendOrderedBroadcast(intent, null);//发送广播

有序广播实例:

MainActivity.class:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.seond_broadcast);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent("com.example.broadcasttest.My_OREDERED_BROADCAST");
                intent.putExtra("name","总统");
                intent.putExtra("content","快去把事情办了");
                sendOrderedBroadcast(intent,null);
            }
        });
    }
}

MyOrederedBroadcast3.class:

public class MyOrederedBroadcast3 extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        String name = intent.getStringExtra("name");
        String content = intent.getStringExtra("content");
        Log.d("MyOrederedBroadcast3","省长收到了"+name+"发过来的消息,消息内容是"+content);
        Bundle bundle = new Bundle();
        bundle.putString("name","省长");
        bundle.putString("content","快去把事情办了");
        setResultExtras(bundle);
        //abortBroadcast(); 截断广播

    }
}

MyOrederedBroadcast2.class:

public class MyOrederedBroadcast2 extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        //true代表如果前面的接收器没有存放数据,则自动创建一个空的Bundle对象,false则表示如果前面的接收器如果没有存放任何数据则返回null。
        Bundle bundle = getResultExtras(true);
        String name = bundle.getString("name");
        String content = bundle.getString("content");
        Log.d("MyOrederedBroadcast2","市长收到了"+name+"发来的消息,消息内容是"+content);
        bundle.putString("name","市长");
        bundle.putString("content","快去把事情办了");
        setResultExtras(bundle);
        //abortBroadcast(); 截断广播
    }
}

MyOrederedBroadcast.class:

public class MyOrederedBroadcast extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = getResultExtras(true);
        String name = bundle.getString("name");
        String content = bundle.getString("content");
        Log.d("MyOrederedBroadcast","县长收到了"+name+"发来的消息,消息内容是"+content+
        "。县长说:“好的市长,我这就去办”。");

    }
}

AndroidManifest.xml:

 <receiver
            android:name=".MyOrederedBroadcast"
            android:enabled="true"
            android:exported="true" >
            <intent-filter android:priority="100">
                <action android:name="com.example.broadcasttest.My_OREDERED_BROADCAST"/>
            </intent-filter>
        </receiver>

        <receiver
            android:name=".MyOrederedBroadcast2"
            android:enabled="true"
            android:exported="true" >
            <intent-filter android:priority="200">
                <action android:name="com.example.broadcasttest.My_OREDERED_BROADCAST"/>
            </intent-filter>
        </receiver>

        <receiver
            android:name=".MyOrederedBroadcast3"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="300">
                <action android:name="com.example.broadcasttest.My_OREDERED_BROADCAST"/>
            </intent-filter>
        </receiver>

        <!--优先级的设定 MyReceiver3大于MyReceiver2,MyReceiver2大于MyReceiver,优先级的范围-1000~1000 -->

logcat:

MyOrederedBroadcast3: 省长收到了总统发过来的消息,消息内容是快去把事情办了
MyOrederedBroadcast2: 市长收到了省长发来的消息,消息内容是快去把事情办了
MyOrederedBroadcast: 县长收到了市长发来的消息,消息内容是快去把事情办了。县长说:“好的市长,我这就去办”。




Sticky Broadcast粘性广播

实例

MainActivity.class:

public class MainActivity extends AppCompatActivity {

    private MyStickyBroadcast myStickyBroadcast;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button) findViewById(R.id.seond_broadcast);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent("com.example.broadcasttest.My_STICKY_BROADCAST");
                intent.putExtra("msg","粘性广播");
                //先发送
                sendStickyBroadcast(intent);

                //后注册
                IntentFilter intentFilter = new IntentFilter("com.example.broadcasttest.My_STICKY_BROADCAST");
                myStickyBroadcast = new MyStickyBroadcast();
                registerReceiver(myStickyBroadcast,intentFilter);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //取消注册
        unregisterReceiver(myStickyBroadcast);
    }

    class MyStickyBroadcast extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("MyStickyBroadcast",intent.getStringExtra("msg"));
        }
    }
}

logcat:

MyStickyBroadcast: 粘性广播

AndroidManifest.xml:

    <!--异步广播必须添加一条权限-->
    <uses-permission android:name="android.permission.BROADCAST_STICKY"/>




本地广播
前面我们发出的全局广播可以被其他应用程序接收到,同样我们也可以接受来自于其他应用程序的广播。这样就容易引起安全问题,比如我们发出的关键性数据可能被其他应用程序截获,或者接收到其他应用程序向我们发送的各种垃圾广播。
为了解决广播的安全问题,Android引用了一套本地广播机制,使用这套机制发出的广播只能够在应用程序的内部进行传递。

实例

MainActivity.class:

public class MainActivity extends AppCompatActivity {

    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //本地广播管理器
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        IntentFilter intentFilter = new IntentFilter("com.example.broadcasttest.My_LOCAL_RECEIVER");
        localReceiver = new LocalReceiver();
        //使用本地广播管理器对广播接收器进行注册
        localBroadcastManager.registerReceiver(localReceiver,intentFilter);
        Button button = (Button) findViewById(R.id.seond_broadcast);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent("com.example.broadcasttest.My_LOCAL_RECEIVER");
                intent.putExtra("msg","本地广播");
                localBroadcastManager.sendBroadcast(intent);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }

    //本地广播接收器
    class LocalReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("LocalReceiver",intent.getStringExtra("msg"));
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值