Android语言基础教程(192)Android多媒体应用播放音频与视频范例之带音量控制的音乐播放器:别再静音人生!手把手教你打造会“呼吸”的BGM播放器,网友:这代码会蹦迪!
你的App还在当“哑巴”吗?本篇深度解剖Android多媒体实战,用爆笑段子+保姆级代码,教你打造带音量滑杆的音乐播放器。从MediaPlayer的“职场生存指南”到SeekBar的“丝滑操控术”,连音频焦点争夺这种“宫斗戏”都安排得明明白白!附完整可跑源码,避开35个新手必踩的坑,保证让你的播放器不仅能唱歌,还会根据场景自动“情商调整”!技术宅和萌新都能秒变BGM魔法师~
作为一个常年和Android“斗智斗勇”的老码农,我见过太多播放器:有的点开就静音到让人怀疑人生,有的突然外放吓得同事摔了键盘……今天咱们就撸个带智商+情商的音乐播放器,重点解决两大灵魂拷问:“声儿呢?!” 和**“太吵了闭嘴!”**。
一、MediaPlayer:它可不是个“傻白甜”
别看MediaPlayer只是个类,人家内心戏多着呢!新手常把它当MP3点击器,结果分分钟表演“闪退三连”:
val mediaPlayer = MediaPlayer().apply {
setDataSource("你的音频路径") // 路径一错,立刻扑街!
prepare() // 纯真版:在主线程调?系统反手一个ANR警告!
start() // 最怕此时手机响起微信电话…音乐秒变BGM伴奏
}
高级玩法:给它穿上“防弹衣”!
- 用
prepareAsync()异步准备——相当于让播放器自己蹲角落加载,不堵UI线程; - 状态监听连环套:
mediaPlayer.setOnPreparedListener {
// 此时才能安全点击播放,别像急着拆快递把盒子撕烂了
btn_play.isEnabled = true
}
mediaPlayer.setOnCompletionListener {
// 循环播放?在这偷偷调mediaPlayer.seekTo(0)就行
}
二、音量控制:SeekBar的“丝滑魔术”
为什么你的音量拖拽像卡了痰?因为缺了进度反馈闭环!记住这个公式:
// ① 初始化音量滑杆(0f-1f范围)
val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
seekBar_volume.max = 100
seekBar_volume.progress = (currentVolume.toFloat() / maxVolume * 100).toInt()
// ② 拖拽时实时调节(这才是灵魂!)
seekBar_volume.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
if (fromUser) {
val volume = progress / 100.0f
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, (volume * maxVolume).toInt(), 0)
// 第三个flag:0表示安静调整,AudioManager.FLAG_PLAY_SOUND会作死地播放调节音效…
}
}
})
三、音频焦点争夺战:比抢车位还刺激!
你的App放音乐时突然来了电话?没处理音频焦点的话,就会变成**“音乐+铃声”双重奏**!学学高情商播放器:
val audioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run {
setOnAudioFocusChangeListener { focusChange ->
when (focusChange) {
AudioManager.AUDIOFOCUS_LOSS -> mediaPlayer.pause() // 别人霸占车位,咱先熄火
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> mediaPlayer.pause() // 临时被抢,比如导航说话
AudioManager.AUDIOFOCUS_GAIN -> mediaPlayer.start() // 重新抢回方向盘!
}
}
build()
}
// 申请焦点!没这步就像没驾照开车
audioManager.requestAudioFocus(audioFocusRequest)
四、完整代码:会“蹦迪”的播放器长这样!
(Activity完整版,粘贴即用)
class MainActivity : AppCompatActivity() {
private lateinit var mediaPlayer: MediaPlayer
private lateinit var audioManager: AudioManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 初始化管理器
audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
setupMediaPlayer()
setupVolumeSeekBar()
}
private fun setupMediaPlayer() {
mediaPlayer = MediaPlayer.create(this, R.raw.your_music) // 资源文件扔进res/raw/
btn_play.setOnClickListener {
if (!mediaPlayer.isPlaying) {
mediaPlayer.start()
btn_play.text = "暂停"
} else {
mediaPlayer.pause()
btn_play.text = "播放"
}
}
}
private fun setupVolumeSeekBar() {
val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
seekBar_volume.max = 100
seekBar_volume.progress = (currentVolume.toFloat() / maxVolume * 100).toInt()
seekBar_volume.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
if (fromUser) {
audioManager.setStreamVolume(
AudioManager.STREAM_MUSIC,
(progress / 100.0f * maxVolume).toInt(), 0
)
}
}
// 必须重写但用不到的方法…(假装这里有空实现)
})
}
override fun onDestroy() {
mediaPlayer.release() // 别忘了!否则下次打开播放器会变“哑巴”
super.onDestroy()
}
}
五、踩坑预警:血泪总结3条保命技巧
- 资源释放是爸爸:MediaPlayer用完必须
release(),否则内存泄漏多来几次,App直接表演“原地去世”; - 生命周期要偷窥:App退到后台记得暂停,监听到
onPause()时就该让播放器“眯一会儿”; - 异常处理不能浪:
IllegalStateException是MediaPlayer的祖传大招,所有操作都得包在try-catch里。
现在运行你的播放器——拖动滑杆时,是不是终于有了“掌控全局”的爽感?这不仅是技术实现,更是和Android系统的一场深度对话。当你理解音频焦点、系统服务协作时,你的代码就真正“活”过来了。
彩蛋:想让播放器更智能?试试在音频焦点丢失时自动淡出音量,恢复时再淡入,用户体验直接封神!(提示:用ObjectAnimator操作音量值+Handler延时)
总结:从“哑巴应用”到“智能DJ”,只需搞定MediaPlayer的状态机管理、SeekBar的实时反馈机制、音频焦点的场景化协作。你的代码不止能跑,还能带着节奏跑!
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)