Service中MediaPlayer已启动但无法播放音乐的问题求助
音乐服务启动但无法播放的排查与解决
1. 验证文件存在性与权限
先查看代码中Log.d("file exist", "file is------${musicFile.exists()}")的输出:
- 如果输出为
false:确认song.mp3是否放在系统公共Downloads目录下;Android 10+受Scoped Storage限制,公共目录访问需适配,Android 11及以上需申请MANAGE_EXTERNAL_STORAGE权限(或改用MediaStore获取文件Uri)。 - 如果输出为
true:检查Manifest中是否添加了<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>,并完成动态权限申请(Android 6.0+)。
2. 排查MediaPlayer初始化异常
当前仅用e.printStackTrace()捕获异常,Logcat中可能无法清晰看到错误细节,建议修改为:
catch (e:Exception){ Log.e("MediaPlayerInitError", "初始化MediaPlayer失败", e) }
通过日志可定位具体问题,比如文件格式不支持、文件损坏、权限不足等。
3. 修正MediaPlayer状态判断逻辑
playMusic()中的状态判断不够严谨,若MediaPlayer初始化失败或未准备完成,start()不会执行,修改为:
private fun playMusic(){ if (mediaPlayer != null && !mediaPlayer.isPlaying && mediaPlayer.isPrepared) { mediaPlayer.start() } }
4. 添加音频焦点申请
Android系统播放音频需获取音频焦点,否则可能被系统拦截,在playMusic()中添加焦点请求:
private fun playMusic(){ val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager val focusResult = audioManager.requestAudioFocus( null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN ) if (focusResult == AudioManager.AUDIOFOCUS_REQUEST_GRANTED && mediaPlayer != null && !mediaPlayer.isPlaying && mediaPlayer.isPrepared) { mediaPlayer.start() } }
5. 优化MediaPlayer初始化方式
同步prepare()会阻塞线程,大文件可能导致Service初始化延迟甚至ANR,改用异步准备:
private fun prepareMediaPlayer(){ val folder= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) val musicName="song.mp3" val musicFile=File(folder,musicName) Log.d("file exist","file is------${musicFile.exists()}") mediaPlayer= MediaPlayer() try { mediaPlayer?.setDataSource(musicFile.absolutePath) mediaPlayer?.isLooping=true mediaPlayer?.setOnPreparedListener { mp -> // 准备完成后可标记状态,或按需启动 } mediaPlayer?.prepareAsync() // 异步准备避免阻塞 } catch (e:Exception){ Log.e("MediaPlayerInitError", "初始化失败", e) mediaPlayer?.release() // 失败后释放资源 mediaPlayer = null } }
内容的提问来源于stack exchange,提问作者Sumita Das
相关产品推荐
相关产品推荐

