1. 广播机制简介
android中每个应用程序都可以对自己感兴趣的广播进行注册,这样程序只接受自己所关心的广播内容。
广播内容来自:①来自系统的;②来自其他应用程序的。
android提供一套完整的API,允许应用程序自由的发送和接收广播。
发送广播的方法:借助Intent;
接收广播的方法:使用广播接收器(Broadcast Receiver)。
广播类型:
标准广播(Normal broadcast)
有序广播(Ordered broadcast)
2. 接收系统广播
如果要接收这些广播,需要使用广播接收器。
android内置了很多系统级别的广播,应用程序通过监听这些广播来得到各种系统的状态信息。
(如手机开机完成后会发出一条广播,电池电量发生变化会发出一条广播,时间或时区发送变化也会发出一条广播。)
广播接收器,可以注册感兴趣的广播,当有相应的广播发出时,广播接收器就能收到该广播,并在内部处理相应的逻辑。
注册广播的方式有两种:
- 动态注册,即在代码中注册;
- 静态注册,即在AndroidManifest.xml中注册。
2.1 动态注册监听网络变化
创建一个广播接收器:新建一个继承自BroadcastReceiver的类(内部类),并重写父类的onReceive()方法,这样,当有广播到来时,onReceive()方法就得到执行(处理具体的逻辑)。
实例:
package com.example.liu.broadcasttest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
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();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");//广播
networkChangeReceiver=new NetworkChangeReceiver();//定义广播接收器
registerReceiver(networkChangeReceiver,intentFilter);//注册
}
@Override
protected void onDestroy(){
super.onDestroy();
unregisterReceiver(networkChangeReceiver); //注销
}
//内部类,继承自BroadcastReceiver类,并实现onReceive()方法
class NetworkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent){
//接收到广播后,需要处理的逻辑。
Toast.makeText(context,"network changes",Toast.LENGTH_SHORT).show();
}
}
}
动态注册的广播接收器,可以自由的控制注册与注销,灵活。
缺点:必须在程序启动之后才能接收到广播,因为注册的逻辑是写在onCreate()方法中。
静态注册方式,能让程序在未启动的情况下接收到广播,从而实现开机启动功能。
2.2 静态注册实现开机启动
让程序接收一条开机广播,当收到这条广播时就可以在onReceive()方法中执行相应的逻辑,从而实现开机启动功能。
1.外部类的方式定义广播接收器
public class BootCompleteReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent){
Toast.makeText(context,"Boot Complete",Toast.LENGTH_LONG).show();
}
}
2.在AndroidManifest.xml中,将这个广播接收器的类名注册进去。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.liu.bootcompletereceiver">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
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=".BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
</manifest>
<application>
标签内添加新的标签<receiver>
,所有静态注册的广播接收器都是在这里注册的。
监听系统开机广播,需要声明权限,即<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
3. 发送自定义广播
两种广播类型:标准广播,有序广播
3.1 发送标准广播
3.2 发送有序广播
4. 本地广播
系统全局广播:即发出的广播可以被其他人任何的应用程序接收到,并且也可以接受来自其他任何应用程序的广播。
本地广播:发出的广播只能够在应用程序内部进行传递,并且广播接收器也只能接受来自本应用程序发出的广播。
本地广播,主要使用LocalBroadcastManager来对广播进行管理,并提供发送广播和注册广播接收器的方法。
package com.example.liu.locatbroadcastmanagertest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter=null;
private LocalReceiver localReceiver=null;
private LocalBroadcastManager localBroadcastManager=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// TODO: 2016/11/15
localBroadcastManager=LocalBroadcastManager.getInstance(this);
Button button=(Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);//发送广播
}
});
intentFilter=new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver=new LocalReceiver();//定义广播接收器
localBroadcastManager.registerReceiver(localReceiver,intentFilter);//注册广播接收器
}
@Override
protected void onDestroy(){
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);//注销
}
//本地广播接收器
class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent){
Toast.makeText(context,"receive local broadcast",Toast.LENGTH_SHORT).show();
}
}
}
本地广播是无法通过静态注册的方式来接收的。
因为,静态注册主要是为了让程序在未启动的情况下也能接收到广播,而发送本地广播时,我们的程序肯定已经启动了,因此也完全不需要使用静态注册的功能。
本地广播优势:
- 发送的广播不会离开应用程序,因此,不需要担心机密数据泄露。
- 其他程序无法将广播发送到程序内部,因此,不需要担心有安全漏洞隐患。
- 发送本地广播比发送系统全局广播高效。