今天编写自己的播放器时总是报了下面的错误,
而求错误指向mediaplayer.setDataSource()这个一行。
我反复看了很久也没觉得有什么错误,甚至利用Toast查看了SP的信息,发现确实是正确的文件路径,所以肯定不是路径的问题,后来去网上查了很多资料,各种各样但都没有效果,没办法接着分析自己写的代码逻辑,仔细看了看MainActivity中的iniMediaPlayer()方法,觉得很有问题,下面贴代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private MediaPlayer mediaPlayer = new MediaPlayer(); public List musicList = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button play = (Button)findViewById(R.id.play); Button stop = (Button)findViewById(R.id.stop); Button pause = (Button)findViewById(R.id.pause); ListView listView = (ListView)findViewById(R.id.list_view); play.setOnClickListener(this); stop.setOnClickListener(this); pause.setOnClickListener(this); if (Environment.getExternalStorageDirectory().listFiles(new MusicFilter()).length > 0){ for (File file : Environment.getExternalStorageDirectory().listFiles(new MusicFilter())) { musicList.add(file.getAbsolutePath().substring(20)); } } ArrayAdapter adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, musicList); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { String SD = "/storage/emulated/0/"; String path = musicList.get(i).toString(); String SP = SD + path; Toast.makeText(MainActivity.this,SP,Toast.LENGTH_SHORT).show(); try { mediaPlayer.setDataSource(SP); mediaPlayer.prepare(); mediaPlayer.start(); } catch (IOException e) { e.printStackTrace(); } } }); if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE },1); }else{ initMediaPlayer(); } } @Override public void onClick(View view) { switch (view.getId()){ case R.id.play: if (!mediaPlayer.isPlaying()){ mediaPlayer.start(); } break; case R.id.stop: if (mediaPlayer.isPlaying()){ mediaPlayer.reset(); initMediaPlayer(); } break; case R.id.pause: if (mediaPlayer.isPlaying()){ mediaPlayer.pause(); } break; default: break; } } private void initMediaPlayer(){ try { File file = new File(Environment.getExternalStorageDirectory(),"m.mp3"); mediaPlayer.setDataSource(file.getPath()); mediaPlayer.prepare(); } catch (Exception e) { e.printStackTrace(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode){ case 1: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){ initMediaPlayer(); }else{ Toast.makeText(this,"无权限",Toast.LENGTH_SHORT).show(); finish(); } break; default: } } @Override protected void onDestroy() { super.onDestroy(); if (mediaPlayer != null){ mediaPlayer.stop(); mediaPlayer.release(); } } }
try { mediaPlayer.reset(); mediaPlayer.setDataSource(SP); mediaPlayer.prepare(); mediaPlayer.start(); } catch (IOException e) { e.printStackTrace(); }
仔细想想,每次使用MediaPlarer都是要先初始化和释放资源的,也就是要reset()的,之前在设置listview点击事件时没有注意到这点,所以一直有这个异常,而这个异常可以解释为:因为java里面的mediaplayer对象的状态和native的对象状态发生了不一致。也就是说,你在用MediaPlayer之前没有初始化或者没有回复到原来刚创建是的状态,所以只要加上这一句就可以了: