Android Studio中如何实现音频播放并设置循环播放
Android Studio 实现音频播放与循环播放的实操方案
核心实现方式(分两种常用场景)
长音频播放(背景音乐、录音、长音效等,推荐用MediaPlayer)
- 前期准备
把需要播放的音频文件(支持mp3、wav、ogg等主流格式)放到项目res/raw目录下(没有该目录就手动新建),注意音频文件名必须全小写、不能包含中文、空格和特殊字符,否则R文件无法生成对应资源ID。 - 基础播放代码实现(Kotlin示例)
// 声明MediaPlayer实例 private lateinit var mediaPlayer: MediaPlayer override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 初始化加载raw目录下的音频,create方法会自动完成prepare流程,无需手动调用 mediaPlayer = MediaPlayer.create(this, R.raw.your_audio_name) } // 开始播放 private fun startPlay() { if (!mediaPlayer.isPlaying) { mediaPlayer.start() } } // 暂停播放 private fun pausePlay() { if (mediaPlayer.isPlaying) { mediaPlayer.pause() } } // 停止并重置播放 private fun stopPlay() { mediaPlayer.stop() mediaPlayer.prepare() // stop后必须重新prepare才能再次start mediaPlayer.seekTo(0) }- 循环播放设置
两种方式可按需选择:
- 直接开启系统自带循环属性:在初始化完成后设置
mediaPlayer.isLooping = true,适合对循环衔接缝隙要求不高的场景 - 监听播放完成手动重启:如果自带循环有明显缝隙,可以通过播放完成回调实现无缝衔接:
mediaPlayer.setOnCompletionListener { mp -> mp.seekTo(0) mp.start() }
- 高频踩坑点(绝大多数人调试失败的核心原因)
- 忘记释放资源:必须在页面销毁的生命周期里释放MediaPlayer,否则会出现内存泄漏、后续播放无声音、程序崩溃等问题:
override fun onDestroy() { super.onDestroy() if (this::mediaPlayer.isInitialized) { mediaPlayer.release() } } - 权限缺失:如果播放的是手机外部存储里的音频,Android 12及以下需要申请
READ_EXTERNAL_STORAGE运行时权限,Android 13及以上需要申请READ_MEDIA_AUDIO运行时权限,未授权状态下无法读取音频文件。 - 重复调用prepare:用
MediaPlayer.create()加载资源时已经自动完成prepare流程,重复调用prepare会直接抛异常。 - 大文件主线程加载:如果是播放几MB以上的网络音频或者本地大文件,不要在主线程调用
prepare(),要用prepareAsync()异步准备,等setOnPreparedListener回调触发后再调用start,否则会触发ANR。
- 前期准备
短音频播放(按钮音效、游戏提示音等10s以内的高频触发音频,推荐用SoundPool)
- 基础实现与循环设置代码
private var soundPool: SoundPool? = null private var soundId: Int = 0 private var playStreamId: Int = 0 private fun initShortAudio() { // 初始化音频配置 val audioAttributes = AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_MEDIA) .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .build() soundPool = SoundPool.Builder() .setMaxStreams(3) // 支持同时播放的最大音频流数量 .setAudioAttributes(audioAttributes) .build() // 加载音频资源 soundId = soundPool?.load(this, R.raw.short_btn_sound, 1) ?: 0 } // 播放并设置循环:play方法第5个参数传-1为无限循环,传0为不循环,传正整数为对应循环次数 private fun playLoopShortAudio() { playStreamId = soundPool?.play(soundId, 1f, 1f, 1, -1, 1f) ?: 0 } // 停止循环播放 private fun stopShortAudio() { soundPool?.stop(playStreamId) } override fun onDestroy() { super.onDestroy() soundPool?.release() soundPool = null }
Stack Overflow 提问难通过审核的核心原因
- 问题不符合站点定位:Stack Overflow主站仅接收具体编程实操类、有明确解决方案、可复现、能对其他开发者产生参考价值的问题,求学习资料、作业代写、软件安装基础教程、宽泛的行业讨论类问题都会被直接打回。
- 问题信息不足无法定位:比如只说“音频播放实现失败”,但不贴报错日志、不贴自己写的核心代码、不说明测试设备版本、使用的API版本,审核者和社区用户根本无法判断问题原因,这类问题会被判定为低质量内容拦截。
- 重复提问:如果所提问题已经在站点内有成熟的高赞答案,系统会自动标记为重复问题,不进入公开队列。
- 格式与规范问题:代码没有用代码块排版、标题表意模糊(比如写“求大佬救急”“程序崩了”这类无意义标题)、标签错配、内容排版混乱,都会被要求修改后重新提交。
- 账号权重问题:新注册账号初始权重低,发布的内容会先进入严格的人工审核队列,如果前几次提问质量差被打回,后续账号的审核阈值会更高,更容易被拦截。
- 语言问题:Stack Overflow主站是英文社区,提交中文等非英文内容会被直接判定为不符合规范打回。
内容的提问来源于stack exchange,提问作者Badr_ G9mer
相关产品推荐
相关产品推荐

