android 的广播

简介

安卓的广播机制是一套十分灵活的消息/信号发送(send)/接收(receive)机制,系统或者应用发出的广播(消息)可以覆盖几乎整个Android,因此广播机制是跨应用的,全局的。

自定义个广播接收器(custom BroadcastReceiver)

广播接收器的实质是一个监听器(接收到广播时执行相应的动作),创建该监听器只需创建一个继承自BroadcastReceiver的类,并重写(override)其中的onReceive方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.notice.agno3.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//TODO:write what you want to do when receive a broadcast,such as a toast:
Toast.makeText(context,"network changed" ,Toast.LENGTH_SHORT ).show();
}
}

这样就写好了自定义的receiver ,方法体里面写在收到广播的时候要干的事情。

使用自定义的广播接收器(use your customized BroadcastReceiver)

要有广播才能使用广播接收器,目前先使用系统自带的广播(后面有自定义广播),例如:在手机的网络情况发生变化时系统会发一条值为android.net.conn.CONNECTIVITY_CHANGE的广播。
使用接收器的过程可以称为注册,注册分为动态注册静态注册两种。

动态注册

首先利用IntentFilter(意图筛选器)把值为android.net.conn.CONNECTIVITY_CHANGE的广播筛选出来;然后利用registerReceiver方法进行注册;最后不要忘记在onDestroy()方法中取消注册:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//MainActivity.java
package com.notice.agno3.receiver;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

private IntentFilter intentFilter;
private MyReceiver myReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intentFilter = new IntentFilter();
//set the filter
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
//register the broadcast
myReceiver = new MyReceiver();
registerReceiver(myReceiver, intentFilter);
}

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

这样在运行app的时候,只要改变网络状态,app就会弹出一条toast显示“network changed”.但如果想在不运行这个app的时候也能进行监听,这就要靠静态注册了。

静态注册

静态注册的思路和动态注册思路一样,只不过不在java代码中写,而是在AndroidManifest.xml进行注册,在<application><application/>内加入:

1
2
3
4
5
6
7
8
9
<receiver android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action
android:name="android.net.conn.CONNECTIVITY_CHANGE"
tools:ignore="BatteryLife" />
</intent-filter>
</receiver>

主要看<intent-filter>标签,同样起到了过滤效果。

自定义广播

自定义广播通过Intent进行发送,应该还是好理解的:

1
2
Intent intent = new Intent("com.agno3.MY_BROADCAST");
sendBroadcast(intent);

把它放在button的监听事件中(或其他触发方式),点击按钮就能发送自定义的广播了,同样可以用自定义的接收器进行接收:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//custom receiver
package com.notice.agno3.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//TODO:write what you want to do when receive a broadcast
Toast.makeText(context,"button is clicked it has sent a broad cast" ,Toast.LENGTH_SHORT ).show();
}
}

然后是MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//MainActivity.java
package com.notice.agno3.receiver;

import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

private IntentFilter intentFilter;
private MyReceiver myReceiver;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//button
button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//send receiver
Intent intent = new Intent("com.agno3.MY_RECEIVER");
sendBroadcast(intent);
}
});
//set the filter
intentFilter = new IntentFilter();
intentFilter.addAction("com.agno3.MY_RECEIVER");
myReceiver = new MyReceiver();
//register
registerReceiver(myReceiver, intentFilter);
}

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

点击屏幕上按钮就会有toast:”button is clicked it has sent a broad cast”这样就完成了一次send + receive 的完整操作。注意这里的广播其他应用也是可以接收的,要发送其他应用无法接收的需要本底广播,详见下篇。