当前位置: 首页 > article >正文

android 自定义通话录音

在 Android 开发中,实现通话录音功能通常涉及到对系统通话的拦截和录音。由于通话录音涉及到用户隐私和安全性,Android 系统对此有严格的限制和要求。在 Android 10(API 级别 29)及以上版本中,直接访问通话录音功能变得更为复杂,因为 Google 引入了运行时权限和更严格的隐私政策。

方案一:使用系统内置功能

如果你的应用目标是 Android 10 以下版本,你可以使用 TelephonyManager 的 addProximityListener 方法来监听通话状态,并结合 AudioRecord 类来录制音频。例如:

import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.content.Context;
 
public class CallRecorder {
    private AudioRecord audioRecord;
    private boolean isRecording = false;
    private Thread recordingThread;
    private static final int SAMPLE_RATE = 44100;
    private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;
    private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
 
    private void startRecording() {
        int minBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT);
        audioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_CALL, SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT, minBufferSize * 10);
        audioRecord.startRecording();
        isRecording = true;
        recordingThread = new Thread(() -> {
            byte[] buffer = new byte[minBufferSize];
            while (isRecording) {
                audioRecord.read(buffer, 0, buffer.length);
                // 处理录音数据,例如写入文件等
            }
        });
        recordingThread.start();
    }
 
    private void stopRecording() {
        if (isRecording) {
            isRecording = false;
            audioRecord.stop();
            audioRecord.release();
            recordingThread.interrupt();
        }
    }
}

方案二:使用 Android 10+ 的权限和 API 变更

在 Android 10 及更高版本中,你需要动态请求 RECORD_AUDIO 和 FOREGROUND_SERVICE 权限,并且使用前台服务来进行录音,以符合 Google 的隐私政策。你可以使用 MediaProjection API 来捕获音频流。例如:

import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.content.Intent;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.io.*;
import android.media.*;
import androidx.annotation.*;
 
public class MainActivity extends AppCompatActivity {
    private MediaProjectionManager mProjectionManager;
    private MediaProjection mMediaProjection;
    private AudioFormat mAudioFormat;
    private AudioTrack mAudioTrack;
    private ExecutorService mExecutor = Executors.newSingleThreadExecutor();
    private static final int REQUEST_CODE = 1000; // 请求代码,自定义即可
    private ActivityResultLauncher<Intent> requestPermissionLauncher; // 处理权限请求的Launcher对象。
    private static final String[] REQUIRED_PERMISSIONS = new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.FOREGROUND_SERVICE}; // 需要的权限数组。
    private boolean hasPermissions = false; // 标记是否拥有所有权限。默认为false。表示不拥有权限。
    private boolean isScreenCapturing = false; // 表示是否正在进行屏幕捕获。默认为false。表示不进行屏幕捕获。默认为false。表示不进行屏幕捕获。默认为false。表示不进行屏幕捕获。默认为false。表示不进行屏幕捕获。默认为false。表示不进行屏幕捕获。默认为false。表示不进行屏幕捕获。默认为


http://www.kler.cn/a/534592.html

相关文章:

  • DeepSeek各版本说明与优缺点分析
  • 6 [新一代Github投毒针对网络安全人员钓鱼]
  • js的 encodeURI() encodeURIComponent() decodeURI() decodeURIComponent() 笔记250205
  • vue2-为啥data属性是一个函数而不是对象
  • DeepSeek:全栈开发者视角下的AI革命者
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.22 形状操控者:转置与轴交换的奥秘
  • 【PostgreSQL内核学习 —— (WindowAgg(二))】
  • Docker 国内最新可用镜像源20250205
  • Solidity08 Solidity 函数
  • 机器学习8-卷积和卷积核1
  • 【AI 语音】实时语音交互优化全解析:从 RTC 技术到双讲处理
  • Java常见的技术场景面试题
  • python-leetcode-岛屿数量
  • 设备通过国标GB28181接入EasyCVR,显示在线但视频无法播放的原因排查
  • Racecar Gym
  • 【B站保姆级视频教程:Jetson配置YOLOv11环境(七)Ultralytics YOLOv11配置】
  • .NET 中实现生产者-消费者模型,BlockingCollection<T> 和 Channel<T>使用示例
  • 大模型Dense、MoE 与 Hybrid-MoE 架构的比较
  • 从java角度对比nodejs、fastapi,同步和异步区别
  • 【hot100】073矩阵置零
  • FFmpeg 头文件完美翻译之 libavfilter 模块
  • 怎么实现AI思考过程
  • 【前端】【Ts】TypeScript的关键知识点
  • css小知识
  • Windows图形界面(GUI)-QT-C/C++ - QT Dock Widget
  • 【12】深入理解Golang值传递与引用传递:避坑指南与性能优化