Broadcast:
广播机制 分两种:
标准广播(Normal broadcasts)
是一种完全异步执行的广播,在广播发出后,所有广播接收器几乎在同一时刻接收到
因此没有先后顺序可言
有序广播(Ordered broadcast)
同步执行的广播,在广播发出后,在同一时刻只有一个广播接收器能收到这条广播
层层传递,也就是层层可以拦截并作其他处理
注册广播:
代码中注册成为动态注册
AndroidManifest.xml下注册成为静态注册
//动态注册:
public class MainActivity extends Activity {
//广播的动态注册,即代码注册
private IntentFilter intentFilter;
private NetworkChangeReciver networkChangeReciver;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//广播对象
intentFilter = new IntentFilter();
//广播监听的对象
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
//广播接收
networkChangeReciver = new NetworkChangeReciver();
//广播注册
registerReceiver(networkChangeReciver, intentFilter);
}
//内部类----广播接收器
class NetworkChangeReciver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show();
//监听网络是否可用
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 Inavailable", Toast.LENGTH_SHORT).show();
}
}
}
}
//动态注册的广播在最后一定要unregisterReceiver(networkChangeReciver);
@Override
protected void onDestroy(){
super.onDestroy();
unregisterReceiver(networkChangeReciver);
}
//最后别忘记添加相应的权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
静态注册(AndroidManifest.xml)
案例:静态注册开机启动
同样,必须新建一个广播接收器的class
public class BootCompleteReciver extends BroadcastReceiver {
//在AndroidManifest静态注册后,在这里重写onReceive就Ok,实现你的操作
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show();
}
}
//在AndroidManifest.xml文件中:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- 这里添加了一个接收器,并在接收器加上了一个Action,这里实现的功能就是开机启动 -->
<receiver
android:name=".BootCompleteReciver">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
//权限:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
以上的两种接收器实现了接收系统的广播,广播都是由系统直接发出的。那么如何创建自定义的广播呢
自定义发送广播:
/*发送标准的广播:
案例:这里我们通过按钮的点击事件来发送一条广播,采用静态注册的方法*/
//创建一个广播接收器
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "received in MyBroadcastReceiver",
Toast.LENGTH_SHORT).show();
//拦截广播
//abortBroadcast();
}
}
//然后在AndroidManifest.xml文件下:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- 表示接收的是一个action为MY_BROADCAST的广播 -->
<receiver android:name=".MyBroadcastReceiver">
<!-- 设置为100,确保先接收广播 -->
<intent-filter android:priority="100">
<action android:name="com.baozhong.sendbroadcast.MY_BROADCAST"/>
</intent-filter>
</receiver>
</application>
//只要两个程序所接收的广播是一样的,那么这两个应用程序几乎同时接收到了这个广播,点击其中一个
//会接收到两条信息
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activtiy);
//以下为发送广播
//button为发送点
//注意Intent传递的内容要和action里面的一致,这样才能成为一个对应得广播
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent("com.baozhong.sendbroadcast.MY_BROADCAST");
sendBroadcast(intent);
//sendOrderedBroadcast(intent,null);
}
});
}
}
同:点击发送的com.baozhong.sendbroadcast.MY_BROADCAST和接收器中的
<action android:name="com.baozhong.sendbroadcast.MY_BROADCAST"/>
相同,才能接收
/*再新建一个SendBroadcast2
和原先的一样
在没有拦截的情况下,一条广播可以被两个程序接收,回应两次*/
//发送有序的广播:
/*在原先的项目的MainActivity中加入一条语句sendOrderedBroadcast(intent,null);
,然后再对应得广播接收器MyBroadcast加入拦截abortBroadcast();
可以查看到其效果
*/
/*以上的广播属于系统的全局广播,即发送的广播可以被其他应用程序接收到
那么就可能会引起安全性的问题,那么如何进一步解决这个问题?
使用本地广播来实现:
本地广播多了一个LocalBroadcastManager 用于获取实例 发送广播 注册接收器的监听的一整套的广播机制,所以比较安全*/
//本地广播无法通过静态来注册,只能通过代码注册
//这个为本地广播
//关键是加了private LocalBroadcastManager localBroadcastManager;
//本地广播用来管理本地注册
/*注意:本地广播无法通过静态注册的方式接收
* 因为静态注册主要是为了在未启动的情况下也能接收到广播
* 而发送本地广播时,我们的程序已经启动了
* 因此不需要静态注册功能
* 所以本地广播比较安全,之前做的都是全局广播
*
* */
public class MainActivity extends Activity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//获取本地广播管理实例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
Button button =(Button)findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent("com.baozhong.localbroadcastmanager."
+ "LOCAL_BROADCAST");
//发送本地广播
localBroadcastManager.sendBroadcast(intent);
}
});
intentFilter = new IntentFilter();//获取传送广播对象
//加载广播
intentFilter.addAction("com.baozhong.localbroadcastmanager.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
//注册本地广播监听器
localBroadcastManager.registerReceiver(localReceiver, intentFilter);
}
class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "receive in Local broadcast", Toast.LENGTH_SHORT).show();
}
}
}
/*广播的最佳实践:OffLine实现强制下线的功能
如何实现强制下线:关闭所有的活动,并回到登录界面
一开始为LoginActivity,如果登录成功,就进入发送点击强制下线的广播的界面MainActivity,点击发送广播之后,
就弹出一个警告的对话框,点击Ok后就回到登陆界面LoginActivity*/
//将LoginActivity作为一开始的启动界面
//警告的对话框接收器:AlertDialog.Builder构建一个对话框
public class ForceOfflineReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
// TODO Auto-generated method stub
//注意一个final Context context
//AlertDialog.Builder构建一个对话框
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle("warning");
dialogBuilder.setMessage("You are forced to be offline.Please try"
+ " to login again");
dialogBuilder.setCancelable(false);//设置为不能按返回键取消
//点击Ok,然后活动重新跳到登录界面
dialogBuilder.setPositiveButton("OK", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
//销毁所有的活动
ActivityCollector.finishAll();
Intent intent = new Intent(context,LoginActivity.class);
//一定要加入这个标志FLAG_ACTIVITY_NEW_TASK
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
//设置一下AlertDialog的类型,保证在广播接收器中对话框可以正常弹出
AlertDialog alertDialog = dialogBuilder.create();
alertDialog.getWindow().
setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
}
}