Android 广播机制

1.Android中的广播分为两种:

(1)标准广播:完全异步执行,当广播发出时,所有的广播接收器同时收到消息,故无法被截断;

(2)有序广播:同步执行,在一条广播发出后,广播接收器1收到消息,处理完毕后,才会传到广播接收器2,故前面的广播接收器可以截断正在传递的广播。

2.广播接收器注册的方法分为两种:

(1)动态注册:在代码中注册;动态注册的广播接收器可以自由地控制注册与注销,在灵活性方面有很大的优势,但是它有一个缺点,必须在程序启动之后才能收到广播

(2)静态注册:在AndroidManifest.xml中注册;可以让程序在未启动的情况下就能接收到广播。

下文都为系统全局广播

3.接收系统广播(以动态注册监听网络变化为例),需用将NetWorkChangeReceiver定义为内部类

(1)只可以监听到网络状态发生变化,但不知道目前的网络状态

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");                     //添加响应广播的action
        
        netWorkChangeReceiver = new NetWorkChangeReceiver();
        registerReceiver(netWorkChangeReceiver, intentFilter);                                             //调用此方法进行注册后,NetWorkChangeReceiver类就会收到action对应的广播
    }
    
    private class NetWorkChangeReceiver extends BroadcastReceiver
    {
        //当网络状态发生变化时,onReceive方法将得以执行
        @Override
        public void onReceive(Context context, Intent intent)
        {
            // TODO Auto-generated method stub
           Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show();
        }
    }
    
    //动态注册的广播都需要取消注册
    @Override
    protected void onDestroy()
    {
        // TODO Auto-generated method stub
        super.onDestroy();
        unregisterReceiver(netWorkChangeReceiver);    //取消注册
    }
}
(2)在(1)的基础上,知道网络状态,只需修改onReceive方法,

 private class NetWorkChangeReceiver extends BroadcastReceiver
    {
        //当网络状态发生变化时,方法得以执行
        @Override
        public void onReceive(Context context, Intent intent)
        {
            // TODO Auto-generated method stub
            //ConnectivityManager类是一个系统服务类,专门用于管理网络连接
            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();
            }
            
        }
    }

若程序需要访问一些系统的关键信息,必须在配置文件中声明权限

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcasttest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21" />

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

    
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

4.接收系统广播(静态注册实现开机启动),不再使用内部类的方式来定义广播接收器,但要在AndroidManifest.xml中将这个广播接收器的类名注册进去。

(1)不用内部类定义广播接收器
    public class BootComplteteReceiver extends BroadcastReceiver
    {
       
        @Override
        public void onReceive(Context context, Intent intent)
        {
            // TODO Auto-generated method stub
            Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();
        }
    }

(2)注册权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.broadcasttest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="21" />

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <receiver
            android:name="com.example.broadcasttest.BootComplteteReceiver">         //类名
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

    </application>

</manifest>

动态注册有问题。。。。。。没解决。。。。。。。猜想是不是系统的问题

5.发送自定义广播

(1)发送标准广播

a.新建一个MyBroadcastReceive.java,其中MyBroadcastReceive类继承自BroadcastReceiver,一定要新建!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!,不然程序会死

public class MyBroadcastReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // TODO Auto-generated method stub
        Log.d("myError", "出问题了啊");
        Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_LONG).show();
    }
}

b.在AndroidManifest.xml中进行注册

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

c.在布局文件中定义一个按钮,作为发送广播的触发点,然后修改mainActivity中的代码

        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener()
        {
            
            @Override
            public void onClick(View v)
            {
                // TODO Auto-generated method stub
                Log.d("myError", "出问题了");
                Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
                sendBroadcast(intent);
                Log.d("myError", "没问题");
                
            }
        });

(2)发送有序广播

a.MainActivity中:

        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener()
        {
            
            @Override
            public void onClick(View v)
            {
                // TODO Auto-generated method stub
                Log.d("myError", "出问题了");
                Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
                sendOrderedBroadcast(intent,null);                      //发送有序广播,第一个参数是Intent,第二个参数是一个与权限相关的字符串,这里传入null就行了
                Log.d("myError", "没问题");
                
            }
        });

b.AndroidManifest.xml

         <receiver
            android:name=".MyBroadcastReceiver">
            <intent-filter android:priority="100">                        //给广播接收器设置优先级,优先级比较高的广播器就可以先收到广播
                <action android:name="com.example.broadcasttest.MY_BROADCAST"/>
            </intent-filter>
        </receiver>

c.public class MyBroadcastReceiver extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        // TODO Auto-generated method stub
        Log.d("myError", "出问题了啊");
        Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_LONG).show();
        abortBroadcast();    //截断广播
    }
}

上文都为系统全局广播

6.使用本地广播

//动态注册广播
public class MainActivity extends Activity
{
    private LocalReceiver localReceiver;                    //广播接收器
    private IntentFilter intentFilter;                        //过滤广播
    private LocalBroadcastManager localBroadcastManager;    //本地广播
    
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //IntentFilter对象负责过滤掉组件无法响应和处理的Intent,只将自己关心的Intent接收进来进行处理
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.broadcasttest.MY_BROADCAST");
        
        //获取实例
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        
        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener()
        {
            
            @Override
            public void onClick(View v)
            {
                // TODO Auto-generated method stub
                Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");//传入要发送的广播的值
                localBroadcastManager.sendBroadcast(intent);    //发送本地广播
                
            }
        });
        
        localReceiver = new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver, intentFilter);    //注册本地广播监听器
    }
    
    //创建广播接收器
    class LocalReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            // TODO Auto-generated method stub
            Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();
        }
    }
    //取消注册
    @Override
    protected void onDestroy()
    {
        // TODO Auto-generated method stub
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值