上一篇
安卓开发 来电监控
- 行业动态
- 2025-04-21
- 2732
来电监控核心实现步骤
权限申请
权限类型 | 权限名称 | 适用场景 |
---|---|---|
危险权限 | android.permission.READ_PHONE_STATE | 监听电话状态 |
危险权限 | android.permission.CALL_PHONE (可选) | 需要主动处理通话时使用 |
普通权限 | android.permission.READ_CALL_LOG (API >= 22) | 获取通话记录(部分功能依赖) |
动态权限申请流程:
// 检查权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, REQUEST_CODE); }
BroadcastReceiver监听来电
// 动态注册接收器(需在Activity或Service生命周期内) private void registerPhoneStateReceiver() { IntentFilter filter = new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED); phoneStateReceiver = new PhoneStateReceiver(); registerReceiver(phoneStateReceiver, filter); } // 接收器实现 public class PhoneStateReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); if (TelephonyManager.EXTRA_STATE_RINGING.equals(state)) { // 处理来电逻辑 } } }
通过TelephonyManager获取信息
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); String incomingNumber = tm.getLine1Number(); // 需API >= 22且已获取READ_CALL_LOG权限
使用PhoneStateListener(推荐方式)
private void listenPhoneState() { TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); tm.listen(new PhoneStateListener() { @Override public void onCallStateChanged(int state, String phoneNumber) { switch (state) { case TelephonyManager.CALL_STATE_RINGING: // 来电处理 break; case TelephonyManager.CALL_STATE_OFFHOOK: case TelephonyManager.CALL_STATE_IDLE: // 通话结束/空闲状态 break; } } }, PhoneStateListener.LISTEN_CALL_STATE); }
处理来电(需谨慎)
// 接听来电(需ITelephony接口) private void answerCall() { try { Class<?> clazz = Class.forName("android.os.ServiceManager"); Method method = clazz.getMethod("getService", String.class); IBinder binder = (IBinder) method.invoke(null, "telephony.registry"); ITelephony telephony = ITelephony.Stub.asInterface(binder); telephony.answerRingingCall(); // 接听电话 } catch (Exception e) { e.printStackTrace(); } }
关键适配问题
Android版本 | 主要限制 | 解决方案 |
---|---|---|
Android 6.0+ | 动态权限机制 | 运行时申请敏感权限 |
Android 8.0+ | 后台执行限制 | 使用前台Service注册接收器 |
API 22+ | 读取通话信息受限 | 改用PhoneStateListener或获取READ_CALL_LOG权限 |
Android 10+ | 隐私限制加强 | 使用系统级API或引导用户手动授权 |
常见问题与解答
问题1:为什么无法获取到来电号码?
解答:
- 可能原因:未获取
READ_PHONE_STATE
权限 / API >=22时缺少READ_CALL_LOG
权限 / 部分厂商ROM限制。 - 解决方案:
- 确保已动态申请并获取必要权限
- API >=22时优先使用
PhoneStateListener
获取号码 - 检查设备是否允许第三方应用访问通话信息(部分小米/华为设备需手动开启)
问题2:Android 8.0后台接收不到来电广播怎么办?
解答:
- 原因:Android 8.0限制后台应用注册广播接收器
- 解决方法:
- 将接收器注册逻辑放在前台Service中
- 使用JobIntentService保持接收器活跃状态
- 引导用户将应用加入电池优化白名单