广播


广播机制简介

标准广播(Normal broadcasts)

完全异步执行的广播,广播发出后所有的广播接收器几乎在统一时刻收到这条广播信息,无法被截断

有序广播(Ordered broadcasts)

同步执行的广播,广播发出后,同一时刻只会有一个广播接收器能收到这条广播消息,当广播接收器中的逻辑执行完毕后,广播才会继续传递。

接收系统广播

Android内置很多系统级别的广播,我们可以在应用程序中监听这些广播。这就需要广播接收器,下面将介绍其用法:

广播接受器可以对自己感兴趣的广播进行注册,这样当有相应广播发出时,接收器就能够收到。

注册广播的方式一般有两种,在代码中注册和在AndroidManifest.xml中注册,前者被称为动态注册,后者被称为静态注册

动态注册监听网络变化

public class MainActivity extends AppCompatActivity {

    private IntentFilter intentFiler;

    private NetworkChangeReceiver networkchangeReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intentFiler = new IntentFilter();
        intentFiler.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkchangeReceiver = new NetworkChangeReceiver();
        registerReceiver(networkchangeReceiver,intentFiler);
    }

    @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();
        }
    }
}
  1. 定义类NetworkChangeReceiver继承自BroadcastReceiver,重写onReceive()方法得到信息

  2. 在onCreat()方法中创建IntentFiler的实例。添加监听的广播

  3. 创建NetworkChangeReceiver的实例

  4. 调用registerReceiver()方法注册,将NetworkChangeReceive和InterFilter的实例传进去。

  5. 此时,NetworkChangeReceive就可以收到指定值的广播。

  6. 重写onDestroy()方法,加入

    unregisterReceiver(networkchangeReceiver);
    

    取消注册

优化代码

重写NetworkChangeReceiver类

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 not available",Toast.LENGTH_SHORT).show();
        }
    }
}
  1. 通过getSystemService()方法得到了ConnectivityManager的实例,这是一个系统服务类,专门用于管理网络连接。
  2. 调用ConnectivityManager的getActiveNetworkInfo()方法得到NetworkInfo实例
  3. 接着调用NetworkInfo的isAvailable()方法,判断是否有网络

在AndroidManifest,xml文件中加入权限:

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

静态注册实现开机启动

创建广播接收器

Exported:是否允许广播接收器接受程序以外信息

Enabled:是否启用这个广播接收器

修改BootCompleteReceiver中的代码

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.
        Toast.makeText(context,"Boot Complete",Toast.LENGTH_SHORT).show();
    }
}

添加权限

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

修改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>

发送自定义广播

  1. 新建广播接收器

  2. 在AndroidManifest.xml中

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

自定义广播名

  1. 发出对应的广播”com.example.broadcasttest.MY_BROADCAST”时接收器可以收到该广播

对于无法接收静态广播的情况(Android 8.0后):

加入

intent.setComponent(new ComponentName(getPackageName(), "包名"));

发送有序广播

  1. 将sendBroadcast()方法改为sendOrderBroadcast()方法,接收intent和null
  2. 设置优先级
<receiver
    android:name=".MyBroadcastReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter android:priority="100">
        <action android:name="com.example.broadcasttest01.MY_BROADCAST"/>
    </intent-filter>
</receiver>
  1. 截断代码,在OnReceive()方法中添加abortBroadcast()方法。

使用本地广播

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);
        Button button = findViewById(R.id.button);
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent("com.example.LOCAL_BROADCAST");
                localBroadcastManager.sendBroadcast(intent);
            }
        });
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.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 in local broadcast",Toast.LENGTH_SHORT).show();
        }
    }
}

主要使用一个LocalBroadcastManager来对广播进行管理

  1. 新建类LocalReceiver继承自BroadcastReceiver()

  2. 通过LocalBroadcastManager.getInstance(this)方法得到实例

  3. 调用LocalBroadcastManager的registerReceiver()方法注册广播接收器

  4. 调用localBroadcastManager.sendBroadcast()方法发送广播


Author: Xi Chen
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Xi Chen !
评论
  TOC