一、前言

最近写一个Android项目,想使用AudioRecord录制手机内部声音,但是调用开始录音的方法startRecording()时,总是遇到这个错误:

startRecording() called on an uninitialized AudioRecord.

在此总结一下。

二、分析

1.百度发现,报这个错可能是AudioRecord没有初始化(没有new)。正确写法可以这样写:

private AudioRecord mRecord = null;
private final int kFrameSize = 2048;
private final int kSampleRate = 44100;
private final int kChannelMode = AudioFormat.CHANNEL_IN_STEREO;
private final int kEncodeFormat = AudioFormat.ENCODING_PCM_16BIT;//标志位,通过修改这个,决定录音是否停止
public boolean mReqStop = true;public void recordAndPlay(File f) {//修改标志位,开始录音mReqStop = false;FileOutputStream os = null;if(mRecord == null) {int minBufferSize = AudioRecord.getMinBufferSize(kSampleRate, kChannelMode, kEncodeFormat);mRecord = new AudioRecord(MediaRecorder.AudioSource.REMOTE_SUBMIX, kSampleRate, kChannelMode, kEncodeFormat, minBufferSize * 2);//mRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, kSampleRate, kChannelMode, kEncodeFormat, minBufferSize * 2);}try {mRecord.startRecording();}catch (Exception e){Log.e("错误!",e.getMessage());return;}try {os = new FileOutputStream(f);byte[] buffer = new byte[kFrameSize];int num = 0;while (!mReqStop) {num = mRecord.read(buffer, 0, kFrameSize);os.write(buffer, 0, num);}os.close();} catch (IOException e) {Log.e("IO错误!",e.getMessage());}mRecord.stop();mRecord.release();mRecord = null;}

这个方法可以开始录音,保存为pcm文件。
这个方法已经确实把AudioRecord初始化了,但是还是会报错

2.继续百度,发现没有权限也会报这个错,需要在AndroidManifest.xml增加权限

<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" />  <uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/>  <uses-permission android:name="android.permission.RECORD_AUDIO" />  <uses-sdk  android:minSdkVersion="19"  android:targetSdkVersion="19" />  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

3.为了保险,又在Android代码中增加了申请权限的方法

    @SuppressLint("NewApi")private boolean checkAudio2(){if (checkSelfPermission(Manifest.permission.CAPTURE_AUDIO_OUTPUT) == PackageManager.PERMISSION_GRANTED){return true;}else{return false;}}@SuppressLint("NewApi")private void requestAudio2Permission() {if (!checkAudio2()) {requestPermissions(new String[]{Manifest.permission.CAPTURE_AUDIO_OUTPUT}, 0);} else {}}

然后给录音按钮增加了个功能,点击按钮时,调用requestAudio2Permission()方法,应该就出现申请权限的对话框才对,但是点击后没有反应

3.继续百度发现,MediaRecorder.AudioSource.REMOTE_SUBMIX功能只有系统应用才能使用,不开放给其它应用。
因此按照教程,把apk重新签名为系统应用。

(1)在AndroidManifest.xml文件的application标签中,增加配置:android:sharedUserId="android.uid.system"

(2)打release包,然后使用signapk.jar重新签名为系统应用。

●signapk.jar下载地址:

https://gitee.com/code_to_success/signapk.git

其中包含了platform.x509.pem与platform.pk8这2个文件。

●可以把自己打的release包改名为test.apk,然后执行下面的命令:

java -jar signapk.jar platform.x509.pem platform.pk8 ./test.apk final.apk

需要把相关文件放在命令中对应的路径下,然后生成的final.apk就是有系统签名的apk了。

备注:
那2个文件可以从android官网下载,platform.x509.pem和platform.pk8在Android源码的build/target/product/security目录下。
signapk.jar可以从https://code.google.com/p/signapk/下载。

注意这种方法录音时扬声器不能输出。

(3)安装apk测试,发现没有用,还是报错
不知道是不是由于platform.x509.pem和platform.pk8不是最新版的问题。

4.经过多次测试,使用MediaRecorder.AudioSource.MIC、申请
Manifest.permission.RECORD_AUDIO权限后,是可以正常使用手机录音功能的,不过录制的是麦克风;
而使用MediaRecorder.AudioSource.REMOTE_SUBMIX,无法申请Manifest.permission.CAPTURE_AUDIO_OUTPUT权限、并且无法录音,报错:startRecording() called on an uninitialized AudioRecord

5.所以最后暂时没有实现录制手机内部声音的功能,改为了使用MIC参数、录制麦克风的声音。

三、总结

●AudioRecord报错startRecording() called on an uninitialized AudioRecord,可能是没有初始化AudioRecord没有申请权限使用REMOTE_SUBMIX等不开放给非系统应用的参数导致的。
●目前暂时没有解决REMOTE_SUBMIX无法使用、无法录制手机内部声音的问题。
待后续研究。

四、后记

2021.9.26
1.关于录制手机内部声音问题
现在是android11版本,第三方软件实现手机内录功能比较困难,因此还是使用系统自带的录屏软件->选择录制内部声音,然后使用视频音频提取APP,提取录屏视频中的音频为mp3的方式好些。

相关网址:
https://zhidao.baidu.com/question/396545963009870525.html
https://www.zhihu.com/question/265086051

2.关于AudioRecord使用的参数
可以使用以下参数:

//声音来源等参数
Audio Source: MIC
Sample rate: 16000
Number of channels: CHANNEL_CONFIGURATION_MONO
Format: ENCODING_PCM_16BIT
Buffer size: 16000 * 30 (30 second buffer)//Java中写法
AudioRecord mRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,16000,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT,16000*30);

AudioRecord报错startRecording() called on an uninitialized AudioRecord.总结相关推荐

  1. conda tensorflow_TensorFlow笔记1——补充附录(1) 机器学习相关库安装、使用中遇到的报错情况...

    本文内容汇总 Anaconda(python3.7)和原生python3.7安装tensorflow 警告 AVX2 FMA 报错 'tensorflow' has no attribute 'xxx ...

  2. 【Tensorflow】报错:FailedPreconditionError: Attempting to use uninitialized value keep_prob_7

    问题描述: 定义了一个变量: keep_prob = tf.Variable(1.0 , name='keep_prob') 尝试打印它的值: print(sess.run(keep_prob)) 报 ...

  3. 从零开始在ubuntu上安装和使用k8s集群及报错解决

    文章目录 安装docker 安装kubernetes 配置k8s集群 配置虚拟机网络 配置Master节点的k8s网络 拉取k8s需要的镜像 启动 kubeadm 和 kubelet 配置 node节 ...

  4. Tensorflow运行程序报错 FailedPreconditionError

    1 FailedPreconditionError错误现象 在运行tensorflow时出现报错,报错语句如下: FailedPreconditionError (see above for trac ...

  5. kibana常见启动报错

    环境 :Ubuntu16.04 报错1.连接elasticsearch,kibana启动报错 报错信息 : Status changed from uninitialized to green - R ...

  6. bdd 启动 data processing进程报错 Can't locate LWP.pm in @INC

    bdd 启动 data processing进程报错 Can't locate LWP.pm in @INC Can't locate LWP.pm in @INC (@INC contains: / ...

  7. redis.clients java_redis报错redis/clients/jedis/JedisPoolConfig'(curren

    redis + Jedis + Spring报错Type 'redis/clients/jedis/JedisPoolConfig'(current frame, stack[4]) is not a ...

  8. 【ELK报错】Alias [.kibana] has more than one indices associated with it [[.kibana_1, .kibana_2]]

    错误复现 搭建1套新的ELK环境,将之前旧的ES的索引文件data/nodes/0/indices/全部复制到新的ES中.期间不要停止ES.然后kibana就无法访问了,重启kibana报错如下: l ...

  9. 为什么我的程序debug版本运行没有问题,而release版本总是报错?

    To   楼主   ,我在另外一个类似的贴子作了回答     http://expert.csdn.net/Expert/topic/2955/2955693.xml?temp=.3361933   ...

最新文章

  1. linux安全狗 nginx,linux 下 safedog 防护 Nginx
  2. hdu 1003 Max Sum
  3. jcache_窥探JCache API(JSR 107)
  4. Python爬虫十六式 - 第三式:Requests的用法
  5. allegro放置器件无法放_洗衣机放卫生间,这几种赶紧学起
  6. Android-Splash
  7. NULL指针的奇妙之旅
  8. Astar寻路教程!
  9. 数据分析sql面试必会6题经典_经典SQL面试题及答案分析
  10. Android实现AirPlay,DriodAirPlay开发
  11. 图像加密技术综述(常见的图像加密算法简介)
  12. 肠道微生物群:环境污染物毒性的重要参与者?
  13. 世界五大黑客:代码创造他们,他们改变世界!
  14. 经典Bug永流传---每周一“虫”(二十一)
  15. 服务器修改不了分辨率,ubuntu不能设置高分辨率问题的解决方法
  16. docker MySQL8
  17. python爬取所有页url_Python 如何爬取相同url下,多个页面的链接内容
  18. [SHELL]: ln 命令详解
  19. 一个普通玩家眼中的网博会
  20. VUE 学习之parent 选项

热门文章

  1. java邮件模板_java创建邮件模板
  2. Android 集成 zxing
  3. 求知讲堂Java视频 128天完整版 学完可就业
  4. 在idea中鼠标光标变成了小手
  5. iOS QQ第三方登录
  6. 软考-中级-网络工程师-笔记-第7章-下一代互联网IPv6
  7. 【技术贴】note8 N5100刷机 双清 落雨
  8. 四款最火在线作业APP深度测评
  9. 率土之滨鸿蒙团,关于率土之滨几个顶级大盟的实力分析
  10. 今天,你薅支付宝羊毛了么?