第12+13天BroadCastReceiver广播

BroadCastReceiver

在这里插入图片描述

一.BroadCastReceiver介绍:

在这里插入图片描述

  • BroadCastReceiver广播接受者,安卓四大组件之一
  • 广播三要素:
    (1)广播发送者 : 发送广播
    (2)广播接收者(调频): 用于接收广播
    (3)要处理的事情 :处理广播的相关信息, Intent有图对象
  • 广播的使用场景:
    (1)同一APP下多个组件之间传递数据(Activity/Fragment/Service之间传递数据)
    (2)2个APP之间传递数据
  • 技能get点:
    (1)自定义广播接受者
    (2)使用广播接受者进行电话拦截和短信拦截和系统电量的变化

二.如何实现广播

步骤1:广播接受者
(1)自定义类继承BroadcastReceiver,重写onReceive方法
(2)注册广播(安卓的四大组件都需要注册

  • 静态注册:在清单文件中
  • 动态注册:在代码中注册(注册和解除注册)

步骤2:广播发送方:sendBroadcast(Intent意图对象)

静态注册和动态注册的区别:假如说Activity是接受者:
动态注册:
(1)广播会跟Activity的生命周期的结束而结束;
(2)自由的控制注册和取消,有很大的灵活性
静态注册:
(1)广播不会跟随Activity的生命周期的结束而结束,一直存在,即使应用程序关闭,也会被唤醒接受广播
(2)全局的广播

三.代码案例:

(1)自定义广播接受者类继承BroadCastReceiver,重写onReceiver方法

 public class MyReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        //TODO 1:获取action
        String action = intent.getAction();
        if("android.bawei.action.customer".equals(action)){
            Bundle bundle = intent.getExtras();
            int msg=bundle.getInt("msg");
            Log.i("广播", "接受到了一个广播: "+msg);

        }
    }
}

(2)注册广播方式一:清单文件静态注册

 <!--收音机-->
        <receiver android:name=".MyReceiver">
            <!--调频-->
            <intent-filter>
                <action android:name="android.bawei.action.customer" />
            </intent-filter>
        </receiver>

(3)注册广播方式二:动态注册
onCreate():注册广播调用Context的registerReceiver()方法
onDestory():解除注册调用Context的unregisterReceiver()方法

public class MainActivity extends AppCompatActivity {
    private MyReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        receiver=new MyReceiver();
        regeister();//注册广播
    }
    private void regeister() {
        //TODO 1:创建过滤器
        IntentFilter intentFilter=new IntentFilter();
        //TODO 2:调频:
        intentFilter.addAction("android.bawei.action.customer");
        //TODO 3:注册: 给这个Activity注册
        registerReceiver(receiver,intentFilter);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);//解除注册
    }
}

(4)发送方:sendBroad(Intent意图对象)

 //按钮的点击事件
    public void customer(View view) {
        Intent intent=new Intent();
        intent.setAction("android.bawei.action.customer");
        Bundle bundle=new Bundle();
        bundle.putString("msg","发送广播");
        intent.putExtras(bundle);
        sendBroadcast(intent);
    }

四.广播的分类:

1. 无序广播:sendBroadcast()

2.有序广播:sendOrderBroadcast()

当发送的是有序广播的时候,优先级越高的接受者越先接收到广播,可以调用abortBroadCast()中断广播,不让其他人接受广播。

3.粘性广播:sendStickyBroadcast()

将之前广播发送方发送的消息存储起来,普通广播就不能接受之前发过的消息

五.BroadCastReceiver和Notifcation 的结合使用

为通知上的图片设置点击事件
在这里插入图片描述

1.自定义通知布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:src="@drawable/ic_launcher_background"
        android:id="@+id/iv"
        android:layout_width="60dp"
        android:layout_height="60dp"></ImageView>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/tv_name"
            android:text="歌曲名称"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"></TextView>
        <TextView
            android:id="@+id/tv_artist"
            android:text="歌手"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"></TextView>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <ImageView
                android:layout_weight="1"
                android:id="@+id/iv_pre"
                android:src="@drawable/pre"
                android:layout_width="0dp"
                android:layout_height="wrap_content"></ImageView>
            <ImageView
                android:layout_weight="1"
                android:id="@+id/iv_play"
                android:src="@drawable/play"
                android:layout_width="0dp"
                android:layout_height="wrap_content"></ImageView>
            <ImageView
                android:layout_weight="1"
                android:id="@+id/iv_next"
                android:src="@drawable/next"
                android:layout_width="0dp"
                android:layout_height="wrap_content"></ImageView>
        </LinearLayout>




    </LinearLayout>

</LinearLayout>

2.java核心代码

 //TODO 1:获得通知管理者
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        //TODO 2:创建builder
        RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.no);
        //设置文字
        remoteViews.setTextViewText(R.id.tv_name,"青花瓷");
        remoteViews.setTextViewText(R.id.tv_artist,"周杰伦");
        //设置图片:本地图片SD卡权限
        // remoteViews.setImageViewResource(R.id.iv,R.drawable.pre);
        remoteViews.setImageViewBitmap(R.id.iv, BitmapFactory.decodeFile("/sdcard/分组通知.png"));
        //设置点击+发送广播
        {
            Intent intent = new Intent();
            intent.setAction("com.bawei.pre");
            //参数一 上下文 参数二 请求码 参数三 intent对象 参数四 flag标记 update
            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 101, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            remoteViews.setOnClickPendingIntent(R.id.iv_pre, pendingIntent);
        }

        {
            Intent intent = new Intent();
            intent.setAction("com.bawei.play");
            //参数一 上下文 参数二 请求码 参数三 intent对象 参数四 flag标记 update
            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 101, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            remoteViews.setOnClickPendingIntent(R.id.iv_play, pendingIntent);
        }
        {
            Intent intent = new Intent();
            intent.setAction("com.bawei.next");
            //参数一 上下文 参数二 请求码 参数三 intent对象 参数四 flag标记 update
            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 101, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            remoteViews.setOnClickPendingIntent(R.id.iv_next, pendingIntent);
        }

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 102, new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);

        Notification.Builder builder = new Notification.Builder(this)
                .setContentIntent(pendingIntent)//设置通知的跳转到activty
                .setSmallIcon(R.mipmap.ic_launcher)  //必须设置小图片
                .setCustomContentView(remoteViews);//设置自定义布局
        //TODO 3:发送通知
        manager.notify(1,builder.build());

六 .本地广播和全局广播

全局广播可以跨app接受和发送数据,不安全
本地广播只能本app发送和接受数据,安全

1.全局广播

发送的广播事件可被其他应用程序获取,也能响应其他应用程序发送的广播事件(可以通过 exported–是否监听其他应用程序发送的广播 在清单文件中控制) 全局广播既可以动态注册,也可以静态注册。

2.本地广播

发送的广播事件不被其他应用程序获取,也不能响应其他应用程序发送的广播事件。
本地广播只能被动态注册,不能静态注册。动态注册或方法时需要用到LocalBroadcastManager。

3.实现:

依赖:implementation ‘androidx.localbroadcastmanager:localbroadcastmanager:1.0.0’

package com.example.day013;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class MyReceiver extends BroadcastReceiver {
    private static final String TAG = "MyReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, "onReceive: ");
    }
}


package com.example.day013;

import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements  View.OnClickListener{
    private Button send;
    private LocalBroadcastManager localBroadcastManager;
    private MyReceiver myReceiver;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        send = findViewById(R.id.send);
        send.setOnClickListener(this);
        //创建一个本地广播
        localBroadcastManager = LocalBroadcastManager.getInstance(this);

	    //动态注册一个广播
        myReceiver = new MyReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.feng");
        localBroadcastManager.registerReceiver(myReceiver,intentFilter);

    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
            case R.id.send:
                Intent intent = new Intent();
                intent.setAction("com.feng");
                //注意广播的发送者
                localBroadcastManager.sendBroadcast(intent);
                break;

            default:
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //有注册就有销毁
        localBroadcastManager.unregisterReceiver(myReceiver);
    }
}

七.获取系统广播:动态注册

更多的广播:https://blog.csdn.net/cc_want/article/details/82344899

1.来电监听

(1)添加权限:

android.permission.READ_PHONE_STATE

(2)注册广播(这里用的是动态广播)

		musicRecevicer = new MusicRecevicer();
        IntentFilter intentFilter = new IntentFilter();
     	intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);//来电监听       
        getActivity().registerReceiver(musicRecevicer,intentFilter);

(3)创建接受广播对象

class MusicRecevicer extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
           if(TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(intent.getAction())){//来电
                TelephonyManager telephonyManager = (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
                telephonyManager.listen(new PhoneStateListener(){
                    @Override
                    public void onCallStateChanged(int state, String phoneNumber) {
                        super.onCallStateChanged(state, phoneNumber);
                        switch (state){
                            case TelephonyManager.CALL_STATE_RINGING://来电话
                                musicBinder.pause();
                                break;

                            case TelephonyManager.CALL_STATE_IDLE://挂断
                                musicBinder.start();
                                break;

                            case TelephonyManager.CALL_STATE_OFFHOOK://童话
                                musicBinder.pause();
                                break;

                        }
                    }
                },PhoneStateListener.LISTEN_CALL_STATE);

            }
        }
    }

(4)注销掉广播对象

@Override
    public void onDestroyView() {
        super.onDestroyView();
        if(musicRecevicer != null){
            getActivity().unregisterReceiver(musicRecevicer);
        }
    }

2.网络状态监听

(1)添加权限:

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

(2)注册广播(这里用的是动态广播)

		musicRecevicer = new MusicRecevicer();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);//网络状态监听
        getActivity().registerReceiver(musicRecevicer,intentFilter);

(3)创建接受广播对象

class MusicRecevicer extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
if(ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())){//网络
                ConnectivityManager connectivityManager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
                if(activeNetworkInfo != null && activeNetworkInfo.isConnected()){//有网
                    musicBinder.start();
                }else{//无网
                    musicBinder.pause();
                }
            }


  	}
    }

(4)注销掉广播对象

@Override
    public void onDestroyView() {
        super.onDestroyView();
        if(musicRecevicer != null){
            getActivity().unregisterReceiver(musicRecevicer);
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值