如何通过Intent选取歌曲播放?出现MediaPlayer错误该如何解决?
问题原因分析
E/MediaPlayerNative: start called in state 4, mPlayer(0xb400007abddc1780)
error (-38, 0)
E/MediaPlayerNative: error (1, -2147483648)
E/MediaPlayer: Error (-38,0)
E/MediaPlayer: Error (1,-2147483648)
- 路径获取错误:通过
ACTION_GET_CONTENT拿到的是content://类型的Uri,直接调用getPath()得到的不是本地文件的真实路径,MediaPlayer无法解析该路径,触发错误码(1,-2147483648)。 - 异步准备逻辑错误:
prepareAsync()是异步执行方法,调用后不会立刻完成播放器准备,代码中调用完直接执行start(),此时播放器处于PREPARING状态(状态4),非法调用start()触发错误码(-38,0)。 - 播放器状态管理混乱:每次点击播放都会重复调用
setDataSource(),调用前没有执行reset()重置播放器状态,多次调用会导致状态异常。 - 缺少资源释放逻辑:页面销毁时没有释放MediaPlayer资源,可能造成内存泄漏。
修复代码
public class MainActivity extends AppCompatActivity { boolean songExists = false; Uri songData; private MediaPlayer mediaplayer = new MediaPlayer(); private Handler handler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 新增播放器准备完成监听,准备完成后再执行播放逻辑 mediaplayer.setOnPreparedListener(mp -> { if (!mp.isPlaying()) { mp.start(); } }); } public void addSong(View v){ Intent intent = new Intent(); intent.setType("audio/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent,1); } public void playSong(View v) { if (songExists) { if (mediaplayer.isPlaying()){ mediaplayer.pause(); } else if (mediaplayer.getDuration() > 0) { // 已完成过准备,直接播放 mediaplayer.start(); } else { // 首次播放触发准备逻辑 prepareMediaPlayer(); } } } private void prepareMediaPlayer(){ try { // 重置播放器状态,避免多次设置数据源报错 mediaplayer.reset(); // 直接传入Context和Uri,适配content类型的资源地址 mediaplayer.setDataSource(this, songData); mediaplayer.prepareAsync(); } catch (Exception exception) { Toast.makeText(this, exception.getMessage(), Toast.LENGTH_SHORT).show(); } } @Override protected void onActivityResult(int requestCode,int resultCode,Intent data){ if(requestCode == 1){ if(resultCode == RESULT_OK) { Toast.makeText(getApplicationContext(),"Selected",Toast.LENGTH_LONG).show(); songData = data.getData(); songExists = true; } } super.onActivityResult(requestCode, resultCode, data); } // 页面销毁时释放MediaPlayer资源 @Override protected void onDestroy() { super.onDestroy(); if (mediaplayer != null) { mediaplayer.release(); mediaplayer = null; } } }
内容的提问来源于stack exchange,提问作者User Name
相关产品推荐
相关产品推荐

