Android第4讲:广播

文章关于活动的创建,布局代码,控件绑定没有指出,可以先找到相关视频进行基础学习

1. 广播概述

广播接收器的主要责任是在后天接收广播。这些广播相当于“触发器”,而广播接收器相当于“监听器”,这些广播是在整个系统范围内查找广播接收器,能匹配上就可以触发广播接收器,匹配是通过意图实现的
有一些广播是系统发出的,例如时区改变、电池量低、照片已被拍、改变语言习惯等。自定义的广播可以通过上下文(活动和服务)组件实现,其可以发送两种广播:

  • 标准关播。采用异步方式并行发送广播,可以通时发出多个广播,sendBroadcast()可以发送标准广播。
  • 有序广播。采用同步方式串行发送广播,同一时刻只能接收一个广播,sendOrderedBroadcast()可以发送有序广播。

2. 广播接收器

2.1 广播接收器概述

广播接收器和服务被称为非UI组件或后台组件。与服务不同,广播接收器是为后台短时间、少量处理功能而设计的,它的响应处理事件很短。而服务是为后台长事件大量处理功能而设计的,其响应时间比较长,一般还有多线程的处理。广播接收器的最大特点是可以异步、跨进程通信。一般情况下广播接收器接收一个广播后,再启动一个服务,再由服务进行处理。

2.2 编写广播接收器

广播接收器需要重写onReceive(Context context,Intent intent)方法。

广播接收器可以编写一个类继承BroadcastReceiver者是在组件内部创建一个广播接收器内部类。接下来会分别举例。

方式一:编写广播接收器类。

public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "您已经接收到了广播", Toast.LENGTH_SHORT).show();
    }
}

方式二:组件中写内部类。

public class MainActivity extends AppCompatActivity {
	....
	private BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context,"您的内部广播接收器接收了广播",Toast.LENGTH_SHORT).show();
        }
    };
}

2.3 注册广播接收器

广播接收器在使用前要进行注册,注册有两种方式:静态注册动态注册。分别对应上面的两种方式。

静态注册是在AndroidManifest.xml中通过标签</receiver/>注册。与服务一样可以带有过滤器。

静态注册参考代码如下

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        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=".MyBroadcastReceiver">
            <intent-filter>
                <action android:name="com.a51work6.brsample.MyBroadcastReceiver" />
            </intent-filter>
        </receiver>

    </application>

动态注册是在程序种通过registerReceiver()方法注册,通过unregisterReceiver()方法注销。这两个方法在使用的时候需要放置在上下文组件(活动或服务)中的两个相对应的生命周期方法中。例如在onResume()中注册那么就要在onPause()中注销,在onCreate()方法中注册,就要在onDestroy()方法中注销。

动态注册参考代码如下

public class MainActivity extends AppCompatActivity {

	private static String ACTION_APP_INNER_BROADCAST="MyInnerBroadcastReceiver";
	 
	@Override
    protected void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        .....
        IntentFilter filter=new IntentFilter();
        filter.addAction(ACTION_APP_INNER_BROADCAST);//指定过滤的意图
        registerReceiver(broadcastReceiver,filter);//广播接收器的注册

    }
    ....
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(broadcastReceiver);//注销
    }
    .....
    //编写广播接收器
    private BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {...};
}

2.4 实例:发送广播

这个例子是使用动态注册在组件内部创建一个广播接收器内部类

public class MainActivity extends AppCompatActivity {

    private static String ACTION_APP_BROADCAST="MyBroadcastReceiver";
    private static String ACTION_APP_INNER_BROADCAST="MyInnerBroadcastReceiver";

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

        Button button1=findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent =new Intent();
                intent.setAction(ACTION_APP_BROADCAST);//设置意图动作
                sendBroadcast(intent);//发送广播
            }
        });
        
        Button button2=findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent =new Intent();
                intent.setAction(ACTION_APP_INNER_BROADCAST);//设置意图动作
                sendBroadcast(intent);//发送广播
            }
        });
        
        IntentFilter filter=new IntentFilter();
        filter.addAction(ACTION_APP_INNER_BROADCAST);//指定了意图过滤,确定接收的广播
        registerReceiver(broadcastReceiver,filter);//注册广播接收器

    }

	//编写广播接收器
    private BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context,"您的内部广播接收器接收了广播",Toast.LENGTH_SHORT).show();
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(broadcastReceiver);//注销广播接收器
    }
}

3. 系统广播

在Android中,广播是普遍的,例如:时区改变、电量低了、照片已经被拍、改变语言习惯、SD卡的拔出和插入、耳机的拔出和插入、系统启动等等都会发出广播。广播的发出判断是通过意图来实现的。

3.1 系统广播动作

常量说明
Intent.ACTION_TIME_TICK时间改变的时候发出的广播
Intent.ACTION_TIME_CHANGED时间设置的时候发出的广播
Intent.ACTION_TIMEZONE_CHANGED时区改变时候发出广播
Intent.ACTION_BOOT_COMPLETED系统启动完成,发出的一次广播
Intnet.ACTION_PACKAGE_ADDED一个新的应用包程序安装到设备上发出的广播
Intnet.ACTION_PACKAGE_REMOVED一个新的应用包程序从设备上卸载时候发出的广播
Intnet.ACTION_BATTERY_CHANGED电池电量变低,或者是电池的状态发生变化时候发出的广播
AudioManager.VIBRATE_SETTING_CHANGED_ACTION手机震动设置改变时候发出的广播
AudioManager.RINGER_MODE_CHANGED_ACTION手机铃声模式改变时候发出的广播
ConnectivityManager.CONNECTIVITY_ACTION网络连接状态改变时候发出的广播
WifiManager.WIFI_STATE_CHANGED_ACTIONWIFI连接状态改变时候发出的广播

3.2 实例

这个例子设计一个广播接收器接收WIFI连接状态变化的广播,收到广播后启动一个服务,由服务执行数据的下载。服务适合像下载这种耗时的操作。相关服务知识在本人的Android第3讲:服务有讲解。下面来看代码。

广播接收器的代码

public class SyatemReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent it=new Intent(context,DownloadService.class);
        context.startService(it);
    }
}

服务的代码

public class DownloadService extends IntentService {

    private final static String TAG="DownloadService";
    private boolean isRunning=true;
    public DownloadService(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        while (isRunning){
            try{
                Thread.sleep(5000);
                if(isConnected(ConnectivityManager.TYPE_WIFI)){
                    Log.i(TAG,"下载线程开启");
                }
            } catch (Exception e) {
                Log.i(TAG,"下载线程开启失败");
                continue;
            }
        }

    }
	//线程中调用的方法
    private boolean isConnected(int type){
        ConnectivityManager connectivityManager=(ConnectivityManager)this.getSystemService(Context.CONNECTIVITY_SERVICE);
        Network[] networks = connectivityManager.getAllNetworks();
        NetworkInfo networkInfo;

        for(Network mNetwork : networks){
            networkInfo=connectivityManager.getNetworkInfo(mNetwork);
            if(networkInfo!= null && networkInfo.getType()==type && networkInfo.isConnected()){
                return true;
            }
        }
        return false;
    }
}

本例子是展示了系统广播的其中一种使用方式,只要理解之前讲解的广播原理就能够正确使用。

4. 本地广播

4.1 本地广播介绍

上述所说广播都为全局广播,只要接收组件的意图能够匹配上,都可以接收这些广播。因此全局广播有一定的风险。当应用是需要在自己内部进行广播的收发,可以使用本地广播。

本地广播是通过LocalBroadcastManager管理发送、注册和注销的,而全局广播是通过上下文(活动或服务)对象发送、注册、注销广播。LocalBroadcastManager常用方法:

  • boolean sendBroadcast(Intent intent)。发送广播
  • void registerReceiver(BroadcastReceiver receiver,IntentFilter filter)。注册广播
  • void unregisterReceiver(BroadcastReceiver receiver)。注销广播

4.2 实例:发送本地广播

本地广播和之前的全局广播使用思路类似,只不过发送、注册和注销需要本地广播管理器对象执行。

public class MainActivity extends AppCompatActivity {

    private static String ACTION_LOCAL_BROADCAST="MyBroadcastReceiver";
    private LocalBroadcastManager localBroadcastManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //获得本地广播管理器实例
        localBroadcastManager=LocalBroadcastManager.getInstance(this);
        
        IntentFilter filter=new IntentFilter();
        filter.addAction(ACTION_LOCAL_BROADCAST);
        localBroadcastManager.registerReceiver(mReceiver,filter);//注册本地广播


        Button button1=findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent =new Intent();
                intent.setAction(ACTION_LOCAL_BROADCAST);
                localBroadcastManager.sendBroadcast(intent);//本地广播发送
            }
        });
        
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //注销本地广播
        localBroadcastManager.unregisterReceiver(mReceiver);
    }
	//本地广播接收器
    private BroadcastReceiver mReceiver =new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context,"您接收了本地广播",Toast.LENGTH_SHORT).show();
        }
    };

}

文章关于活动的创建,布局代码,控件绑定没有指出,可以先找到相关视频进行基础学习
文章还会持续更新。。。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值