android 广播的使用

来源:互联网 发布:seo要学多久 编辑:程序博客网 时间:2024/06/05 06:38

      1.广播的简单介绍

             1.  android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样该应用程序就只会接受自己所关心的广播内容,这些广播可能来自于系统的,也可能来自于其他应用程序的.而接收广播的方法则需要广播接收器(Broadcast Receiver).

          2.接收系统广播 

           注册广播的方式有两种,一种是在代码中注册,另一种是在AndroidManifest,xml中注册.前者又称之为动态注册,后者又称之为静态注册.例如:  

   2.1 动态注册监听网络变化

                      新建一个类,让他继承自BroadcastReceiver,并重写父类中的onReceive()方法就可以了.这样当有广播的时候,onReceive()方法就会得到执行,具体的逻辑就可以在这里面去处理.

        MainActivity中代码如下:

public class MainActivity extends Activity {        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);      }      class NetWorkChangeReceiver extends BroadcastReceiver{            @Override          public void onReceive(Context context, Intent intent) {              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 unAvailable",Toast.LENGTH_SHORT).show();              }          }      }      @Override      protected void onDestroy() {          super.onDestroy();          unregisterReceiver(netWorkChangeReceiver);      }  }  
 intentfilter中添加的action是android.net.conn.CONNECTIVITY_CHANGE,因为当网络状态发生变化的时候,系统发出的刚好是值为android.net.conn.CONNECTIVITY_CHANGE的广播registerReceiver就是注册广播的方法.需要注意的是,动态注册的广播必须要取消注册才行,这里我们是在OnDestory方法中取消注册的。在onReceive()方法中的ConnectivityManager就是一个系统服务类,专门用于管理网络连接的,后面,如果有网络的话,就会弹出一个提示network is Available的提醒.对于监听网络状态,我们需要在Androidmanifest.xml文件中声明权限,

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

运行程序,效果如下.关闭手机wifi:


连接手机wifi:

 2.2 静态注册实现开机启动

                  动态注册广播的缺点就是必须要在程序启动之后才能接收到广播,而静态注册的广播则可以在程序未启动的情况下就能接收到广播.

新建一个BootCompleteReceiver,继承自BroadcastReceiver,代码如下:

<?xml version="1.0" encoding="utf-8"?>  <manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.example.administrator.broadcasttest">  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>      <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>      <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"></action>              </intent-filter>          </receiver>      </application>    </manifest>  

在receiver中,name就是我们写的Java中的完整类名,action就是系统启动完成的广播.程序运行一下程序.博主是用手机实测的,华为荣耀7i,系统版本是6.0.程序安装完成后,在权限管理里面对应用所申请的权限允许,如下.

之后关机,再开机(这个图非常不好截,截了 6次 才截到,2333),如下:

需要注意的是,在广播接收器的onReceiver()方法中不能进行长期的耗时逻辑,否则会出现ANR.

   3.发送自定义广播

        广播主要分为两种类型,标准广播和有序广播.

          3.1发送标准广播

           新建一个MyBroadcastReceiver类继承自BroadcastReceiver,这个类就是用来接收广播的.代码如下:

public class MyBroadcastReceiver extends BroadcastReceiver{      @Override      public void onReceive(Context context, Intent intent) {          Toast.makeText(context,"receiver in MyBroadcastReceiver",Toast.LENGTH_SHORT).show();      }  }  
代码很简单,就不说了,当MyBroadcastReceiver接收到广播时候,就会弹出receiver in MyBroadcastReceiver的提示.我们在AndroidManifest.xml中注册,如下:
<?xml version="1.0" encoding="utf-8"?>  <manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.example.administrator.broadcasttest">  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>      <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>      <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">          <receiver android:name=".MyBroadcastReceiver">              <intent-filter>                  <action android:name="com.dyk.broadcasttest.MyBroadcastReceiver"></action>              </intent-filter>          </receiver>      </application>    </manifest>  
 在activity_main.xml中代码添加一个按钮:

<?xml version="1.0" encoding="utf-8"?>  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"      android:id="@+id/activity_main"      android:layout_width="match_parent"      android:layout_height="match_parent">       <Button         android:id="@+id/button"         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:text="发送广播"/>  </RelativeLayout>  
,对按钮的时间处理:
public class MainActivity extends Activity {  ...      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) {                  sendBroadcast(new Intent("com.dyk.broadcasttest.MyBroadcastReceiver"));              }          });      }  }  
重新运行程序,效果如下:

  3.2发送有序广播.

        我们新建另一个项目,BroadcastReceiver2,新建AnotherBroadcastReceiver,继承自BroadcastReceiver,代码如下:

public class AnotherBroadcastReceiver extends BroadcastReceiver{      @Override      public void onReceive(Context context, Intent intent) {          Toast.makeText(context,"receiver in AnotherBroadcastReceiver",Toast.LENGTH_SHORT).show();      }  }  
然后在AndroidManifest.xml中对这个广播接收器进行注册:
<?xml version="1.0" encoding="utf-8"?>  <manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.example.administrator.broadcastreceiver2">        <application          android:allowBackup="true"          android:icon="@mipmap/ic_launcher"          android:label="@string/app_name"          android:supportsRtl="true"          android:theme="@style/AppTheme">         ...          <receiver android:name=".AnotherBroadcastReceiver">              <intent-filter>                  <action android:name="com.dyk.broadcasttest.MyBroadcastReceiver"></action>              </intent-filter>          </receiver>      </application>    </manifest>  
,可以看到AnotherBroadcastReceiver同样接收的是 com.dyk.broadcasttest.MyBroadcastReceiver,运行程序,然后回到上一节的Broadcast项目,点击发送按钮,会受到两条广播信息,
可以看出,广播是可以被其他应用程序所接收的。上面介绍的都是标准广播,下面我们来看一下有序广播,打开Broadcast项目,修改MainActivity代码如下:
public class MainActivity extends Activity {  ...      Button button;      @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);          button =(Button)findViewById(R.id.button);          button.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  sendOrderedBroadcast(new Intent("com.dyk.broadcasttest.MyBroadcastReceiver"),null);              }          });      }
sendOrderedBroadcast()方法中第二个参数是与权限有关的参数,我们传入null,现在重新运行下程序,没什么变化,但是现在的广播是有先后顺序的, 我们修改Broadcast中的AndroidManifest.xml文件,如下:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.administrator.broadcasttest"><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>    <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">        <receiver android:name=".MyBroadcastReceiver">            <intent-filter android:priority="100">                <action android:name="com.dyk.broadcasttest.MyBroadcastReceiver"></action>            </intent-filter>        </receiver>    </application></manifest>
将MyBroadcastReceiver的优先级设置了100,以保证它一定会在AnotherBroadcastReceiver之前收到广播.既然MyBroadcastReceiver以及获得了接收广播的优先权,那么MyBroadcastReceiver就可以选择是否允许广播继续传递了,修改MyBroadcastReceiver代码如下:
public class MyBroadcastReceiver extends BroadcastReceiver{    @Override    public void onReceive(Context context, Intent intent) {        Toast.makeText(context,"receiver in MyBroadcastReceiver",Toast.LENGTH_SHORT).show();        abortBroadcast();    }}
abortBroadcast()方法表示将这条广播截断,后面的广播接收器就无法接收了.程序运行程序,会发现只有MyBroadcastReceiver中的Toast信息能够弹出,这说明这条广播经过MyBroadcastReceiver之后确实是终止传递了.

4.使用本地广播
   前面我们接收和发送的广播全部都属于系统广播,既发送的广播能够被其他任何应用程序所接收到,这样就很容易引起安全问题,这时,就需要用到本地广播了,这个广播只能在我们应用程序内部传递,并且广播接收器只能接收来自于本应用的广播,需要注意的是,本地广播是不能通过静态注册方式来接收的.说了这么多,我们看个例子:
新建一个LocalBroadcastManager项目,MainActivity中代码如下:

public class MainActivity extends Activity {    private IntentFilter intentFilter;    private LocalReceiver localReceiver;    private LocalBroadcastManager localBroadcastManager;    private Button button;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        localBroadcastManager =LocalBroadcastManager.getInstance(this);        button =(Button)findViewById(R.id.button);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                localBroadcastManager.sendBroadcast(new Intent("com.dyk.broadcasttest.LOCAL_BROADCAST"));            }        });        intentFilter =new IntentFilter();        localReceiver =new LocalReceiver();        intentFilter.addAction("com.dyk.broadcasttest.LOCAL_BROADCAST");        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,"received local broadcast",Toast.LENGTH_SHORT).show();        }    }}
和动态注册很像,只不过注册和接收,取消注册要用到LocalBroadcastManager类,activity_main代码:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent">    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="发送本地广播" /></RelativeLayout>
,运行程序,
源码









0 0
原创粉丝点击