Android 电话功能开发指南
在 Android 应用开发中,电话功能涉及拨打电话、监听通话状态、拦截呼出电话以及处理来电挂断等核心场景。由于涉及用户隐私和通信费用,相关 API 需要严格的权限声明和运行时授权。
Android 平台下电话功能的开发实现,涵盖拨打电话、监听通话状态、拦截呼出电话及自动挂断来电四大场景。内容包含 Intent 跳转机制、TelephonyManager 监听器使用、BroadcastReceiver 拦截逻辑以及 TelecomManager 挂断接口。同时强调了不同 Android 版本对权限的要求,特别是 Android 6.0+ 的运行时权限申请以及高版本对 PROCESS_OUTGOING_CALLS 的废弃说明,确保代码在现代环境下的兼容性与安全性。

在 Android 应用开发中,电话功能涉及拨打电话、监听通话状态、拦截呼出电话以及处理来电挂断等核心场景。由于涉及用户隐私和通信费用,相关 API 需要严格的权限声明和运行时授权。
Android 提供了两种主要的拨打电话方式:
Intent.ACTION_DIAL。用户确认后会显示号码并等待点击呼叫。此方式不需要 CALL_PHONE 权限。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。
Android 提供了 TelephonyManager 类来管理电话服务,配合 PhoneStateListener 可以监听三种主要状态:
PhoneStateListener 的类。onCallStateChanged 方法处理状态变化。TelephonyManager 实例并注册监听器。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 也需要在运行时动态申请。
通过广播接收器监听系统发出的呼出电话广播,可以在特定条件下阻止呼叫。
BroadcastReceiver 监听 Intent.ACTION_NEW_OUTGOING_CALL。onReceive 中获取目标号码。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 进行更合规的管理。
对于特定的来电,可以使用 TelecomManager 提供的接口在响铃阶段自动挂断。
if (incomingNumber.equals("10086")) {
TelecomManager tm = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
if (tm != null) {
tm.endCall();
}
}
android.permission.ANSWER_PHONE_CALLSonDestroy 或 onPause 中取消电话监听器和广播接收器,防止内存泄漏。通过以上方法,开发者可以在 Android 应用中安全、有效地实现电话相关的核心功能。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online