您的位置:首页 > 其它

broadcast receiver广播接收器

2015-11-19 09:43 190 查看
注册广播有2种方式

1.代码注册(动态注册)

2.在AndroidManifest.xml注册(静态注册)

动态注册

MainActivity.java

public class MainActivity extends Activity {
NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

IntentFilter intentFilter =new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");//网络状态发生变化的广播
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver, intentFilter);//注册
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);//解除注册
}
public class NetworkChangeReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent arg1) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo =connectivityManager.getActiveNetworkInfo();
if(networkInfo!=null&&networkInfo.isAvailable()){
Toast.makeText(context, "network is available", Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(context, "network is unavailable", Toast.LENGTH_LONG).show();
}
}
}


查询网络连接的状态必须要在AndroidManifest.xml中注册

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>


当网络连接状态发生改变的时候





静态注册

新建一个BootCompleteReceiver.java

package com.example.broadcastReceiver;

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

public class BootCompleteReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent arg1) {
Toast.makeText(context,"BootComplete", Toast.LENGTH_LONG).show();
}

}


AndroidManifest.xml

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED">
<!--接收开机启动广播的权限-->
</uses-permission>
<application>
<receiver         android:name="com.example.broadcastReceiver.BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<!--开机启动的广播-->
</intent-filter>
</receiver>
</application>


效果:



自定义发送广播

使用静态的方式先注册广播

<receiver
android:name="com.example.broadcastReceiver.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.MyBroadcastReceiver"/>
</intent-filter>
</receiver>


MyBroadcastReceiver.java(广播接收器类)

package com.example.broadcastReceiver;

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 arg1) {
Toast.makeText(context,"mybroadcastReceiver", Toast.LENGTH_SHORT).show();
}

}


在MainActivity发送广播

Button btn_sent =(Button) this.findViewById(R.id.sendBroadcast);
btn_sent.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent  = new Intent("android.intent.action.MyBroadcastReceiver");
sendBroadcast(intent);
}
});


效果



广播可以用于应用程序之间的通信。

在另一个app内也静态的注册一个广播接收器,接收的广播为第一个app发送的广播。

有序广播

在原来

Intent intent  = new Intent("android.intent.action.MyBroadcastReceiver");
sendBroadcast(intent);


改为

sendOrderedBroadcast(intent, null);


当广播为有序广播时,要为广播接收器设定优先级

android:priority=”100”

<receiver
android:name="com.example.broadcastReceiver.MyBroadcastReceiver">
<intent-filter android:priority="100">
<action android:name="android.intent.action.MyBroadcastReceiver"/>
</intent-filter>
</receiver>


有序广播可以被切断

当广播被此广播接收器接收后,广播被切断

public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent arg1) {
Toast.makeText(context,"mybroadcastReceiver", Toast.LENGTH_SHORT).show();
abortBroadcast();//切断广播
}

}


上方的广播属于全局广播,存在安全性问题,广播有可能被别的程序截获,别的程序也可以不断的向我们的程序发送垃圾广播,因此引入本地广播

本地广播

本地广播使用的是动态注册,因为既然是在app内传播,app当然已经启动了,所以不使用静态注册是可以理解的(不能静态注册)

MainActivity.java

LocalReceiver localReceiver;
LocalBroadcastManager localBroadcastManager;
{
localBroadcastManager =      LocalBroadcastManager.getInstance(this);//实例一个本地广播管理者

IntentFilter inteFilter = new IntentFilter();       inteFilter.addAction("android.intent.action.LoaclBroadcast");

localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver,inteFilter);//注册本地广播监听器

Button btn_sent =(Button) this.findViewById(R.id.sendBroadcast);
btn_sent.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent  = new Intent("android.intent.action.LoaclBroadcast");
localBroadcastManager.sendBroadcast(intent);
}
});
}

@Override
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);//解除注册
}

public class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent arg1) {
Toast.makeText(context, "localBroadcast", Toast.LENGTH_SHORT).show();
}

}


效果



在广播接受器弹出窗口

package com.example.broadcastReceiver;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.view.WindowManager;
import android.widget.Toast;

public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent arg1) {

AlertDialog.Builder ab =new AlertDialog.Builder(context);
ab.setTitle("hello world!");
ab.setCancelable(false);//不可以取消
ab.setMessage("ni hao!");
ab.setPositiveButton("ok",null);

AlertDialog alertDialog = ab.create();
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);//系统级别的弹出窗口
//是TYPE_SYSTEM_ALERT而不是TYPE_SYSTEM_DIALOG
alertDialog.show();
}
}


声明权限

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"></uses-permission>


效果



2015/12/27 更新

(讨论的是动态注册)

在活动创建的时候注册广播,在活动销毁的时候销毁广播。

即一个活动没有被创建就不会收到广播,之前发的广播不会在活动启动后接收到。

必须在活动存活的时候发送广播,活动才能接收到。

如果有多个活动同时接受一个广播,并且这些活动都是存活的,那么它们都可以接收到广播。接收的顺序按栈向上的顺序,即在底层的活动会先接收到。

项目中的使用广播的格式

定义一个Broadcast类,专门为APP注册和销毁广播

package com.example.broadcast;

import com.example.testbroadcast1227.MyApp;

import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;

public class MyBroadcast {

public static String BROADCAST = "broadCast";
public static String BROADCAST2 = "broadCast2";

/**
* 注册广播接收者
*/
public static void registerBroadcastReceiver(String action,BroadcastReceiver receiver) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(action);
MyApp.getContext().registerReceiver(receiver, intentFilter);
//这里的MyApp.getContext()返回的是 继承Application类的context
}

public static void registerBroadcastReceiver(String [] actions,BroadcastReceiver receiver) {
IntentFilter intentFilter = new IntentFilter();
for (String action : actions) {
intentFilter.addAction(action);
}
MyApp.getContext().registerReceiver(receiver, intentFilter);
}

/**
* 销毁广播接收者
*/
public static void unregisterBroadcastReceiver(BroadcastReceiver receiver) {
MyApp.getContext().unregisterReceiver(receiver);
}

/**
* 发广播
*/
public static void sendBroadcastAction(String action){
sendBroadcastAction(action, null);
}

public static void sendBroadcastAction(String action,Bundle bundle){
Intent intent = new Intent(action);
if (bundle != null) {
intent.putExtras(bundle);
}
MyApp.getContext().sendBroadcast(intent);
}

}


在具体的活动中用法:

MainActivity.java

package com.example.testbroadcast1227;

import com.example.broadcast.MyBroadcast;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener{

private BroadcastReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

registerBroadcast();

Button bt = (Button) findViewById(R.id.bt_sendBroadcast);
bt.setOnClickListener(this);
Button bt2 = (Button) findViewById(R.id.bt_intoAct2);
bt2.setOnClickListener(this);
}

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

private void registerBroadcast() {
if (receiver == null) {
receiver = new BroadcastReceiver(){

@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MyBroadcast.BROADCAST)) {
Log.v("TAG", "1:broadcast");
}
else if (intent.getAction().equals(MyBroadcast.BROADCAST2)) {
Log.v("TAG", "1:broadcast2");
}
}};
}

MyBroadcast.registerBroadcastReceiver(new String[] {
MyBroadcast.BROADCAST,
MyBroadcast.BROADCAST2 }, receiver);
}

private void unregisterBroadcast() {
MyBroadcast.unregisterBroadcastReceiver(receiver);
}

@Override
public void onClick(View v) {

switch (v.getId()) {
case R.id.bt_sendBroadcast:
MyBroadcast.sendBroadcastAction(MyBroadcast.BROADCAST);
break;

case R.id.bt_intoAct2:
//跳转
Act2.show(this);
break;
}

}

}


Act2.java

package com.example.testbroadcast1227;

import com.example.broadcast.MyBroadcast;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Act2 extends Activity implements OnClickListener{

BroadcastReceiver receiver;

public static void show(Context context) {
Intent intent = new Intent(context,Act2.class);
context.startActivity(intent);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act2);
registerBroadcast();
Button bt2 = (Button) findViewById(R.id.bt_sendBroadcast2);
bt2.setOnClickListener(this);
Button bt1 = (Button) findViewById(R.id.bt_sendBroadcast1);
bt1.setOnClickListener(this);

}

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

private void registerBroadcast() {
if (receiver == null) {
receiver = new BroadcastReceiver(){

@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MyBroadcast.BROADCAST)) {
Log.v("TAG", "2:broadcast");
}
else if (intent.getAction().equals(MyBroadcast.BROADCAST2)) {
Log.v("TAG", "2:broadcast2");
}
}};
}

MyBroadcast.registerBroadcastReceiver(new String[] {
MyBroadcast.BROADCAST,
MyBroadcast.BROADCAST2 }, receiver);
}

private void unregisterBroadcast() {
MyBroadcast.unregisterBroadcastReceiver(receiver);
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_sendBroadcast2:
MyBroadcast.sendBroadcastAction(MyBroadcast.BROADCAST2);
break;

case R.id.bt_sendBroadcast1:
MyBroadcast.sendBroadcastAction(MyBroadcast.BROADCAST);
break;
}
}

}


在MainActvity点击按钮发送广播:



只有MainActivity能接到广播

在Act2的2个按钮分别发送广播:



可以看到2个活动都收到广播,并且是MainActivity先收到,Act2后收到

2016/01/27更新

1.开机广播

<action android:name="android.intent.action.BOOT_COMPLETED"/>


在4.42 (T1),4.4.4(小米平板1) 测试均无法接收

2.app如果被杀死(Back键退出不算),将无法接收到广播

2016/3/25 更新

广播接收器注册一共有两种形式 : 静态注册和动态注册.

两者及其接收广播的区别:

1.动态注册的广播 永远要快于 静态注册的广播,不管静态注册的优先级设置的多高,不管动态注册的优先级有多低>\

2.动态注册广播不是 常驻型广播 ,也就是说广播跟随activity的生命周期。注意: 在activity结束前,移除广播接收器。

静态注册是常驻型 ,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。

3.在同一个优先级下,谁先启动的快,谁将先接收到广播.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: