在 Android 应用中监测来电信息

本文讲的是在 Android 应用中监测来电信息,

目标

本文的主要目标是监测 Android 中的来电状态信息。

你想在你的 Android 应用中监测来电状态和来电号码么?

你在处理通话、摘机、空闲状态时无从下手么?

你想在收到来电、摘机(接听时的状态)或空闲(挂机状态)时做一些事情么?

我最近搞的一个大工程中必须要用到监测电话信息。

如果你想知道我如何实现的话,就继续读下去吧。.

即使应用关闭也可以监测来电信息

你知道么,即使你的 Android 应用是关闭状态,也可以在应用中取到来电信息的。

这很酷,是吧?现在让我们看看该 “怎么做” !

关键点在于 Receiver

你听说过 Android 里面的 receiver 么?

如果听说过的话,那么你会很容易的弄清楚手机状态这个概念的。

当然,没听说过也不要担心,我会告诉你 receiver 是什么以及如何在应用中使用它。

RECEIVER 到底是个什么鬼东西?

Broadcast receiver 帮助我们接收系统或其他应用的消息。

Broadcast receiver 响应来自系统本身或其他应用的广播信息(intent、event等)。

点击以下链接获取更多知识:

在我们的应用里创建一个 Broadcast Receiver 需要执行以下两步:

  1. 创建 Broadcast Receiver
  2. 注册 Broadcast Receiver

让我们先在 Android Studio 里建立一个带有空白 Activity 的简单工程。

如果你第一次接触 Android studio 不知道如何创建新工程的话,点击以下链接:

让我们创建并注册 BROADCAST RECEIVER

创建一个名为 PhoneStateReceiver 的 Java 类文件,并继承 BroadcastReceiver 类。

要注册 Broadcast Receiver的话,需要将以下代码写入 AndroidMainifest.xml 文件

<receiver android:name=".PhoneStateReceiver">
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE" />
    </intent-filter>
</receiver>

注意

你必须在 <application>标签内写这几行代码.

我们的主要目的是接收通话广播,所以我们需要将 android.intent.action.PHONE_STATE 作为 receiver 的 action。

你的 AndroidMainifest.xml 文件应该和下图一样:

Phone State Receiver

漂亮!我们成功的在项目中加入了一个 Broadcast Receiver。

你得到权限了么?

为了在应用中接收手机的通话状态广播,你需要取得对应的权限。

我们需要在 AndroidManifest.xml 文件中写入以下代码来获取权限。

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

现在你的 AndroidManifest.xml 应该和下面这张图一样了

Read Phone State

关于 onReceive() 方法的来龙去脉

现在让我们将目光转回到 继承了 BroadcastReceiver 的 PhoneStateListener 类中。

在这个类中我们需要重写 onReceive(Contex context, Intenet intent) 方法,因为在基类(BroadcastReceiver)中这个方法是抽象方法(abstract method)。

你对 onReceive() 方法了解多少呢?

如果我让你天马行空的想象一下这个方法的作用,你会怎么猜呢?

提示: 它的名字已经解释了一切。

加油……努力……你离答案只有一步之遥了……

是的,就是你猜的那样。onReceive() 使用 Intent 对象参数来接收每个消息。我们已经声明并在 AndroidManifest.xml 中注册了Broadcast Receiver。

现在,让我们将目光转向 PhoneStateReciver.java 文件来看看我们要在 onReceive() 方法中做些什么。

public void onReceive(Context context, Intent intent) {

    try {
        System.out.println("Receiver start");
        Toast.makeText(context," Receiver start ",Toast.LENGTH_SHORT).show();
    }
    catch (Exception e){
        e.printStackTrace();
    }

}

我们已经做了一堆准备工作了,你觉得我们现在是不是可以检测到通话状态了呢?

先自己想一想。

目前只要收到来电就会弹出一个显示 Receiver start 消息的 toast,我们也会在控制台中收到同样的消息,因为我们已经将其输出到控制台中。 Receiver Start

但……

我们无法得知准确的通话状态,我们的目标是取到如下的状态:

  • 响铃
  • 摘机
  • 空闲

保持冷静,继续探索手机状态

那我们要怎么做来取到电话状态信息呢? 你听说过 Android 里面的 Telephony Manager 么?

如果你对 Telephony Manager 不熟悉的话,别担心。我会教你什么是 Telephony Manager 以及如何用它取到通话状态的。

Telephony Manager 会将来自 Android 设备电话的全部状态信息告诉你。利用这些状态我们可以做许多事。

想了解更多关于 Telephony Manager 的知识,请点以下链接:

我们可以通过 TelephonyManager.EXTRA_STATE 来取得当前通话状态。它会用一个 String 对象来返回当前通话状态。

以如下方式新建一个 String 对象来获取不同的通话状态信息:

String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);

要获取不同的状态,我们可以用下面的代码达到目的:

if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){
    Toast.makeText(context,"Ringing State Number is -"+incomingNumber,Toast.LENGTH_SHORT).show();
}
if ((state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))){
    Toast.makeText(context,"Received State",Toast.LENGTH_SHORT).show();
}
if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){
    Toast.makeText(context,"Idle State",Toast.LENGTH_SHORT).show();
}

现在我们的 PhoneCallReceiver 类应该如下所示:

Broadcast Receiver

是的,我们成功了!!!

我们成功达到了目标,你可以用模拟器或真机来检验一下成果。

如果你不知道如何打开模拟器的话,按照下面的步骤来:

  1. 打开 Android studio
  2. 点击 Android Device Monitor。如果你找不到 Android Device Monitor 的话,看下面这张截图。

Android Device Moniter

下面这张图会显示如何操作模拟器

Emulator Control

如果你使用新版本的 Android Studio (2.1 +) 或者你有最新的 HAXM 那你要跟着下面这张图来

Phone Device

就酱。你可以用模拟器来监测通话状态了,下面的截图显示了运行结果。

结果 1. 来电状态

Incoming Call State

结果 2. 接听状态

Call Receiver State

结果 3. 空闲状态

Call Idle State

我们的主要目标就完成了。

需要来电号码?

你仔细看过 Telephony Manager 这个类么?

你看到 TelephonyManager.EXTRA_INCOMING_NUMBER 这个了么?

如果你已经了解了 TelephonyManager.EXTRA_INCOMING_NUMBER,那很好,证明你读过我在上面给的关于 Telephony Manager 类的链接了

TelephonyManager.EXTRA_INCOMING_NUMBER 用 String 的形式返回来电号码。

Extra State

String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

如果你想在自己的应用中监测来电号码,可以利用下面的代码:

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

        try {
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

            if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){

                Toast.makeText(context,"Ringing State Number is - " + incomingNumber, Toast.LENGTH_SHORT).show();
            }
        }
        catch (Exception e){
            e.printStackTrace();
        }

    }

啊哈!我们成功取到了来电号码!

但愿本篇博客在获取来电信息方面对你有所帮助。对于获取来电消息方面还有问题的话请留言,我会尽快回复的。

学习 Android 很棒,不是么?来看看其他的 Android 教程 吧。

有开发 Android 应用的灵感?还等什么,快 联系我们 ,灵感直播即将上线。我们的公司被提名为印度最好的 Android 应用开发公司 。





原文发布时间为:2016年11月06日

本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。
功能 1. 查询来电号码并显示悬浮窗,显示位置和其他号码信息。 2. 主界面显示最近来电列表(不会导入已有的系统通讯录)。 3. 在主界面可以查询任意电话号码信息。 4. 自定义设置卡片及悬浮窗的颜色。 5. 自定义悬浮窗, 如文字大小、透明度、位置。可以自定义显示与隐藏,如忽略已存在的联系人、去电时显示、接听后隐藏。 6. 离线查询。优先从本地的离线归属地及历史记录查询数据并显示,没有查询到标记数据且有网络(有 WIFI 或手机未掉网)时会联网查询。 隐藏功能 (点击七次版本后出现) 1. 自定义数据源。可以自定义百度、聚合数据(360)的 API 密钥,可以自定义 API (用于适配客户信息系统)。可以设置忽略号码段来忽略查询,可以强制使用本地离线数据。 插件功能(安装插件后出现) 1. 自动挂断。可以自动挂断匹配的标记关键字(诈骗、广告等)、归属地、起始号码(400*)。归属地可逆向匹配,如 "!西安 !咸阳" 将挂断所有除 "西安" "咸阳" 的来电。起始号码关键字添加完整号码并以空格分隔可以实现 "黑名单" 的功能。 2. 添加号码信息到系统通话记录。会添加诈骗、骚扰、广告、响一声、自动挂断等信息到系统通话记录。 说明 1. “来电信息” 的不断改进和完善离不开社区的反馈,非常感谢所有在 Play 市场、V站、酷市场留言及发送邮件反馈的朋友。 2. 应用开源免费无广告,请放心使用。APK 文件通过 Travis CI 自动生成并上传,用户可在每个 GitHub 版本发行 找到编译日志来校验文件 sha1 及 md5。 3. 请避免限制主应用及插件请求的权限。如出现来电时不显示悬浮窗,请先检查权限设置、权限管理类型应用的设置。如果安装了插件,请确保插件和主应用没有进入管理类软件的黑名单或优化项目。 4. 如果对此开源应用有任何不满、问题或建议,请在 GitHub 提交问题单或发送问题到作者邮件。非常欢迎大家反馈,来和作者一起完善这个应用。 5. 如果您觉得这个应用做的不错,欢迎在 GitHub star、在 Play 市场 及 酷市场 五星好评,欢迎您将此应用通过推特、微博、朋友圈等社交网络推广给更多的人。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值