在 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();
}
}
}
}
关键问题与注意事项
-
音频源限制
-
VOICE_CALL
音频源需要系统级权限,普通应用无法使用。 -
大部分设备使用
MIC
仅能录制本地麦克风声音(无法录制对方声音)。
-
-
厂商兼容性
-
华为、小米等厂商可能屏蔽通话录音功能,需申请白名单或使用特殊 API。
-
-
Android 版本适配
-
Android 9+ 禁止后台应用访问麦克风,需结合前台服务(Notification)实现。
-
-
法律与隐私
-
通话录音需明确告知用户并取得同意(部分国家/地区要求双重确认)。
-
替代方案(推荐)
如果无法直接录制通话音频,可通过以下方式实现:
-
使用系统提供的通话录音接口(如小米的
MiuiTelephony
) -
Root 设备后获取系统权限
-
接入第三方通话录音 SDK(如 Twilio、Agora)
建议根据实际需求选择合规方案。