android 广播的使用

      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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值