跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Android 电话操作指南:拨打、监听与拦截

Android 平台下电话功能的开发实现,涵盖拨打电话、监听通话状态、拦截呼出电话及自动挂断来电四大场景。内容包含 Intent 跳转机制、TelephonyManager 监听器使用、BroadcastReceiver 拦截逻辑以及 TelecomManager 挂断接口。同时强调了不同 Android 版本对权限的要求,特别是 Android 6.0+ 的运行时权限申请以及高版本对 PROCESS_OUTGOING_CALLS 的废弃说明,确保代码在现代环境下的兼容性与安全性。

二进制发布于 2025/2/7更新于 2026/7/2736 浏览
Android 电话操作指南:拨打、监听与拦截

Android 电话功能开发指南

在 Android 应用开发中,电话功能涉及拨打电话、监听通话状态、拦截呼出电话以及处理来电挂断等核心场景。由于涉及用户隐私和通信费用,相关 API 需要严格的权限声明和运行时授权。

1. 如何使用代码拨打电话

Android 提供了两种主要的拨打电话方式:

  1. 打开拨号界面:使用 Intent.ACTION_DIAL。用户确认后会显示号码并等待点击呼叫。此方式不需要 CALL_PHONE 权限。
  2. 直接拨打电话:使用 Intent.ACTION_CALL。程序直接发起呼叫,无需用户二次确认。此方式必须声明 android.permission.CALL_PHONE 权限。

代码示例

// 打开拨号界面(无需 CALL_PHONE 权限)
Intent intentDial = new Intent();
intentDial.setAction(Intent.ACTION_DIAL);
intentDial.setData(Uri.parse("tel:10086"));
startActivity(intentDial);

// 直接拨打电话(需 CALL_PHONE 权限)
Intent intentCall = new Intent();
intentCall.setAction(Intent.ACTION_CALL);
intentCall.setData(Uri.parse("tel:10086"));
startActivity(intentCall);

权限配置

在 AndroidManifest.xml 中添加权限:

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

注意:从 Android 6.0 (API 23) 开始,CALL_PHONE 属于危险权限,必须在运行时动态申请并获得用户授权后才能调用,否则会导致 SecurityException。

2. 如何监听电话状态

Android 提供了 TelephonyManager 类来管理电话服务,配合 PhoneStateListener 可以监听三种主要状态:

  • 空闲状态 (IDLE):无通话活动。
  • 振铃状态 (RINGING):有来电或正在拨出。
  • 摘机状态 (OFFHOOK):通话正在进行中。

实现步骤

  1. 创建继承自 PhoneStateListener 的类。
  2. 重写 onCallStateChanged 方法处理状态变化。
  3. 获取 TelephonyManager 实例并注册监听器。
  4. 在适当时机取消监听以避免内存泄漏。

代码示例

public class MainActivity extends AppCompatActivity {
    private TelephonyManager telephonyManager;
    private MyPhoneStateListener listener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 获取电话管理器
        telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        
        // 创建监听器
        listener = new MyPhoneStateListener();
        
        // 开启监听(需 READ_PHONE_STATE 权限)
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
            telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
        }
    }

    // 电话状态监听器
    class MyPhoneStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    Log.i("Telephony", "CALL_STATE_IDLE: 空闲");
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    Log.i("Telephony", "CALL_STATE_OFFHOOK: 通话中");
                    break;
                case TelephonyManager.CALL_STATE_RINGING:
                    Log.i("Telephony", "CALL_STATE_RINGING: 振铃,号码:" + incomingNumber);
                    break;
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 取消监听
        if (telephonyManager != null && listener != null) {
            telephonyManager.listen(listener, PhoneStateListener.LISTEN_NONE);
        }
    }
}

权限配置

需要在清单文件中声明以下权限:

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

同样,READ_PHONE_STATE 也需要在运行时动态申请。

3. 如何拦截呼出电话

通过广播接收器监听系统发出的呼出电话广播,可以在特定条件下阻止呼叫。

实现逻辑

  1. 注册 BroadcastReceiver 监听 Intent.ACTION_NEW_OUTGOING_CALL。
  2. 在 onReceive 中获取目标号码。
  3. 根据业务逻辑决定是否中断呼叫(设置结果为 null)。

代码示例

public class MainActivity extends AppCompatActivity {
    private MyPhoneReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 注册广播接收器
        receiver = new MyPhoneReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);
        registerReceiver(receiver, filter);
    }

    // 拦截呼出电话的 Receiver
    class MyPhoneReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String number = getResultData();
            Log.i("MyPhoneReceiver", "Outgoing call to: " + number);
            
            // 示例:拦截拨打 10086
            if (number != null && number.equals("10086")) {
                setResultData(null); // 阻止拨出
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 取消注册广播接收器
        if (receiver != null) {
            unregisterReceiver(receiver);
        }
    }
}

权限配置

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

注意:从 Android 9 (API 28) 开始,PROCESS_OUTGOING_CALLS 已被废弃,且普通应用无法再拦截所有呼出电话。此功能通常仅适用于默认电话应用或系统级应用。现代开发建议使用 Telecom API 进行更合规的管理。

4. 如何自动挂断来电

对于特定的来电,可以使用 TelecomManager 提供的接口在响铃阶段自动挂断。

代码示例

if (incomingNumber.equals("10086")) {
    TelecomManager tm = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
    if (tm != null) {
        tm.endCall();
    }
}

权限与版本要求

  • 需要添加权限:android.permission.ANSWER_PHONE_CALLS
  • 该 API 仅在 Android 8.0 (API 28) 及以上版本可用。

5. 最佳实践与注意事项

  1. 生命周期管理:务必在 onDestroy 或 onPause 中取消电话监听器和广播接收器,防止内存泄漏。
  2. 权限检查:始终在调用敏感 API 前检查运行时权限,避免崩溃。
  3. 兼容性:部分电话相关 API 随 Android 版本迭代发生变化,开发时需查阅对应版本的官方文档。
  4. 用户体验:拦截或自动挂断电话应谨慎使用,避免影响正常通信体验。

通过以上方法,开发者可以在 Android 应用中安全、有效地实现电话相关的核心功能。

目录

  1. Android 电话功能开发指南
  2. 1. 如何使用代码拨打电话
  3. 代码示例
  4. 权限配置
  5. 2. 如何监听电话状态
  6. 实现步骤
  7. 代码示例
  8. 权限配置
  9. 3. 如何拦截呼出电话
  10. 实现逻辑
  11. 代码示例
  12. 权限配置
  13. 4. 如何自动挂断来电
  14. 代码示例
  15. 权限与版本要求
  16. 5. 最佳实践与注意事项
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • OpenClaw 架构解析:构建可落地的个人 AI Agent 操作系统
  • Mac 系统 nvm 安装后命令未找到问题排查与.zshrc 配置
  • 2025 年十大开源 RISC-V 处理器项目盘点
  • C++26 反射即将落地:GCC 14 最新进展与迁移路线图
  • HomeAssistant 接入石头扫地机器人配置实战
  • Ollama 下载模型太慢?试试国内 HuggingFace 镜像与 LLama-Factory 组合
  • 海光 DCU K100_AI 环境部署 Ollama 与 DeepSeek
  • 基于Python+OpenCV实现自动扫雷
  • VSCode Copilot 接入智谱 GLM-4.6 实战指南
  • C++ 入门基础:历史、命名空间与输入输出详解
  • SpringBoot 核心模块 Java 源码规模统计
  • 10 种专业渗透测试工具详解
  • DeepSeek 本地部署最简教程:基于 Ollama 的 GUI 交互方案
  • MixAIHub:ChatGPT、Claude 等主流 AI 平台镜像访问入口
  • 2024 年 GraphRAG 代表性工作调研与总结分析
  • UV 国内源配置指南:PyPI 与解释器加速实战
  • 飞书 OpenClaw 机器人配置指南:插件与独立桥接方案
  • Midjourney AI 图像生成器使用教程详解
  • Z-Image-Turbo WebUI 本地部署指南:环境配置与启动流程
  • OpenClaw 免费 AI 大模型及配置方法

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online