当前位置:首页 > 行业动态 > 正文

安卓开发 来电监控

来电监控核心实现步骤

权限申请

权限类型 权限名称 适用场景
危险权限 android.permission.READ_PHONE_STATE 监听电话状态
危险权限 android.permission.CALL_PHONE (可选) 需要主动处理通话时使用
普通权限 android.permission.READ_CALL_LOG (API >= 22) 获取通话记录(部分功能依赖)

动态权限申请流程

安卓开发 来电监控  第1张

// 检查权限
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限制。
  • 解决方案:
    1. 确保已动态申请并获取必要权限
    2. API >=22时优先使用PhoneStateListener获取号码
    3. 检查设备是否允许第三方应用访问通话信息(部分小米/华为设备需手动开启)

问题2:Android 8.0后台接收不到来电广播怎么办?

解答

  • 原因:Android 8.0限制后台应用注册广播接收器
  • 解决方法:
    1. 将接收器注册逻辑放在前台Service中
    2. 使用JobIntentService保持接收器活跃状态
    3. 引导用户将应用加入电池优化白名单
0