小谈Android四大组件之BroadcastReceiver

前面的话

广播接收者(BroadcastReceiver)是什么??什么时候才会用到呢?

当你的手机出现如下情况: 电量不足,sd卡被移除,电话外拨,短信到了等等…

你的手机往往会在第一时间就弹窗给你提醒,这些贴心的功能就是靠BroadcastReceiver实现的!!

定义的个人理解

广播(Broadcast):

广而告之!具有全局性,涵盖整一个安卓的操作环境,即一个安卓设备.

接收者(Receiver)

被动的去接收数据. 只要安卓系统中有数据到来需要接受,它就会默默的完成它的使命.

广播接收者特点:

1.即使应用程序进程不存在,当广播事件到来的时候,广播接收者进程会自动启动,响应广播事件

2.Android4.0以后,将应用强行停止后,应用会被冻结,直到再次手工开启应用才能继续响应广播事件.

如何创建广播接收者

创建步骤:

1.创建一个类继承BroadcastReceiver(买个收音机)
    *重写onReceive()方法
2.配置清单文件.在application节点下定义<receiver>节点(装电池)
    *<receiver android:name="包名称+类名称"><receiver/>
3.在步骤2定义的<reciever>节点下配置<intent-filter>节点. 在<intent-filter>节点内定义<action>和<date>节点(调频道)
    *<intent-filter>
        <action android:name="android.intent.action.XXX"><action/>
        <data android:scheme="包名"><data/>
    <intent-filter/>
4.在onReceive()方法里编写逻辑(步骤1)

<小案例一:应用程序安装和卸载>

1.配置清单文件:

<!--直接获取系统的广播事件-->
<receiver android:name="com.heima.un_install.InstallReceiver">
    <intent-filter >
        <action android:name="android.intent.action.PACKAGE_ADDED"/>
        <action android:name="android.intent.action.PACKAGE_REMOVED"/>
        <data android:scheme="package"/>
    </intent-filter>
</receiver>

2.写个类继承BroadcastReceiver,接受系统广播数据:

@Override
public void onReceive(Context context, Intent intent) {
    String action=intent.getAction();
    if ("android.intent.action.PACKAGE_ADDED".equals(action)) {
        System.out.println("有应用程序被安装了:"+intent.getData().toString());
    }else if ("android.intent.action.PACKAGE_REMOVED".equals(action)) {
        System.out.println("有应用程序被卸载了:"+intent.getData().toString());
    }
}

<小案例二:IP拨号器>

需求:利用系统拨号器拨打电话时自动添加前缀:17951

1.配置清单文件和呼叫电话的权限

<!--配置receiver-->
<receiver android:name="com.heima.ipcall.IPcallReceiver">
    <intent-filter >
        <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
    </intent-filter>
</receiver>

<!--添加呼叫电话的权限-->
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

2.写一个Actiity,获取电话号码,存到sp里

public class MainActivity extends Activity {
private EditText et_ipnumber;
private SharedPreferences sp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //关系控件
        et_ipnumber=(EditText) findViewById(R.id.et_ipnumber);
        //创建一个SharedPreferences
        sp=getSharedPreferences("config", 0);
        //回显设置的IP前缀到页面上
        et_ipnumber.setText(sp.getString("ipNum", ""));
    }

    //按钮点击事件
    public void save(View view){
        //获取输入的IP前缀
        String ipNum=et_ipnumber.getText().toString().trim();
        sp=getSharedPreferences("config", 0);
        Editor editor = sp.edit();
        //存到sp里
        editor.putString("ipNum", ipNum);
        editor.commit();
        Toast.makeText(MainActivity.this, "设置成功",0).show();
    }
}

MainActivity的布局文件:

<!--使用线性布局,垂直分布-->
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="请设置您的IP号码" />
<EditText 
    android:id="@+id/et_ipnumber"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="内容留空表示取消ip拨号"
    />
<Button 
    android:onClick="save"
    android:layout_gravity="center"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="保存"
    />

3.写一个广播接收者类继承BroadcastReceiver

@Override
public void onReceive(Context context, Intent intent) {
    //获取存到config.xml文件里的数据
    SharedPreferences sp=context.getSharedPreferences("config", 0);
    String ipNum = sp.getString("ipNum", "");
    String num=getResultData();
    //设置拨打的电话号码
    if (num.startsWith("0")) {
        setResultData(ipNum+num);
    }

}

小结:

以上是一般的广播事件,可以通过清单文件注册广播事件,即静态注册. 同时也可以在java代码里面动态注册. 一般使用静态注册.

特殊的广播接收者

一些操作比较频繁的事件,比如锁屏解锁和电量变化,这些事件会发送特定的广播.这列广播在清单文件里配置不会生效,只能在Java代码中进行注册.即动态注册

锁屏广播接收者核心代码:

在MainActivity.java里

的onCreate()方法里面写:

receiver=new ScreenStatusReceiver();
IntentFilter filter=new IntentFilter();
//屏幕关闭的action
filter.addAction("android.intent.action.SCREEN_OFF");
//屏幕点亮的action
filter.addAction("android.intent.action.SCREEN_ON");
//注册广播接收者
registerReceiver(receiver,filter);

在MainActivity.java的onDestory()方法里写:

//取消注册广播接收者(必须!!否则会报错)
unregisterReceiver(receiver);
receiver=null;

自定义类继承BroadcastReceiver:

在onReceive()方法里面写:

if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
    Log.d("tag","监听到屏幕点亮了");
}else if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
    Log.d("tag","监听到屏幕关闭了");
}

注:

1.监听锁屏和解锁不需要额外的权限, 因此可以直接运行.
2.为了避免IntentReceiver的泄露.必须在MainActivity的onDestory方法中或者其他地方(必须保证Activity被销毁之前)将接收者给反注册掉.

广播事件的发送类型

发送有序广播:

*广播消息按照一定的顺序传达. 高优先级接收者先得到消息,低优先级后得到. 如果优先级相同,则按
照清单文件配置的顺序依次减弱优先级.

*高优先级可以拦截或者修改广播消息.

*有序广播使用context.sendOrderedBroadcast()方法来发送,使用abordBroadcast()方法拦截

实例: 短信窃听拦截

分析:窃听短信是利用有序广播的优先级和终止来实现的.

1.配置清单文件,设置接收短信的权限,设置设置广播接收者的优先级

 <receiver android:name="com.heima.msglisten.SMSListenerReceiver">
        <!--优先级设置为最高1000-->
        <intent-filter android:priority="1000" >
            <!--设置接收数据类型-->
            <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
        </intent-filter>
 </receiver>

<!--配置接收短信的权限-->
<uses-permission android:name="android.permission.RECEIVE_SMS"/>

2.写一个广播接收者类,解析PDU格式短信内容,并终止(拦截)有序广播

public class SMSListenerReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        System.out.println("短信来啦啊~~~~");
        //解析PDU格式的短信信息
        Object[] objs = (Object[]) intent.getExtras().get("pdus");
        for (Object obj:objs) {
            SmsMessage smsMessage=SmsMessage.createFromPdu((byte[]) obj);

            String body = smsMessage.getMessageBody();
            String sender = smsMessage.getOriginatingAddress();
            System.out.println("body:"+body+"\nsender:"+sender);
            //终止发短信的有序广播
            if (isOrderedBroadcast()) {
                abortBroadcast();
            }
        }
    }
}

3.利用空的Activity开启广播接收者

发送无序广播:

*广播消息接受没有优先级顺序,多个接收者同时接收广播消息.

*效率高. 不能拦截,不能修改

*无序广播使用context.sendBroadcast()方法来发送

实例: 自定义无序广播

1.创建一个Android项目,在MainActivity里面写发送的广播内容

Intent intent=new Intent();
//设置意图action
intent.setAction("com.yashiro.ccav");
//绑定数据
intent.putExtra("data","我是无序广播的数据");
//发送无序广播
sendBroadcast(intent);

2.创建一个广播接收者接收广播.

public class MyReceiver extends BroadcastReceiver{
    @override
    public void onReceive(Context context,Intent intent){
        System.out.println("哈哈哈,我们接收到了自定义的广播消息");
        System.out.println("消息原文:"+intent.getStringExtra("data"));
    }

}

3.在清单文件中进行注册操作

<receiver android:name="com.yashiro.MyReceiver">
    <intent-filter>
        <action android:name="com.yashiro.ccav"/>
    <intent-filter/>
<receiver/>

小结:

BroadcastReceiver 就是一个贴心的小伙伴,不管它有没有睡着,只要有事件在召唤他它随时会醒来完成它的使命!!!!

未完待续….

接下来会继续更新其他两种组件的特点, 不喜勿喷

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值