<Android基础>(五) 广播机制 Part 1

1)接收系统广播:a.动态注册监听网络变化

        b.静态注册实现开机启动

2)发送自定义广播:a.发送标准广播

         b.发送有序广播

3)使用本地广播

第五章

5.1 广播机制

Android中的每个程序都可以对自己感兴趣的广播进行注册。发送广播的方法借助Intent,接收广播的方法则为广播接收器(Broadcast Receiver)。

广播可分为两种。

1.标准广播 (Normal broadcasts):完全异步执行的广播,在广播发出之后,所有广播几乎会在同一时刻接收到这条广播信息,没有任何先后顺序。这种广播传播效率比较高,同时使无法被截断的。

2.有序广播(Ordered broadcasts):同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播,当当前的广播接收器中的逻辑执行完毕后,广播才会继续传递,所以此时的广播接收器是有先后顺序的,优先级高的广播接收器可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后边的广播接收器就无法收到广播信息了。

5.2 接收系统广播

注册广播的方式有两种。

1.动态注册:在代码中注册。

2.静态注册:在AndroidManifest.xml中注册。

5.2.1 动态注册监听网络变化

新建类继承BroadcastReceiver类,并重写onReceive()方法,当有广播来时,onReceiver就会得到执行。

新建一个BroadCastTest项目,修改MainActivity.java中的方法

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);
    }

    class NetworkChangeReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show();
        }
    }
}

a.在MainActivity中定义一个内部类NetworkChangeReceiver,继承BroadcastReceiver类,并重写onReceive()方法,当网络状态变化时显示Toast

b.创建IntentFilter实例,并添加了android.net.conn.CONNECTIVITY_CHANGE的action,意思为当系统的网络发生变化时,及发送该条广播

c.创建NetworkChangeReceiver实例,最后调用registerReceiver()方法传入两个实例进行注册

d.最后,动态广播的广播接收器一定要取消注册,在onDestroy()方法中调用unrigisterReceiver()来实现

运行程序,当网络发生变化时,显示Toast。

优化设计:直接告诉用户是否有网络

修改onReceive()方法

 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_LONG).show();
            }
        }
    }

a.ConnectivityManager为一个系统服务类,专门用于管理网络连接,通过getSystemService()方法得到

b.调用ConnectivityManager的getActiveNetworkInfo()方法来判断当前是否有网络

c.最后判断显示的Toast

Android为了保护用户的隐私和安全,做了严格的规定:如果程序需要进行对一些用户来说敏感的操作,就必须在配置文件中声明权限才可以,否则程序会崩溃。

打开AndroidManifest.xml文件,加入访问系统网络的权限

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.song.broadcasttest">
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

运行程序:

5.2.2 静态注册实现开机启动

动态注册的广播接收器可以自由地控制注册与注销,在灵活方面有很大优势,但是必须要在程序启动之后才能接收广播。

在程序未启动的情况下接收广播,就需要用到静态注册的方式。

a.右击包com.example.song.broadcasttext——>New——>Other——>Broadcast Receiver 创建名为BootCompleteReceiver

修改onReceive()中的方法

@Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show();
    }

b.在AndroidManifest.xml文件中发现静态广播就已经被注册了

 <receiver
            android:name=".BootCompleteReciver"
            android:enabled="true"
            android:exported="true">
</receiver>

c.添加新权限

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.song.broadcasttest">

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

d.系统启动完成后会发出一条值为android.intent.action.BOOT_COMPLETED的广播

 <receiver
            android:name=".BootCompleteReciver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

在<intent-filter>中添加了相应的action

重启模拟器,即可在启动完成后收到开机广播

不要在onReceiver()方法中添加过多的逻辑或者进行任何耗时的操作,当onReceiver()方法运行了较长时间而没有结束时,程序就会报错。

5.3 发送自定义广播

5.3.1 发送标准广播

a.新建类MyBroadcastReceiver,设置显示Toast

public class MyBroadcastReceiver extends BroadcastReceiver {
    public MyBroadcastReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, " received in MyBroadcastReciver", Toast.LENGTH_SHORT).show();
    }
}

b.在AndroidManifest.xml中对这个广播接收器进行修改

<receiver
            android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.song.broadcasttest.MY_BROADCAST"/>
            </intent-filter>

        </receiver>

c.在activity_main.xml中加入一个Button

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    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="Send Broadcast"/>
</LinearLayout>

d.在MainAcitivity.java中为Button注册事件

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent intent = new
                        Intent("com.example.song.broadcasttest.MY_BROADCAST");
                sendBroadcast(intent);
            }
        });
    }

构建一个Intent对象,并把发送的广播的值传入,然后调用Context的sendBroadCast方法将广播发送出去。所有监听com.example.song.broadcasttest.MY_BROADCAST这条广播的广播接收器都会收到消息。

运行程序:

5.3.2 发送有序广播

广播是一种可以跨进程的通信方式,在当前应用程序内发出的广播在其他的应用程序里也是可以收到的。

1.发送标准广播

a.新建一个BroadcastTest2项目,新建AnotherBroadcastReceiver类

public class AnotherBroadcastReceiver extends BroadcastReceiver {
    public AnotherBroadcastReceiver() {
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "received in AnotherBroadcastReceiver",
                Toast.LENGTH_SHORT).show();
    }
}

当接收到广播弹出Toast

b.在AndroidManifest.xml中对这个广播接收器进行修改

 <receiver
            android:name=".AnotherBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.song.broadcasttest.MY_BROADCAST"/>
            </intent-filter>
        </receiver>

同样接收的是com.example.song.broadcasttest.MY_BROADCAST这条广播

运行BroadcastTest项目的程序,点击Send Broadcast按钮,分别弹出两次提示信息

 

2.发送有序广播

a.修改BroadcastTest项目中的MainActivity代码

 button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent intent = new
                        Intent("com.example.song.broadcasttest.MY_BROADCAST");
                sendBroadcast(intent, null);
            }
        });

sendBroadcast()多传入了一个参数null,第一个为Intent,第二个是与权限相关的字符串,传入null

b.设定先后顺序,在AndroidManifest.xml中修改,设定了优先级别为100,以保证它一定会在AnotherBroadcastReceiveer之前收到广播

<receiver
            android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter android:priority="100">
                <action android:name="com.example.song.broadcasttest.MY_BROADCAST"/>
            </intent-filter>

        </receiver>

运行程序与原来效果一样,但实际设定了顺序。

c.可以在MyBroadcastReceiver中设定中断下一步传播

 @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, " received in MyBroadcastReciver", Toast.LENGTH_SHORT).show();
        abortBroadcast();
    }

加一句abortBroadcast()即可截断后面的广播接收器无法再接收到这条广播。

只有MyBroadcastReciver中的Toast信息能够弹出,这条广播经过MyBroadcastReceiver之后中止传递。

5.4 使用本地广播

之前发送的和接收的广播全部属于系统全局广播,即发出的广播可以被其他任何应用程序接收到,并且也可以接受来自其他任何应用程序的广播。

为了能够简单的解决广播的安全性问题,引入本地广播机制,使发出的广播只能够在应用程序内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播。

主要用LocalBroadcastManager来对广播进行管理,并提供了发送和注册广播接收器的方法。

通过LoaclBroadcastManager的getInstance()方法得到一个实例,然后在注册广播接收器的时候调用LocalBroadcastManager的registerReceiver()方法,在发送广播的时候调用LocalBroadcastManager的sendBroadcast()方法。

public class MainActivity extends AppCompatActivity {

    private IntentFilter intentFilter;

    private LocalReceiver localReceiver;

    private LocalBroadcastManager localBroadcastManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        localBroadcastManager = LocalBroadcastManager.getInstance(this);

        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent intent = new
                        Intent("com.example.song.broadcasttest.LOCAL_BROADCAST");
                localBroadcastManager.sendBroadcast(intent);
            }
        });

        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.song.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, "received local broadcast", Toast.LENGTH_SHORT).show();
        }
    }

}

本地广播是无法通过静态注册的方式来接收的。

本地广播的优势:

1.可以明确地知道正在发送地广播不会离开当前的程序,不必担心机密数据泄露。

2.其他地程序无法将广播发送到当前程序的内部,不必担心会有安全漏洞的隐患。

3.发送本地广播比发送系统全局广播将会更加高效。

原文地址:https://www.cnblogs.com/HarSong13/p/10681408.html

时间: 2024-10-13 12:02:24

<Android基础>(五) 广播机制 Part 1的相关文章

Android中使用广播机制退出多个Activity

谷歌百度一下,Android中退出多个Activity的方法,大家讨论的很多. 在实习的时候,看到公司的项目退出多个Activity,是采用LinkedList方法,毕业设计的时候,也参照了那种方法.完成之时,无意在网上看到的可以使用广播机制退出Activity.看了一部分人的博客.文章等教程,发现也是摘抄的“很随便”,说的不详细,或不能实现. 看了他们的意思,写了demo,大家看看吧.主要代码如下:(不方便看的直接下整个工程) 为了代码的简洁性,抽取出一个基类BaseActivity(自定义的

android开发之 广播机制

广播接收器(BroadcastReceiver) Android中的广播主要可以分为两种类型,标准广播和有序广播. 标准广播(Normal broadcasts): 是一种完全异步执行的广播,在广播发出之后,所有的 广播接收器几乎都会在同一时刻接收到这条广播消息, 因此它们之间没有任何先后顺序可 言.这种广播的效率会比较高,但同时也意味着它是无法被截断的.  有序广播(Orderedbroadcasts): 则是一种同步执行的广播,在广播发出之后,同一时刻 只会有一个广播接收器能够收到这条广播消

[Android随笔]BroadcastReceiver广播机制

一,介绍 android四大组件之一:BroadcastReceiver 翻译成中文:广播接收者.在Android中,Broadcast是一种广泛运用在应用程序之间传输信息的机制.而BroadcastReceiver是对发送出来的Broadcast(广播)进行过滤.接收.响应的一类组件. 呵呵,作为一个android研发学习者,我们想要学习使用BroadcastReceiver这个组件,当然实践是最好的方式.下面介绍BroadcastReceiver的几种使用方式. 二,使用方式 2.1 静态注

android基础:广播BroadCast简单案例

运行效果 string.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">TestBroadcast</string> <string name="param_input">请输入发送参数</string> <string name="

Android基础(五) Service全解析----看不见的Activity

一.服务的介绍: 作为Android四大组件之中的一个,Service(服务)也常常运用于我们的日常使用中,它与Activity的差别在于:Service一直在后台执行.没实用户界面.所以绝不会到前台来.但Service被启动起来之后.它就和Activity一样.全然具有自己的生命周期. 在关于程序中是选择用Activity还是Service的一个选择标准就是:假设某个程序组件须要执行时向用户呈现某种用户界面.或者该程序须要与用户交互,就须要使用Activity,否则就该考虑使用Service.

Android学习笔记-广播机制

Android广播类似QT中的信号和槽~~~ 界面文件activity_main.xml    <TextView         android:id="@+id/textView1"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="@string/hell

&lt;Android基础&gt;(五) UI开发 Part 2

ListView 1)ListView的简单用法 2)定制ListView界面 3)提升ListView的运行效率 4)ListView的点击事件 3.5 ListView 3.5.1 ListView的简单用法 1.新建项目,修改activity_main.xml中的代码,插入<ListView>控件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=

九、Android学习第八天——广播机制与WIFI网络操作(转)

(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 九.Android学习第八天——广播机制与WIFI网络操作 今天熟悉了Android中的广播机制与WIFI网络的一些基本操作,总结如下: Android的广播机制 我们知道广播机制中,发送方不会关心接收方时候接收到数据或者如何去处理数据. 这里总结下Android中BroadcastReceiver的注册方法: (一)在应用程序中进行注册 (二)在Manifest.xml

Android广播机制:Broadcast

转载:Android总结篇系列:Android广播机制 1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器).广播作为Android组件间的通信方式,可以使用的场景如下:1.同一app内部的同一组件内的消息通信(单个或多个线程之间): 2.同一app内部的不同组件之间的消息通信(单个进程): 3.同一app具有多个进程的不同组件之间的消息通信: 4.不同app之间的组件之间消息通信: