第五章,详解广播机制

1.Android的每个应用程序都可以对自己感兴趣的广播进行注册,Android的广播分为有序广播和标准广播

       标准广播:是一种完全异步执行的广播, 在广播发出后所有的程序都几乎能在同一时刻接受到该广播

        有序广播:是一种同步执行的广播,在广播发出后,同一时间只有一个广播接收器可以接收到这条广播,优先级高的接收器接收到这条广播后可以选择继续传播或者截断这条广播。


2.接收系统广播

    动态注册

    1.对自己感兴趣的广播进行注册, 内部类接收器 NetworkChangeReceiver继承自BroadCastReceiver, 复写其中的onReceiver方法,每当接收到广播就会执行onReceiver中的方法

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 changed", 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 unavailable", Toast.LENGTH_SHORT ).show();
            }

        }
    }
}

最后记得动态注册的广播一定要取消注册才行, 在onDestroy()中通过调用unregisterReceiver() 方法来实现

这里通过getSystemService方法获得 connectivityManger   需要在AndroidManifest.xml中申请权限

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

2.静态注册

    动态注册相对来说比较灵活,但是有一个缺点就是必须在程序起来之后才能接受广播,因为注册逻辑是写在onCreate()方法中

静态注册可以在程序未启动时就接收到广播。

    下面是开机广播的例子:  在刚才的项目上新建 包上-NEW-Other-Broadcast Receiver完成创建(Exported表示接收本程序以外的广播)  需要复写onReceiver方法

public class BootCompleteReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
      //  throw new UnsupportedOperationException("Not yet implemented");
        Toast.makeText( context, "Boot complete", Toast.LENGTH_SHORT ).show();
    }
}

另外静态广播一定要在AndroidManifest.xml中注册才能使用,还要声明权限

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

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


三.发送自定义广播

    1.自定义广播接收器包上-NEW-Other-Broadcast Receiver完成创建

public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
//        throw new UnsupportedOperationException("Not yet implemented");
        Toast.makeText( context, "received in NyBroadcastReceived", Toast.LENGTH_SHORT ).show();
    }
}
    2.在AndroidManifest.xml中注册广播接收器,接收一条名为

com.example.wangyamin.broadvasttest.MY_BROADCAST的广播

    <receiver
            android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.wangyamin.broadvasttest.MY_BROADCAST"/>
            </intent-filter>
        </receiver>
    3.定义一个按钮发送广播
package com.example.wangyamin.broadvasttest;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
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;
    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);*/
        Button button = (Button)findViewById( R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              //  Toast.makeText( MainActivity.this, "click", Toast.LENGTH_SHORT ).show();
                Intent intent = new Intent( "com.example.wangyamin.broadvasttest" );
                intent.setComponent( new ComponentName("com.example.wangyamin.broadvasttest","com.example.wangyamin.broadvasttest.MY_BROADCAST"));
                sendBroadcast( intent);
            }
        });

    }


   /* @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);
    }*/

   /* class  NetworkChangeReceiver extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            //Toast.makeText( context, "network changed", 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 unavailable", Toast.LENGTH_SHORT ).show();
            }

        }
    }*/
}

四,发送有序广播

       发送有序广播只需要修改 sendBroadcast() 改成 sendOrderedBroadcast( ) 方法,这个方法接收两个参数,第一个是Intent第二个是权限相关字符串。

    设定广播接收器的先后顺序,收到广播后可以使用函数abortBroadcast(); 来阻断广播的继续传递

<intent-filter    android:priority="100">

               <action android:name="com.example.wangyamin.broadvasttest.MY_BROADCAST"/>

 </intent-filter>

五,使用本地广播

    由于广播可以跨进程,所以我们的程序也可以接受其他任何程序的广播,这样很容易引起安全性问题。

    Android程序引入了本地广播,只能在应用程序内部传递 主要使用了一个 LocalBroadcastManager来对广播管理

public class MainActivity extends AppCompatActivity {

    /*private IntentFilter intentFilter;
    private  NetworkChangeReceiver networkChangeReceiver;*/
    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;
    @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 = (Button)findViewById( R.id.button);
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
              //  Toast.makeText( MainActivity.this, "click", Toast.LENGTH_SHORT ).show();
                Intent intent = new Intent( "com.example.wangyamin.broadvasttest" );
               // intent.setComponent( new ComponentName("com.example.wangyamin.broadvasttest","com.example.wangyamin.broadvasttest.MY_BROADCAST"));
                localBroadcastManager.sendBroadcast(intent);
              //  sendBroadcast( intent);
            }
        });
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction( "com.example.wangyamin.broadvasttest");
        localReceiver = new LocalReceiver();
        //注册广播
        localBroadcastManager.registerReceiver( localReceiver, intentFilter);

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


   @Override
    protected void onDestroy() {
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }
   
}

        

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值