You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中如何实现音频播放并设置循环播放

Android Studio 实现音频播放与循环播放的实操方案

核心实现方式(分两种常用场景)

  • 长音频播放(背景音乐、录音、长音效等,推荐用MediaPlayer)

    1. 前期准备
      把需要播放的音频文件(支持mp3、wav、ogg等主流格式)放到项目res/raw目录下(没有该目录就手动新建),注意音频文件名必须全小写、不能包含中文、空格和特殊字符,否则R文件无法生成对应资源ID。
    2. 基础播放代码实现(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)
    }
    
    1. 循环播放设置
      两种方式可按需选择:
    • 直接开启系统自带循环属性:在初始化完成后设置mediaPlayer.isLooping = true,适合对循环衔接缝隙要求不高的场景
    • 监听播放完成手动重启:如果自带循环有明显缝隙,可以通过播放完成回调实现无缝衔接:
      mediaPlayer.setOnCompletionListener { mp ->
          mp.seekTo(0)
          mp.start()
      }
      
    1. 高频踩坑点(绝大多数人调试失败的核心原因)
    • 忘记释放资源:必须在页面销毁的生命周期里释放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)

    1. 基础实现与循环设置代码
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 20:06:40