一、Android广播机制介绍

广播机制最大的特点就是发送方并不关心接收方是否接到数据,也不关心接收方是如何处理数据的。

Android中广播的是操作系统中产生的各种各样的事件。例如,收到一条短信就会产生一个收到短信息的事件。而Android操作系统一旦内部产生了这些事件,就会向所有的广播接收器对象来广播这些事件。

BraodcastReceiver(广播接收器)是为了实现系统广播而提供的一种组件,并且广播事件处理机制是系统级别的。比如,我们可以发出一种广播来测试是否收到短信,这时候就可以定义一个BraodcastReceiver来接受广播,当收到短信时提示用户。我们既可以用Intent来启动一个组件,也可以用sendBroadcast()方法发起一个系统级别的事件广播来传递消息。

我们也可以在自己的应用程序中开发BroadcastReceiver,然后把广播接收器这个类或者对象注册到Android操作系统上去,让操作系统知道现在有这样一个广播接收器正在等待接收Android操作系统的广播,即在自己的应用程序中实现BroadcastReceiver来监听和响应广播的Intent。

当有广播事件产生时,Android操作系统首先告诉注册到其上面的广播接收器产生了一个怎么样的事件,每个接收器首先判断是不是我这个接收器需要的事件,如果是它所需要的事件,再进行相应的处理。

例子,我们把骚扰电话的黑名单放到数据库中去,当接到电话时会产生一个接电话事件,事先在Android操作系统中注册一个BroadcastReceiver的对象,当产生事件的时候,会通知我们的广播接收器对象,接收器对象接收到消息之后,就会到数据库里面去取所有黑名单电话和接到的这个电话号码进行比较,如果匹配就直接挂掉。

二、注册BroadcastReceiver的方法

BroadcastReceiver用于监听被广播的事件(Intent),为了达到这个目的,BroadcastReceiver必须进行注册,注册的方法有以下两种:

1.静态注册

静态注册方式是在AndroidManifest.xml的application里面定义receiver并设置要接收的action。

静态注册方式的特点:不管改应用程序是否处于活动状态,都会进行监听。

[html] view plain copy

  1. <receiver android:name="MyReceiver">
  2. <intent-filter>
  3. <action android:name="MyReceiver_Action"/>
  4. </intent-filter>
  5. </receiver>

其中,MyReceiver为继承BroadcastReceiver的类,重写了onReceiver方法,并在onReceiver方法中对广播进行处理。<intent-filter>标签设置过滤器,接收指定action广播。

2.动态注册

动态注册方式在activity里面调用函数来注册,和静态的内容差不多。一个形参是receiver,另一个是IntentFilter,其中里面是要接收的action。

动态注册方式特点:在代码中进行注册后,当应用程序关闭后,就不再进行监听。

[java] view plain copy

  1. MyReceiver receiver = new MyReceiver();
  2. //创建过滤器,并指定action,使之用于接收同action的广播
  3. IntentFilter filter = new IntentFilter("MyReceiver_Action");
  4. //注册广播接收器
  5. registerReceiver(receiver, filter);

三、发送广播

[java] view plain copy

  1. // 指定广播目标Action
  2. Intent intent = new Intent("MyReceiver_Action");
  3. // 可通过Intent携带消息
  4. intent.putExtra("msg", "发送广播");
  5. // 发送广播消息
  6. sendBroadcast(intent);

四、注销BroadcastReceiver

[java] view plain copy

  1. //注销广播接收器
  2. unregisterReceiver(receiver);

注:

1.一般在onStart中注册BroadcastReceiver,在onStop中取消BroadcastReceiver。

2.一个BroadcastReceiver 对象只有在被调用onReceive(Context, Intent)时才有效,当从该函数返回后,该对象就无效的了,结束生命周期。

注意事项:

谷歌修改了8.0的广播机制之后,那么静态注册的自定义有序广播相当于功能是废掉了,因为它不会按照优先级继续向下传递,
而是在第一次发送有序广播的时候就需要指定组件名,并且之后不会自动的向下传递,只能在之后的广播接收者当中
再次使用发送有序广播的方式,相当于是废掉了

=========================================

demo

广播者: app

package com.glsite.myapplication;import android.content.ComponentName;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void click(View vaiew) {Toast.makeText(this,"被点击了", Toast.LENGTH_SHORT).show();Intent intent = new Intent();intent.setAction("com.alsite.ccav.XXMLZY");intent.putExtra("money","wumao");//要兼容8.0以上的手机系统需要多这么一步intent.setComponent(new ComponentName("com.glsite.wumaodae","com.glsite.wumaodae.MyReceiver"));sendBroadcast(intent);}
}

接收者:app

新建:BroadcastReceiver

package com.glsite.wumaodae;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;public class MyReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context,"wozaixuex", Toast.LENGTH_SHORT).show();String money = intent.getStringExtra("money");System.out.println("wo li dao le :"+money);}
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.glsite.wumaodae"><applicationandroid: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"><receiverandroid:name=".MyReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.alsite.ccav.XXMLZY"/></intent-filter></receiver><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

===================================================

拨打电话拦截app

在APP中保存区号,拨打电话时在电话前加上区号;

1.运行时权限

BaseActivity.java

package com.glsite.ipcall;import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;/*** @author Admin* @version $Rev$* @des ${TODO}* @updateAuthor $Author$* @updateDes ${TODO}*/
public class BaseActivity extends AppCompatActivity {//**************** Android M Permission (Android 6.0权限控制代码封装)private int permissionRequestCode = 88;private PermissionCallback permissionRunnable;public interface PermissionCallback {void hasPermission();void noPermission();}/*** Android M运行时权限请求封装** @param permissionDes 权限描述* @param runnable      请求权限回调* @param permissions   请求的权限(数组类型),直接从Manifest中读取相应的值,比如Manifest.permission.WRITE_CONTACTS*/public void performCodeWithPermission(@NonNull String permissionDes, PermissionCallback runnable, @NonNull String... permissions) {if (permissions == null || permissions.length == 0)return;//        this.permissionrequestCode = requestCode;this.permissionRunnable = runnable;if ((Build.VERSION.SDK_INT < Build.VERSION_CODES.M) || checkPermissionGranted(permissions)) {if (permissionRunnable != null) {permissionRunnable.hasPermission();permissionRunnable = null;}} else {//permission has not been granted.requestPermission(permissionDes, permissionRequestCode, permissions);}}private boolean checkPermissionGranted(String[] permissions) {boolean flag = true;for (String p : permissions) {if (ActivityCompat.checkSelfPermission(this, p) != PackageManager.PERMISSION_GRANTED) {flag = false;break;}}return flag;}private void requestPermission(String permissionDes, final int requestCode, final String[] permissions) {if (shouldShowRequestPermissionRationale(permissions)) {/*1. 第一次请求权限时,用户拒绝了,下一次:shouldShowRequestPermissionRationale()  返回 true,应该显示一些为什么需要这个权限的说明2.第二次请求权限时,用户拒绝了,并选择了“不在提醒”的选项时:shouldShowRequestPermissionRationale()  返回 false3. 设备的策略禁止当前应用获取这个权限的授权:shouldShowRequestPermissionRationale()  返回 false*/// Provide an additional rationale to the user if the permission was not granted// and the user would benefit from additional context for the use of the permission.// For example, if the request has been denied previously.//            Snackbar.make(getWindow().getDecorView(), requestName,//                    Snackbar.LENGTH_INDEFINITE)//                    .setAction(R.string.common_ok, new View.OnClickListener() {//                        @Override//                        public void onClick(View view) {//                            ActivityCompat.requestPermissions(BaseAppCompatActivity.this,//                                    permissions,//                                    requestCode);//                        }//                    })//                    .show();//如果用户之前拒绝过此权限,再提示一次准备授权相关权限new AlertDialog.Builder(this).setTitle("提示").setMessage(permissionDes).setPositiveButton("授权", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {ActivityCompat.requestPermissions(BaseActivity.this, permissions, requestCode);}}).show();} else {// Contact permissions have not been granted yet. Request them directly.ActivityCompat.requestPermissions(BaseActivity.this, permissions, requestCode);}}private boolean shouldShowRequestPermissionRationale(String[] permissions) {boolean flag = false;for (String p : permissions) {if (ActivityCompat.shouldShowRequestPermissionRationale(this, p)) {flag = true;break;}}return flag;}/*** Callback received when a permissions request has been completed.*/@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {if (requestCode == permissionRequestCode) {if (verifyPermissions(grantResults)) {if (permissionRunnable != null) {permissionRunnable.hasPermission();permissionRunnable = null;}} else {Toast.makeText(this, "暂无权限执行相关操作!", Toast.LENGTH_SHORT).show();if (permissionRunnable != null) {permissionRunnable.noPermission();permissionRunnable = null;}}} else {super.onRequestPermissionsResult(requestCode, permissions, grantResults);}}public boolean verifyPermissions(int[] grantResults) {// At least one result must be checked.if (grantResults.length < 1) {return false;}// Verify that each required permission has been granted, otherwise return false.for (int result : grantResults) {if (result != PackageManager.PERMISSION_GRANTED) {return false;}}return true;}//********************** END Android M Permission ****************************************
}

2.OutCallReceiver.java

接收广播,将区号与手机号拼接后重新写入

package com.glsite.ipcall;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;public class OutCallReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String number = getResultData();// 获取当前的结果数据,数据就是外拨的电话号码SharedPreferences sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);setResultData(sp.getString("ipnumber", "") + number);}
}

3.MainActivity

保存区号

package com.glsite.ipcall;import android.Manifest;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;public class MainActivity extends BaseActivity {private EditText mEtIpNumber;private SharedPreferences mSp;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);performCodeWithPermission("往外拨打电话获取权限", new PermissionCallback() {@Overridepublic void hasPermission() {mEtIpNumber = findViewById(R.id.et_ipnumber);mSp = getSharedPreferences("config", MODE_PRIVATE);String ipnumber = mSp.getString("ipnumber", "");mEtIpNumber.setText(ipnumber);}@Overridepublic void noPermission() {}}, Manifest.permission.PROCESS_OUTGOING_CALLS);}public void save(View view) {String ipnumber =  mEtIpNumber.getText().toString().trim();SharedPreferences.Editor editor = mSp.edit();editor.putString("ipnumber", ipnumber);editor.commit();Toast.makeText(this,"保存成功", Toast.LENGTH_SHORT).show();}
}

AndroidManifest.xml

拨打电话的运行时权限: <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />

拦截拨打电话的action: <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.glsite.ipcall"><uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /><applicationandroid: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"><receiverandroid:name=".OutCallReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="android.intent.action.NEW_OUTGOING_CALL"/></intent-filter></receiver><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

广播接收者android,电话拦截广播,电话接收者demo相关推荐

  1. Android开发——短信电话拦截/接听电话

    1.短信拦截 首先需要声明的是,Android4.4版本以上,如果想做到短信拦截,必须成为default sms,把所有短信相关的功能都包揽了,然后再做短信拦截.但这种做法,适配性和兼容性的工作是非常 ...

  2. 电话拦截以及电话拦截后的提示音

    1. 电话拦截 这个功能大家可能都知道了,就是利用反射原理调用ITelephony的隐藏方法来实现.这个就不说了,在附件的代码里有. 2.拦截后提示忙音/空号/已关机/已停机 这个功能其实是要用到MM ...

  3. 简述在android中如何发送广播消息,Android Intent发送广播消息实例详解

    Android Intent发送广播消息 Intent的另一种用途是发送广播消息,应用程序和Android系统都可以使用Intent发送广播消息,广播消息的内容是可以与应用程序密切相关的数据信息,也可 ...

  4. android中的广播大全,android中的广播

    1系统广播(关闭,锁并,声音,电话,信号,等系统提供的广播)(例如信号) 广播一般是在一个类中直接写出来而不用这样单独写出到一个类中,这样方便在监听到结果时处理数据 import android.co ...

  5. android广播示例,android接受开机广播事件

    [实例简介] [实例截图] [核心代码] package com.yin.servicetest; import com.yin.service.MyService; import android.a ...

  6. android 无法接收广播_别告诉我你不认识Android中广播接收者(二)

    前面我们了解了什么是广播接收者与广播接收者的创建,这一次我们要接着继续去了解广播接收者的相关知识,这些知识包括广播接收者的注册.自定义广播与广播的类型. 当我们学习完广播接收者之后,该如何才能让它起到 ...

  7. 在android中监听呼出电话(电话拦截、修改呼出电话)

    2019独角兽企业重金招聘Python工程师标准>>> 在android中向外拨打电话时系统会发出一个有序广播,虽然该广播最终会被拔号器里的广播接收者所接收并实现电话拔打,但我们可以 ...

  8. android 修改呼出号码,在android中监听呼出电话(电话拦截、修改呼出电话)

    在android中向外拨打电话时系统会发出一个有序广播,虽然该广播最终会被拔号器里的广播接收者所接收并实现电话拔打,但我们可以在广播传递给拔号广播接收者之前先得到该广播,然后清除传递给拔号广播接收者的 ...

  9. android电话、短信黑白名单拦截、电话录音

    功能描述: 总的来说这是一个防骚扰的应用,设置黑名单,白名单,通话录音名单.添加到黑名单的联系人或号码将被拒绝来电或短信:添加到白名单的联系人或号码将通过来电或短信(除白名单以外的号码将被拒绝来电或短 ...

最新文章

  1. The specified child already has a parent. You must call removeView() on the
  2. java 注解开发_Java中的注解到底是如何工作的?
  3. 判断 std map 中是否有 key
  4. 【RecyclerView】 八、RecyclerView.ItemDecoration 条目装饰 ( onDraw 和 onDrawOver 绘制要点 )
  5. Python类的部分
  6. ORACLE的索引和约束详解
  7. 路由器无线桥接 router wireless bridge
  8. 手机工商银行怎么转账_工商银行信用卡要哪些申请条件?想成功办理你需要了解这些!...
  9. C#多线程学习(一) 多线程的相关概念
  10. 如何提升软件交付效能?答案未必如你所想
  11. 发现VB6中SAX的乐趣[转]
  12. maven本地安装jar
  13. python数据分析之(4)读写数据文件CSV,EXCEL等
  14. 批处理一键创建局域网共享文件夹或文件共享轻松访问Win系统其他电脑的共享文件命令行(纯bat代码)实用便携~
  15. 【电源芯片】TPS63020升降压芯片-电池放电
  16. android基带版本,Android - 基带版本为未知时自动隐藏
  17. 碱性溶液中HER动力学分析
  18. 使用C#编写17种Hello World程序(初学者C#测试石)
  19. Python Boss
  20. Markdown-img使用指南

热门文章

  1. 参加博客大赛,多谢大家支持
  2. 无线时代来临,谁来管理我的无线AP?
  3. 强大的DataGrid组件[12]_分组(Group)——Silverlight学习笔记[20]
  4. Microsoft Visual Studio Ultimate 2013密钥
  5. DWR第五篇之文件上传
  6. (转)配置Website的IIS时遇到的问题与解决方法
  7. 使用generator自动生成Mybatis映射配置文件
  8. 航空8联货运单的作用详解
  9. poj题目分类(转)--方便分类做题
  10. 写了个散列算法... 用来获取字符串的哈希. 超高效.10亿以下几乎无碰撞.