在 Android 中实现通话录音

在 Android 中实现通话录音需要处理系统权限通话状态监听音频录制 等关键步骤。以下是详细实现代码及注释,注意不同 Android 版本和厂商设备的兼容性问题


1. 添加权限声明(AndroidManifest.xml)

复制代码
<!-- 录制音频权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 读取通话状态权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- Android 10+ 需要前台服务权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- 存储录音文件权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" 
                 android:maxSdkVersion="28" /> <!-- Android 9及以下需要 -->

2. 创建通话状态监听服务(Java 代码)

复制代码
import android.app.Service;
import android.content.Intent;
import android.media.MediaRecorder;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import java.io.IOException;

public class CallRecordingService extends Service {
    private static final String TAG = "CallRecording";
    private MediaRecorder mediaRecorder;
    private TelephonyManager telephonyManager;
    private PhoneStateListener phoneStateListener;

    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化电话状态监听
        telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        phoneStateListener = new PhoneStateListener() {
            @Override
            public void onCallStateChanged(int state, String phoneNumber) {
                switch (state) {
                    case TelephonyManager.CALL_STATE_OFFHOOK: // 通话开始
                        startRecording(phoneNumber);
                        break;
                    case TelephonyManager.CALL_STATE_IDLE:     // 通话结束
                        stopRecording();
                        break;
                    case TelephonyManager.CALL_STATE_RINGING:  // 来电响铃
                        // 可在此处处理来电号码
                        break;
                }
            }
        };
        // 注册监听器
        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    /**
     * 开始录音
     */
    private void startRecording(String phoneNumber) {
        try {
            mediaRecorder = new MediaRecorder();
            // 设置音频源(不同设备可能支持不同配置)
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL); // 需要系统权限
            // 部分设备需改用 MIC(但无法录制对方声音):
            // mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            
            // 输出格式
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            // 音频编码
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            // 保存路径(示例路径,需适配 Android 10+ 作用域存储)
            String filePath = getExternalFilesDir(null) + "/call_recording_" + System.currentTimeMillis() + ".3gp";
            mediaRecorder.setOutputFile(filePath);
            
            mediaRecorder.prepare();
            mediaRecorder.start();
            Log.d(TAG, "开始录音: " + filePath);
        } catch (IOException | IllegalStateException e) {
            Log.e(TAG, "录音失败: " + e.getMessage());
        }
    }

    /**
     * 停止录音
     */
    private void stopRecording() {
        if (mediaRecorder != null) {
            try {
                mediaRecorder.stop();
                mediaRecorder.reset();
                mediaRecorder.release();
                mediaRecorder = null;
                Log.d(TAG, "录音已停止");
            } catch (RuntimeException e) {
                Log.e(TAG, "停止录音异常: " + e.getMessage());
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // 注销监听器
        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
        stopRecording();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

3. 启动服务并检查权限(Activity 中调用)

复制代码
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

public class MainActivity extends AppCompatActivity {
    private static final int PERMISSION_REQUEST_CODE = 100;

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

        // 检查并请求权限
        if (checkPermissions()) {
            startCallRecordingService();
        }
    }

    private boolean checkPermissions() {
        String[] requiredPermissions = {
                Manifest.permission.RECORD_AUDIO,
                Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
        };
        for (String permission : requiredPermissions) {
            if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, requiredPermissions, PERMISSION_REQUEST_CODE);
                return false;
            }
        }
        return true;
    }

    private void startCallRecordingService() {
        Intent serviceIntent = new Intent(this, CallRecordingService.class);
        // Android 8+ 需使用前台服务
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(serviceIntent);
        } else {
            startService(serviceIntent);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                startCallRecordingService();
            }
        }
    }
}

关键问题与注意事项

  1. 音频源限制

    • VOICE_CALL 音频源需要系统级权限,普通应用无法使用。

    • 大部分设备使用 MIC 仅能录制本地麦克风声音(无法录制对方声音)。

  2. 厂商兼容性

    • 华为、小米等厂商可能屏蔽通话录音功能,需申请白名单或使用特殊 API。
  3. Android 版本适配

    • Android 9+ 禁止后台应用访问麦克风,需结合前台服务(Notification)实现。
  4. 法律与隐私

    • 通话录音需明确告知用户并取得同意(部分国家/地区要求双重确认)。

替代方案(推荐)

如果无法直接录制通话音频,可通过以下方式实现:

  1. 使用系统提供的通话录音接口 (如小米的 MiuiTelephony

  2. Root 设备后获取系统权限

  3. 接入第三方通话录音 SDK(如 Twilio、Agora)

建议根据实际需求选择合规方案。

相关推荐
我该如何取个名字3 分钟前
Mac配置Java的环境变量
java·开发语言·macos
kkkkatoq8 分钟前
Java中的锁
java·开发语言
郁大锤18 分钟前
Android Studio 国内镜像使用与 SDK 下载速度优化指南
android·ide·android studio
界面开发小八哥21 分钟前
「Java EE开发指南」用MyEclipse开发EJB 3无状态会话Bean(二)
java·ide·java-ee·eclipse·myeclipse
LCY13327 分钟前
spring security +kotlin 实现oauth2.0 认证
java·spring·kotlin
Evand J27 分钟前
【MATLAB例程】AOA定位、AOA与TOA混合定位,二维环境下的对比,基站(锚点数量)自适应调整,附代码下载链接
开发语言·matlab
soulermax29 分钟前
数字ic后端设计从入门到精通2(含fusion compiler, tcl教学)
java·linux·服务器
我的代码永没有bug35 分钟前
day1-小白学习JAVA---JDK安装和环境变量配置(mac版)
java·学习·macos
Thomas_YXQ38 分钟前
Unity3D ILRuntime与Scripting Backend整合指南
服务器·开发语言·unity·unity3d
Chandler2442 分钟前
Go:反射
开发语言·后端·golang