Android 简单异步处理类------实现声音的录制及播放

安卓 异步播放在线音乐和离线音乐 项目中需要用到把播放离线音乐设计成可以同时播放在线音乐和离线音乐的. onPrepareAsync 之前弄过,但是内部有很多错误, 所以一直使用onPrepare, 但是因为在网络差的环境中会阻塞线程, 痛定思痛花了心思研究了下,发现可以通过对播放错误进行处理, 结果完美解决.下面是一些代码总结和心得: 点击音乐的时候需要song的集合传入, 这样虽然会播放歌曲但是会打开一个播放队列, 点击随机播 阅读详情

在本例子中, 我们需要用继承一个类AsyncTask以实现后台运行的效果 。

它可以跟线程一样适用于简单的异步处理,而且不需要借助线程和Handler即可实现。

AsyncTask有以下几个可以实现的几个方法:

onPreExecute();

该方法在开始进行后台操作前会被UI thread调用, 我们可以在该方法上做些初始化工作。

doInBackground(params...) ;

该方法在onPreExcute方法后执行, 并且会运行在后台中, 主要实现一些耗时的工作, 并可以使用publishProgress方法来指示当前的进度。

onProgressUpdate();

在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。


onPostExecute(Result),

在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.

为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
  1) Task的实例必须在UI thread中创建
  2) execute方法必须在UI thread中调用
  3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
  4) 该task只能被执行一次,否则多次调用时将会出现异常
      doInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第第三个为doInBackground返回和onPostExecute传入的参数。

 

接下来我们需要在该类中实例化两个重要的对象, 一个是AudioRecord, 用于录制声音。 而另一个是AudioTrack, 用于对声音的播放。

 

代码如下:

所需权限

<uses-permission android:name="android.permission.RECORD_AUDIO"> </uses-permission>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

 

public class SpeechTestActivity extends Activity
{
	private Button mStartButton;
	private Button mStopButton;
	private Button mPlayButton;

	private boolean isRecording = true; // 录制状态
	private boolean isPlaying = false; // 播放状态
	private File audioFile; // 声音文件
	private RecordTask record; // 录制异步处理类
	private PlayTask player; // 播放异步处理类

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		// 我们需要用到开始、停止、播放三个按钮
		mStartButton = (Button) findViewById(R.id.btnStart);
		mStopButton = (Button) findViewById(R.id.btnStop);
		mPlayButton = (Button) findViewById(R.id.btnPlay);

		mStartButton.setOnClickListener(btnListener);
		mStopButton.setOnClickListener(btnListener);
		mPlayButton.setOnClickListener(btnListener);

		// 将缓存文件建立在SD卡根目录中, 用于储存记录的声音
		File fpath = new File("sdcard/");
		fpath.mkdirs(); // 创建一个目录

		try
		{
			// 创建文件
			audioFile = File.createTempFile("recording", ".pcm", fpath);
		} catch (Exception e)
		{
			String strMsg = e.getMessage();
			Log.i("i", strMsg);
		}
	}

	private Button.OnClickListener btnListener = new Button.OnClickListener()
	{
		@Override
		public void onClick(View v)
		{
			Button btn = (Button) v;
			switch (btn.getId())
			{
			case R.id.btnStart:
			{
				record = new RecordTask();
				record.execute();
			}
				break;
			case R.id.btnPlay:
			{
				player = new PlayTask();
				player.execute();
			}
				break;
			case R.id.btnStop:
			{
				isRecording = false;
			}
				break;
			default:
				break;
			}
		}

	};

	// 该异步处理实现类录音的实现
	public class RecordTask extends AsyncTask<Void, Integer, Void>
	{

		@Override
		protected Void doInBackground(Void... params)
		{
			isRecording = true;
			try
			{
				// 创建一个输入输出流
				DataOutputStream dos = new DataOutputStream(
						new BufferedOutputStream(
								new FileOutputStream(audioFile)));

				// 获取缓冲区大小
				// 录制频率Hz、录制通道、录制编码格式
				int bufferSize = AudioRecord.getMinBufferSize(8000,
						AudioFormat.CHANNEL_CONFIGURATION_MONO,
						AudioFormat.ENCODING_PCM_16BIT);

				// 实例化一个录制对象
				AudioRecord record = new AudioRecord(
						MediaRecorder.AudioSource.MIC, 8000,
						AudioFormat.CHANNEL_CONFIGURATION_MONO,
						AudioFormat.ENCODING_PCM_16BIT, bufferSize);

				// 缓冲区
				short[] buffer = new short[bufferSize];

				// 开始录制
				record.startRecording();

				int r = 0;
				while (isRecording)
				{
					// 读出数据
					int bufferReadResult = record
							.read(buffer, 0, buffer.length);
					for (int i = 0; i < bufferReadResult; i++)
					{
						// 写入流
						dos.writeShort(buffer[i]);
					}

					// 为显示进度使用
					publishProgress(new Integer(r));
					r++;
				}

				record.stop();
				dos.close();

			} catch (Exception e)
			{
				// TODO: handle exception
			}
			return null;
		}

		protected void onProgressUpdate(Integer... progress)
		{
			// stateView.setText(progress[0].toString());
		}
	}

	// 该异步处理实现类录音的播放
	class PlayTask extends AsyncTask<Void, Integer, Void>
	{

		@Override
		protected Void doInBackground(Void... params)
		{
			isPlaying = true;

			int bufferSize = AudioTrack.getMinBufferSize(8000,
					AudioFormat.CHANNEL_CONFIGURATION_MONO,
					AudioFormat.ENCODING_PCM_16BIT);

			// 缓冲区大小需要少于录制的大小
			short[] buffer = new short[bufferSize / 4];

			try
			{
				// 定义输入流,将音频写入到AudioTrack类中,实现播放
				DataInputStream dis = new DataInputStream(
						new BufferedInputStream(new FileInputStream(audioFile)));

				// 实例化一个播放对象
				AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC,
						8000, AudioFormat.CHANNEL_CONFIGURATION_MONO,
						AudioFormat.ENCODING_PCM_16BIT, bufferSize,
						AudioTrack.MODE_STREAM);

				// 开始播放
				track.play();

				// 由于AudioTrack播放的是流,所以,我们需要一边播放一边读取
				while (isPlaying && dis.available() > 0)
				{
					int i = 0;
					while (dis.available() > 0 && i < buffer.length)
					{
						buffer[i] = dis.readShort();
						i++;
					}
					// 然后将数据写入到AudioTrack中
					track.write(buffer, 0, buffer.length);
				}
				
				track.stop();
				dis.close();
			} catch (Exception e)
			{
				// TODO: handle exception
			}

			return null;
		}
	}
}


 

Android音乐播放器源码分析与实战 本文还有配套的精品资源,点击获取 简介:本资源提供了针对Android系统的音乐播放器实现源码,目的是为了提供一个无bug且界面美观的解决方案。通过分析源码,可以深入理解音乐播放器的工作原理和核心知识点,包括媒体框架的使用、MediaPlayer类的使用、文件选择与管理、线程与异步处理、音频效果和控制、UI设计、通知栏控制、生命周期管理、权限管理以及多媒体文件元数据的获取等... 阅读详情

相关推荐

Android音乐播放器源码深度解析与实战

在第一章中,我们将对Android音乐播放器的源码进行一个总体的介绍。我们先来了解播放器应用的核心组件以及它是如何与Android系统进行交互的。本章旨在为读者搭建一个宏观的理解框架,帮助读者在后续章节中深入研究每个模块的细节。音乐播放器常见的播放模式包括顺序播放、单曲循环、列表循环和随机播放等。每种播放模式都有其特定的应用场景和用户体验。播放模式描述顺序播放按照列表顺序依次播放单曲循环仅循环当前播放的单首歌曲列表循环对整个播放列表循环播放随机播放。

weixin_42453228的博客 769

Android多媒体功能开发(11)——使用AudioRecord类录制音频

使用AudioRecord录音的基本步骤是:确定录音参数、申请缓冲区、创建AudioRecord对象、开始录制、循环读取数据到缓冲区并处理数据、停止录制、释放资源。

nanoage的博客 8307

安卓后台定时拍照录像监控系统实战——支持自动录制3gp视频并保存

当你写出第一段能成功录制视频的代码时,可能会兴奋一阵子。但真正难的从来不是“怎么实现”,而是“要不要实现”。摄像头是一个极其敏感的权限。它可以用来保护家人安全,也可以沦为偷窥他人生活的工具。作为开发者,我们必须时刻提醒自己:我们是在构建守护,而不是制造恐惧。所以在每一行涉及摄像头访问的代码前,请多问一句:这个功能真的必要吗?用户能否轻松关闭它?数据是否得到了充分保护?只有当答案都是肯定的时候,才值得按下那个“开始录制”的按钮。

weixin_28988985的博客 967

java读写二进制文件

import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.*; public class TaskOne {

merry3602的个人家园 1288

PCM音频采集与异步播放SDK(解决阻塞问题)

该代码为SDK,包括音频采集与播放接口,解决了音频采集直接调用wave api导致应用直接阻塞问题,采用异步线程模式,解决回调函数中调用api阻塞问题;

基于Codex平台与AI Agent技能开发,实现抖音爆款视频分析与脚本自动生成

大家好,我是专注于AI应用开发的技术博主。最近在探索如何利用AI工具自动化内容创作时,我发现了一个非常有趣的组合:通过Codex平台创建自定义的Skill(技能),来批量分析抖音平台的爆款视频,并基于分析结果自动生成新的带货视频脚本。这听起来像是内容团队的“黑科技”,但实现起来其实有清晰的路径可循。本文将为你完整拆解这个实战项目,从环境搭建、Skill编写、数据抓取到视频脚本生成,手把手教你打造自己的“AI内容助理”。无论你是想了解AI Agent的开发,还是对短视频自动化创作感兴趣,都能从本文中获得可直接

weixin_34110749的博客 644

android音乐播放器+异步加载+缓存+图片加载+listview列表显示+tomcat服务器+xml解析...

最近在做一款播放器,服务器为tomcat,将音乐所有信息放在服务器端,客户端与服务器端之间的通信是同http协议进行的。首先把服务器端的数据部署完成,然后客户端 采用pull解析器将服务器端传过来的实体对象解析成music对象,再将需要显示的数据(包括文本和图片)利用自定义的适配器显示在listview上。现在,本人将文本通过异步加载的方式显示在listview上,而图片则通过线程+handle...

weixin_30247781的博客 290

WPS JS宏智能识别代码段并设置样式(完整可用版)

之前,我们已经经历了多次迭代,解决了许多问题,比如识别代码块、处理多行导入、调整样式等。现在他们需要一份全面的文档来解释整个代码的结构和工作原理。(5)智能行分析(含URL和注解检测优化)function analyzeLineEnhanced(rawText,trimmedText,codeSymbols,codePatterns, singleLinePatterns)该解决方案在保持高性能的同时,提供了良好的可扩展性,能够适应不同组织的代码规范需求,是WPS生态中专业文档处理的创新实践。

搏博的专栏 1822

android音乐播放器项目问题记录

做Android项目音乐播放器时的问题记录和解决

jacknoe的博客 1207

飞书+扣子+DeepSeek三件套:5分钟搞定公众号文章批量改写(附完整配置截图)

本文详细介绍了如何利用飞书、扣子和DeepSeek三款工具,无需编程即可搭建一个高效的公众号文章批量改写自动化工作流。通过飞书多维表格管理链接与成果,扣子平台串联整个流程,并调用DeepSeek智能体进行内容润色与改写,实现从内容抓取到智能处理的完整自动化,大幅提升新媒体运营效率。

python9snake的博客 208

深入傅里叶级数与傅里叶变换:从基础到应用

傅里叶分析为我们提供了一种理解信号频率结构的强大工具。从傅里叶级数到傅里叶变换,再到快速傅里叶变换(FFT),其理论与应用紧密结合,对现代科学技术的发展意义非凡。如果你对信号处理、数据分析或工程计算感兴趣,傅里叶分析是必须掌握的基础工具。希望本文能帮助你对傅里叶分析有更深入的理解!如果有问题或想法,欢迎在评论区讨论!

qq_56683019的博客 3522

android 后台录制视频,Android实现视频录制

目录效果展示视频录制视频播放实现步骤●实现自定义相机这里代码比较简单就不多解释了,另外自定义相机中实现了一个用于返回Camera和SurfaceHolder对象的VideoRecord接口,实现VideoRecord接口主要是MediaRecorder在视频录制时需要这两个对象,代码如下,另外相机代码就不贴了,可以在案例源码中查看。interface VideoRecord {/*** 返回相机对...

weixin_42521058的博客 3024

AI 模型训练核心方法论:零基础也能落地的 8 个关键阶段

本文是为 AI 零基础学习者打造的模型训练入门指南,以生活化语言拆解核心概念,规避专业术语壁垒。内容先通俗阐释模型训练、监督学习、数据集划分等基础概念,再按问题定义、数据准备、模型选择、环境搭建、训练、评估、调参、部署 8 个阶段,拆解完整训练流程,搭配 PyTorch 代码示例与实战案例,同时提供资源预算、常见问题解决方案及学习路径。指南强调数据的核心重要性,推荐新手优先使用迁移学习和免费 GPU 资源,兼顾理论与实操,帮助学习者快速上手,避开训练误区,独立完成从模型搭建到部署的全流程。

weixin_52741870的博客 469

Android音频系列(03)-音频播放录制应用开发

摘要:本文介绍了Android系统中音频播放和录制的实现方式。播放部分分为纯音频播放(使用AudioTrack处理PCM原始数据)和多媒体播放(使用MediaPlayer处理压缩格式);录制部分包括音频录制(使用AudioRecord获取PCM数据)和多媒体录制(使用MediaRecorder生成压缩文件)。文章通过代码示例展示了各API的基本使用方法,并指出MediaPlayer底层会调用AudioTrack进行音频输出。两种方案分别适用于低延迟场景和便捷的多媒体文件处理需求。

Minilinux2018的博客 1779

JMeter压力测试全攻略:从入门到精通

本文系统讲解JMeter压力测试的完整流程与结果评估方法。开篇介绍压力测试的核心概念及JMeter工具特性,随后从环境搭建入手,详细说明JDK配置、JMeter安装及中文界面设置。主体部分围绕测试流程展开,涵盖测试计划创建、线程组参数调优、HTTP请求配置、断言与监听器添加等实操步骤;结果评估环节深入解析聚合报告指标、结果树分析及性能瓶颈定位方法,并通过电商接口测试案例演示全流程应用。文末总结关键要点,为读者提供从基础操作到分布式压测、性能调优的进阶学习方向,助力掌握JMeter在系统性能评估中的核心应用。

邓邓子的博客 2416

【代码版本管理】SVN(Subversion)

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对SVN(Subversion)代码版本管理做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章提示:以下是本篇文章正文内容。

qq_35635374的博客 668

Android 音频录制 的三种方式

对于录制音频,Android系统就都自带了一个小小的应用,可是使用起来可能不是特别的灵活。所以有提供了另外的俩种。下边来介绍下这三种录制的方式;1、通过Intent调用系统的录音器功能,然后在录制完毕保存以后在onActivityResult中返回录制的音频的uri,然后通过Mediaplayer进行播放调用系统的录音器 private final static int REQUEST_RECOR...

whyqcwy的专栏 4417

UE5接入在线直播视频源,如hls(m3u8)格式

UE5接入在线直播视频源

专注GIS开发 9499

Android实现录音功能及播放语音功能(附带源码)

Android实现录音功能及播放语音功能(附带源码)

欢迎来到我的博客!这里是一个专注于计算机技术的分享平台,涵盖编程开发、算法研究、系统架构、软件工程等多个领域。无论你是初学者还是资深开发者,都能在这里找到有价值的内容。 2516

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Android多媒体开发:Coursera-android音频视频处理技巧

想要掌握Android多媒体开发的核心技术吗?Coursera-android项目提供了完整的音频视频处理示例,帮助开发者快速上手Android多媒体开发。本文分享10个实用的Android音频视频处理技巧,让你的应用拥有出色的多媒体体验!🎵📱 ## 音频管理技巧:精准控制音量与音效 Android的AudioManager是音频处理的核心组件,通过它你可以精确控制设备音量、管理音频焦点和

gitblog_00620的博客 545

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Android音频学习(三)——应用开发

/ 开始录制} catch (IOException e) { Log.e("Recorder", "Prepare failed: " + e.getMessage());两者的差别在于:MediaPlayer可以播放多种格式的音源,如MP3,flac、wma、ogg、MediaPlayer 可以播放多种格式的音源,如 mp3、flac、wma、ogg、wav 等,而 AudioTrack 只能播放解码后的 PCM 数据流。:低层API,直接播放PCM数据,支持实时音频流,延迟较低。

miemie2014的博客 1073

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

video-use实战:前端视频播放、截图、录制与上传的工程化封装

前端视频处理远不止在页面嵌入一个播放器,背后涉及播放器兼容性、Canvas截帧、MediaRecorder录制、分片上传与性能监控等复杂链路。HTML5 video 提供了基础能力,但浏览器差异与事件流的复杂性让业务代码难以维护。本文从视频播放器的状态管理出发,解析了截图跨域、录制编码、上传续传等核心技术原理,并展示了如何通过 video-use 这类工具层将能力沉淀为可复用模块,帮助视频网站、直播回放、课程平台等业务快速实现稳定可靠的视频体验,同时兼顾移动端兼容性与工程化落地。

weixin_29009081的博客 256

android 多媒体知识,Android 多媒体和相机详解一

Android 手机应用多媒体框架包含了获取和回放音频,视频和各种类形的图像的功能,所以你可以很容易的把它们整合到你的应用中.你可以从存储在资源中的文件,文件系统中的文件,或从网络数据流中播放音频或视频,这些都是用MediaPlayer或JetPlayerAPI实现手机APP .你也可以使用MediaRecorderand Camera API来录制声音,视频或抓取图片.下面的主题向你演示了如何使...

weixin_39849762的博客 269

【Android Dev Guide - 04】 - Media - 学习使用MediaPlayer播放音乐

内容文字太多,根据自己的理解做了一些简略的陈述,如果能自己对照看看官方英文原文,效果会好很多,翻译的不好,有很多不当的地方还望指正,谢谢!后面有时间将写一篇文章详细解释如何实现一个完整的音乐播放器 【0】The Android multimedia framework includes support for encoding and decoding a variety of comm

迁移到http://hukai.me 9601

android 多媒体和相机详解一

Android多媒体框架包含了获取和回放音频,视频和各种类形的图像的功能,所以你可以很容易的把它们整合到你的应用中.你可以从存储在资源中的文件,文件系统中的文件,或从网络数据流中播放音频或视频,这些都是用MediaPlayer或JetPlayerAPI实现.你也可以使用MediaRecorderand Camera API来录制声音,视频或抓取图片.  下面的主题向你演示了如何使用Android框

nkmnkm的专栏 7753

Android 音频开发(二):MediaPlayer 与 Media3 ExoPlayer 播放实战

本文是 Android 音频开发系列第二篇,通过实际 Kotlin Demo 对比 Android Framework MediaPlayer 与 Jetpack Media3 ExoPlayer 的使用方式。实现本地 MP3、HTTPS 网络音频播放,以及播放、暂停、停止、进度拖动、状态监听和异常处理,并分析 prepareAsync、播放器状态机、缓冲机制、生命周期与资源释放等常见问题。结合真实项目场景,介绍两种播放器的适用范围,为后续学习录音、音频焦点、编解码与 Android Framework 音

asd2278344的博客 431
上一篇: Android 使用摄像头。
下一篇: Android 获取联系人资料。
克雷斯
博客等级 码龄17年 36粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值