Broadcast Receiver广播接收器,android的四大组件Activity, Service,Broadcast Receiver, Content Provider之一。它是个接收器,如果哪个android应用对外发出广播了,它就可以收听到了,收听到就可以作相关处理,这个打个比方,比如电视台或者广播台发出广播,明天要下雨了,然后老百姓第二天就会带雨伞雨衣来处理这个事件了。所以说广播接收器的作用就是帮助各个应用之间传输信息。比如电池的使用状态,电话的接收和短信的接收都会产生一个广播,应用程序开发者也可以监听这些广播并做出程序逻辑的处理。
如何发出广播?
要接收广播,那自然需要发出广播了,我们可以在某个activity里面发出我们的广播,有以下发送广播的方法:
1、 public abstract void sendBroadcast (Intent intent) //发给所有的接收器
2、 public abstract void sendBroadcast (Intent intent, String receiverPermission) //发给收听了receiverPermission的接收器
3、 public abstract void sendOrderedBroadcast (Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)//发布有序广播,接收器优先级高的先接收,同时也可以把更改的结果传递给下一个接收器
4、 public abstract void sendOrderedBroadcast (Intent intent, String receiverPermission) //发布有序广播,接收器优先级高的先接收,同时也可以把更改的结果传递给下一个接收器
5、public abstract void sendStickyBroadcast (Intent intent) //
sendStickyBroadcast发出的最后一个Intent会被保留,下次当Recevier处于活跃的时候,又会接受到它,sendBroadcast则不会
6、 public abstract void sendStickyOrderedBroadcast (Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)
如何接收广播?
在BroadcastReceiver 的onReceive(Context, Intent)方法里面接收广播,这个方法只有10秒钟,如果在这个方法里面的业务逻辑超过就会报超时的错误
那既然只给了10秒钟来处理,我们可以在10秒钟内处理好逻辑后,跳转到其他的Activity或者Service中去处理更复杂的逻辑。这里也不能使用子线程来解决,因为BroadcastReceiver的生命周期很短,子线程可能还没有结束,BroadcastReceiver就先结束了.BroadcastReceiver一旦结束,此时BroadcastReceiver的所在进程很容易在系统需要内存时被优先杀死,因为它属于空进程(没有任何活动组件的进程).如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死.所以采用子线程来解决是不可靠的。
如何注册我们的广播接收器?
有两种方法:
1、 statically publish an implementation through the <receiver> tag in your AndroidManifest.xml
比如:
<application android:icon="@drawable/icon" android:label="@string/app_name">
<receiver android:name=".MyBroadcastReceiver" android:priority="1000">
<intent-filter>
<action android:name="android.intent.action.BroadcastReceiver"></action>
</intent-filter>
</receiver>
</application>
android:priority="1000"是优先级范围,只适用于sendOrderedBroadcast有序广播
该广播的级别有级别之分,级别数值是在-1000到1000之间,值越大,优先级越高;
同级别接收是先后是随机的,再到级别低的收到广播;
同级别接收是先后是随机的,如果先接收到的把广播截断了,同级别的例外的接收者是无法收到该广播的。(abortBroadcast())
能截断广播的继续传播,高级别的广播收到该广播后,可以决定把该广播是否截断掉。
实验现象,在这个方法发来的广播中,代码注册方式中,收到广播先后次序为:注明优先级的、代码注册的、没有优先级的;如果都没有优先级,代码注册收到为最先。
2、 You can either dynamically register an instance of this class with Context.registerReceiver()
我们可以在一个activity里面注册或者取消广播接收器,推荐在onPause注销,onResume里面注册
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
// 代码里取消广播接收器
unregisterReceiver(myBroadcastReceiver);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
// // 在代码里面注册广播接收器
myBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();
// // //向过滤器中添加action
filter.addAction("android.intent.action.BroadcastReceiver");
// // 注册广播
registerReceiver(myBroadcastReceiver, filter);
}
说了那么多,开始我们的实践,这里我写了一个范例,场景是:一个应用发出了一句广播:生日快乐,然后另外一个应用的一个接收器就可以捕获到这个广播。
第一步、设计一个发送广播的页面res/layout/broadcastreceiver.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android=" http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:id="@+id/btnSendBc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="52dp" android:text="@string/sendbroadcast"></Button>
</RelativeLayout>
第二步、设计广播发出activity BroadcastReceiverActivity.java
/**
*
*/
package Test.HelloWorld;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* @author zhuzhifei
*
*/
public class BroadcastReceiverActivity extends Activity {
private Button btnSendBroadCast;
MyBroadcastReceiver myBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.broadcastreceiver);
btnSendBroadCast = (Button) findViewById(R.id.btnSendBc);
btnSendBroadCast.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putCharSequence("test", "生日快乐!");
intent.putExtras(bundle);
intent.setAction("android.intent.action.BroadcastReceiver");
// 发送广播
sendBroadcast(intent);
// //发布有序广播
// sendOrderedBroadcast(intent,"");
}
});
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
// 代码里取消广播接收器
// unregisterReceiver(myBroadcastReceiver);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
// // 在代码里面注册广播接收器
// myBroadcastReceiver = new MyBroadcastReceiver();
// IntentFilter filter = new IntentFilter();
// // //向过滤器中添加action
// filter.addAction("android.intent.action.BroadcastReceiver");
// // 注册广播
// registerReceiver(myBroadcastReceiver, filter);
}
}
第三步、设计广播接收器MyBroadcastReceiver.java
/**
*
*/
package Test.HelloWorld;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
/**
* @author zhuzhifei
*
*/
public class MyBroadcastReceiver extends BroadcastReceiver {
/* (non-Javadoc)
* @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
*/
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
Bundle bundle=arg1.getExtras();
//处理超过10秒将会报错,大家可以尝试一下
// Long lo=new Long("11000");
// try {
// Thread.sleep(lo);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//把接收到的广播,打日志
Log.i("test", "我接收到信息:"+bundle.get("test"));
}
@Override
public IBinder peekService(Context myContext, Intent service) {
// TODO Auto-generated method stub
return super.peekService(myContext, service);
}
}
第四步、AndroidManifest.xml注册我们的广播接收器
<receiver android:name=".MyBroadcastReceiver" android:priority="1000">
<intent-filter>
<action android:name="android.intent.action.BroadcastReceiver"></action>
</intent-filter>
</receiver>
第五步、运行效果
如何发出广播?
要接收广播,那自然需要发出广播了,我们可以在某个activity里面发出我们的广播,有以下发送广播的方法:
1、 public abstract void sendBroadcast (Intent intent) //发给所有的接收器
2、 public abstract void sendBroadcast (Intent intent, String receiverPermission) //发给收听了receiverPermission的接收器
3、 public abstract void sendOrderedBroadcast (Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)//发布有序广播,接收器优先级高的先接收,同时也可以把更改的结果传递给下一个接收器
4、 public abstract void sendOrderedBroadcast (Intent intent, String receiverPermission) //发布有序广播,接收器优先级高的先接收,同时也可以把更改的结果传递给下一个接收器
5、public abstract void sendStickyBroadcast (Intent intent) //
sendStickyBroadcast发出的最后一个Intent会被保留,下次当Recevier处于活跃的时候,又会接受到它,sendBroadcast则不会
6、 public abstract void sendStickyOrderedBroadcast (Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)
如何接收广播?
在BroadcastReceiver 的onReceive(Context, Intent)方法里面接收广播,这个方法只有10秒钟,如果在这个方法里面的业务逻辑超过就会报超时的错误
那既然只给了10秒钟来处理,我们可以在10秒钟内处理好逻辑后,跳转到其他的Activity或者Service中去处理更复杂的逻辑。这里也不能使用子线程来解决,因为BroadcastReceiver的生命周期很短,子线程可能还没有结束,BroadcastReceiver就先结束了.BroadcastReceiver一旦结束,此时BroadcastReceiver的所在进程很容易在系统需要内存时被优先杀死,因为它属于空进程(没有任何活动组件的进程).如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死.所以采用子线程来解决是不可靠的。
如何注册我们的广播接收器?
有两种方法:
1、 statically publish an implementation through the <receiver> tag in your AndroidManifest.xml
比如:
<application android:icon="@drawable/icon" android:label="@string/app_name">
<receiver android:name=".MyBroadcastReceiver" android:priority="1000">
<intent-filter>
<action android:name="android.intent.action.BroadcastReceiver"></action>
</intent-filter>
</receiver>
</application>
android:priority="1000"是优先级范围,只适用于sendOrderedBroadcast有序广播
该广播的级别有级别之分,级别数值是在-1000到1000之间,值越大,优先级越高;
同级别接收是先后是随机的,再到级别低的收到广播;
同级别接收是先后是随机的,如果先接收到的把广播截断了,同级别的例外的接收者是无法收到该广播的。(abortBroadcast())
能截断广播的继续传播,高级别的广播收到该广播后,可以决定把该广播是否截断掉。
实验现象,在这个方法发来的广播中,代码注册方式中,收到广播先后次序为:注明优先级的、代码注册的、没有优先级的;如果都没有优先级,代码注册收到为最先。
2、 You can either dynamically register an instance of this class with Context.registerReceiver()
我们可以在一个activity里面注册或者取消广播接收器,推荐在onPause注销,onResume里面注册
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
// 代码里取消广播接收器
unregisterReceiver(myBroadcastReceiver);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
// // 在代码里面注册广播接收器
myBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter();
// // //向过滤器中添加action
filter.addAction("android.intent.action.BroadcastReceiver");
// // 注册广播
registerReceiver(myBroadcastReceiver, filter);
}
说了那么多,开始我们的实践,这里我写了一个范例,场景是:一个应用发出了一句广播:生日快乐,然后另外一个应用的一个接收器就可以捕获到这个广播。
第一步、设计一个发送广播的页面res/layout/broadcastreceiver.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android=" http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:id="@+id/btnSendBc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="52dp" android:text="@string/sendbroadcast"></Button>
</RelativeLayout>
第二步、设计广播发出activity BroadcastReceiverActivity.java
/**
*
*/
package Test.HelloWorld;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
* @author zhuzhifei
*
*/
public class BroadcastReceiverActivity extends Activity {
private Button btnSendBroadCast;
MyBroadcastReceiver myBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.broadcastreceiver);
btnSendBroadCast = (Button) findViewById(R.id.btnSendBc);
btnSendBroadCast.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putCharSequence("test", "生日快乐!");
intent.putExtras(bundle);
intent.setAction("android.intent.action.BroadcastReceiver");
// 发送广播
sendBroadcast(intent);
// //发布有序广播
// sendOrderedBroadcast(intent,"");
}
});
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
// 代码里取消广播接收器
// unregisterReceiver(myBroadcastReceiver);
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
// // 在代码里面注册广播接收器
// myBroadcastReceiver = new MyBroadcastReceiver();
// IntentFilter filter = new IntentFilter();
// // //向过滤器中添加action
// filter.addAction("android.intent.action.BroadcastReceiver");
// // 注册广播
// registerReceiver(myBroadcastReceiver, filter);
}
}
第三步、设计广播接收器MyBroadcastReceiver.java
/**
*
*/
package Test.HelloWorld;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
/**
* @author zhuzhifei
*
*/
public class MyBroadcastReceiver extends BroadcastReceiver {
/* (non-Javadoc)
* @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
*/
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
Bundle bundle=arg1.getExtras();
//处理超过10秒将会报错,大家可以尝试一下
// Long lo=new Long("11000");
// try {
// Thread.sleep(lo);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//把接收到的广播,打日志
Log.i("test", "我接收到信息:"+bundle.get("test"));
}
@Override
public IBinder peekService(Context myContext, Intent service) {
// TODO Auto-generated method stub
return super.peekService(myContext, service);
}
}
第四步、AndroidManifest.xml注册我们的广播接收器
<receiver android:name=".MyBroadcastReceiver" android:priority="1000">
<intent-filter>
<action android:name="android.intent.action.BroadcastReceiver"></action>
</intent-filter>
</receiver>
第五步、运行效果