首页 > 代码库 > 广播接收者(Broadcast Receiver)

广播接收者(Broadcast Receiver)


独立寒秋,湘江北去,橘子洲头。 —–毛泽东《沁园春·长沙》


  • 广播
    • 广播类型
      • 有序广播
      • 无序广播
      • 特殊的广播接收者
    • 注册广播接收者的两种方式
  • 系统广播示例
    • 接收系统发送的广播
      • 示例-短信到来
  • 自定义无序广播示例
    • 创建广播
    • 接收广播方式静态注册
    • 接收广播方式代码注册
  • 自定义有序广播示例
    • 发送有序广播
    • 接收有序广播
    • 有序广播结果
    • 特殊的广播接收者-锁屏等等

广播

  • 听广播要有:电台 收音机 音乐广播
  • Android系统内部已经定义好了电台 ,也已经定义好了一些广播事件

    比如外拨电话 短信到来 SD卡状态 电池电量….

  • 使用Broadcast Receiver取接收系统已经定义好的事件

  • 定义广播是为了开发者更好的开发
  • 发送方和接收发可以是同一个应用程序
  • 广播接收器没有用户界面
  • 如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service, 由Service 来完成

广播类型

有序广播

按照一定的优先级接收
发送优先级级别数值是在 -1000 到 1000 之间 , 值越大 , 发送的优先级越高
有序广播的数据可以被修改
有序广播的数据可以被终止

无序广播

无序广播的数据不可以被修改
无序广播的数据不可以被终止

特殊的广播接收者

操作特别频繁的广播事件,比如屏幕的锁屏和解锁,电池电量的变化 这种事件的广播在清单文件里面注册无效

SD卡的安装,卸载的广播,想要接收的话,需要一个约束类型,在< receiver>中

         <receiver android:name="....">
            <intent-filter>
                <action android:name="android.intent.action.MEDIA_UNMOUNTED"></action>
                <action android:name="android.intent.action.MEDIA_MOUNTED"></action>
                <!--约束类型叫file sd卡的数据类型是file -->
                <data android:scheme="file"></data>
            </intent-filter>
        </receiver>

应用程序的安装,卸载 也需要一个约束类型

<data android:scheme="package"></data>

注册广播接收者的两种方式

注意
动态注册,广播接收者的生命周期依附应用程序的生命,关闭程序,广播接收者也无效了
在清单文件里注册,广播接收者的生命会依附应用程序的进程存在,即使关闭了应用程序,进程没有销毁(没有因为内存不足销毁),广播接收者也是有效的

[1]动态注册 通过代码方式注册

private MyBroadcast myBroadcast;
......
        myBroadcast = new MyBroadcast();

        IntentFilter filter =new IntentFilter();
        filter.addAction("......");
        registerReceiver(myBroadcast,filter);
public  class MyBroadcast extends BroadcastReceiver{
 @Override
        public void onReceive(Context context, Intent intent) {
        //接收广播后执行逻辑
        }
}
@Override
protected void onDestroy() {
    unregisterReceiver(screenReceiver);
    super.onDestroy();
}

[2]在清单文件里通过receiver tag 节点静态发布

<receiver android:name=".SmsListenerReciver">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
            </intent-filter>
</receiver>

系统广播示例

接收系统发送的广播

[1] 定义广播接收者

public class onReceiver extends BroadcastReceiver {
@Override
    public void onReceive(Context context, Intent intent) {
    }
}

[2]在清单文件里配置

<receiver android:name=".SmsListenerReciver"/>

[3定义过滤器具体接收什么广播

<intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>

示例-短信到来

短信到来是一个有序广播

  • 定义广播接收者
package com.peng.smslistener;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;

/**
 * Created by Peng on 2016/7/31.
 */
public class SmsListenerReciver  extends BroadcastReceiver{
    //短信到来是执行
    @Override
    public void onReceive(Context context, Intent intent) {

        System.out.println("短信到了");
        //拿到信息发送的内容和号码
         Object object[] = (Object[]) intent.getExtras().get("pdus");

        //循环取短信
        for(Object obj:object){
            //获取smsmessage实例
             SmsMessage smsMessage= SmsMessage.createFromPdu((byte[]) obj);
            //获取发送短信的内容
            String messageBody = smsMessage.getMessageBody();
            String address = smsMessage.getOriginatingAddress();

            System.out.println("body:"+messageBody+address);
        }

    }
}
  • 配置广播接收者
<receiver android:name=".SmsListenerReciver">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
            </intent-filter>
        </receiver>
        ...
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>

自定义无序广播示例

发送广播和接收广播在不同的两个应用程序中

创建广播

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void click(View view) {
        //发送无序广播
         Intent intent =new Intent();
        intent.setAction("com.peng.guangbo");

        intent.putExtra("name","新闻联播每天晚上7点准时开播");

        sendBroadcast(intent);
        System.out.println("--------------->>>>>>>发送无序广播");
    }
}

接收广播方式(静态注册)

public class onReceiver extends BroadcastReceiver {

    //接收自定义广播
    @Override
    public void onReceive(Context context, Intent intent) {
        //终止广播,在无序广播里没用
        abortBroadcast();
        String content =intent.getStringExtra("name");

   Toast.makeText(context,content,Toast.LENGTH_LONG).show();
    }
}
<receiver android:name="定义的接收者类名">
            <intent-filter>
                <action android:name="com.peng.guangbo"></action>
            </intent-filter>
</receiver>

接收广播方式(代码注册)

有序和无序广播都可以通过代码注册

public class MainActivity extends AppCompatActivity {

    private Mybroadcastreceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        receiver = new Mybroadcastreceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.peng.guangbo");
        registerReceiver(receiver,filter);
    }
    public class Mybroadcastreceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            String content =intent.getStringExtra("name");
            System.out.println(">>>>>>>>>>>动态注册");
            Toast.makeText(context,content, Toast.LENGTH_LONG).show();
        }
    }

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

自定义有序广播示例

发送广播和接收广播在不同的两个应用程序中

发送有序广播

假定”政府”发送一个广播,并携带数据”政府给每个村民发了1000元补贴”,这里设置了四个接收者,分别是”省长”,”市长”,”乡长”,和”农民”,优先级级别从高到低,并且会更改数据

 public void click(View view) {
        //点击按钮发送有序广播
        Intent intent = new Intent();
        intent.setAction("com.peng.sendrice");
        /**
         *
         * 1 Intent 意图
         * 2 receiverPermission 接收的权限
         * 3 resultReceiver 最终的receiver
         * 4 scheduler handler
         * 5 initialcode 初始码
         * 6initalDate 初始化数据
         */
        sendOrderedBroadcast(intent,null,new FinalReceiver(),null,1,"政府给每个村民发了1000元补贴",null);
    }

FinalReceiver 位于发送广播的应用程序中
这是一个resultReceiver,也是一个广播接收者,也可以理解为finalReceiver,当广播被所有接收方接收之后,才会执行这个广播接收者,相当于广播结果的反馈,它返回的是最后一个广播接收者接收的内容,在这个例子中就是”农民”的接收的数据

public class FinalReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        String content = getResultData();

        Toast.makeText(context,"报告习大大:"+content,Toast.LENGTH_LONG).show();

    }
}

接收有序广播

在清单文件里配置过滤器,接收方分别新建一个类,便于管理
技术分享
如果你想在MainActivity里写广播接收者,又想在清单文件里配置,就会是这样,

<receiver android:name=".MainActivity$Mybroadcastreceiver"></receiver>

“省长”

public class ProvienceReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        String content = getResultData();

        Toast.makeText(context,"省长:"+content,Toast.LENGTH_LONG).show();
       /*
        *//终止广播
        *abortBroadcast();
        */
        //修改广播
        setResultData("政府给每个村民发了500元补贴");

    }
}

“市长”

public class CityReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        String content = getResultData();

        Toast.makeText(context,"市长:"+content,Toast.LENGTH_LONG).show();
        //修改广播
        setResultData("政府给每个村民发了250元补贴");
    }
}

“乡长”

public class CountryReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        String content = getResultData();

        Toast.makeText(context,"乡长:"+content,Toast.LENGTH_LONG).show();
        //修改广播
        setResultData("政府给每个村民发了50元补贴");
    }
}

“农民”

public class NongMinReceiver  extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {

        String content = getResultData();

        Toast.makeText(context,"农民:"+content,Toast.LENGTH_LONG).show();
    }
}
  • 清单文件里配置< reeiver>和优先级
    如果通过代码注册,优先级可以这样设置
IntentFilter intentFilter =new IntentFilter();
intentFilter.addAction("......");
intentFilter.setPriority(100);

清单文件里配置

 <receiver android:name=".ProvienceReceiver">
              <!-- 省长-->
            <intent-filter android:priority="1000">
                <action android:name="com.peng.sendrice"></action>
            </intent-filter>
        </receiver>
            <!-- 市长-->
        <receiver android:name=".CityReceiver">
            <intent-filter android:priority="500">
                <action android:name="com.peng.sendrice"></action>
            </intent-filter>
        </receiver>
              <!-- 乡长-->
        <receiver android:name=".CountryReceiver">
            <intent-filter android:priority="100">
                <action android:name="com.peng.sendrice"></action>
            </intent-filter>
        </receiver>
              <!-- 农民-->
        <receiver android:name=".NongMinReceiver">
            <intent-filter android:priority="-100">
                <action android:name="com.peng.sendrice"></action>
            </intent-filter>
        </receiver>

有序广播结果

技术分享

特殊的广播接收者-锁屏等等

MainActivity.java

.....
public class MainActivity extends AppCompatActivity {
    private ScreenReceiver screenReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //动态的注册广播接收者
         screenReceiver = new ScreenReceiver();
        /*<intent-filter>
        <action android:name="android.intent.action.SCREEN_ON"></action>
        <action android:name="android.intent.action.SCREEN_OFF"></action>
        </intent-filter>*/

        //创建intentfilter对象
         IntentFilter intentFilter =new IntentFilter();

        //添加要注册的action
        intentFilter.addAction("android.intent.action.SCREEN_ON");
        intentFilter.addAction("android.intent.action.SCREEN_OFF");
        //动态的注册广播接收者
        registerReceiver(screenReceiver,intentFilter);

    }

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

ScreenReceiver.java

.....
public class ScreenReceiver extends BroadcastReceiver {
    //当我们屏幕解锁和锁屏 这个方法执行
    @Override
    public void onReceive(Context context, Intent intent) {
        //获取广播的事件类型
        String action = intent.getAction();
        if("android.intent.action.SCREEN_OFF".equals(action)) {
            System.out.println("屏幕锁屏了");
        }else if("android.intent.action.SCREEN_ON".equals(action)){
            System.out.println("屏幕解锁了");
        }
    }
}

屏幕都关了,就不要用Toast显示屏幕锁屏数据了

<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
    ‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
  • ‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>

    广播接收者(Broadcast Receiver)