【问题标题】:Android MediaPlayer - setDataSource and Release - IllegalStateExceptionAndroid MediaPlayer - setDataSource 和 Release - IllegalStateException
【发布时间】:2015-03-16 22:24:06
【问题描述】:

我编写了自己的 MediaPlayer 类来播放特定路径中的文件并播放资产文件夹中的文件。这是课程:

public class CMediaPlayer extends MediaPlayer{

public void play(String audioPath){

   this.setOnCompletionListener(new OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            mp.release();
        }
    });

    File f = new File(audioPath);
    if(f.exists()){
        try{
            FileInputStream fis = new FileInputStream(f);
            FileDescriptor fileD = fis.getFD();
            this.setDataSource(fileD);
            this.prepare();

        }catch(IOException e){

        }
       this.start();
}
}

    public void play(AssetFileDescriptor descriptor){

        this.setOnCompletionListener(new OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
               mp.release();
            }
        });
        try {
            this.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
            descriptor.close();
            this.prepare();
        }catch (IOException e){

        }
        this.start();
    }

}

我想从一个活动中播放该类的几个声音。这是我的代码:

public class playGame extends Activity {

//a lot of variables

    CMediaPlayer mediaPlayer; //declare my mediaplayer

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK ) {
            //release??????
            Intent myIntent = new Intent(getBaseContext(), startView.class);
            startActivity(myIntent);
        }
        return super.onKeyDown(keyCode, event);
    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_play_question2);

        mediaPlayer = new CMediaPlayer(); //define my mediaplayer

       //stuff
    }

    //more variables

    public void playQuestion(File question){

        //stuff

        TextView myTextView = (TextView) findViewById(R.id.textViewQuestion);
        //stuff
        myTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            mediaPlayer.play(pathSoundQuestion); //play sound when clicked
            }
        });

    //stuff

        myImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               mediaPlayer.play(pathSoundQuestion); //play sound when clicked
            }
        });

        //stuff
        mediaPlayer.play(pathSoundQuestion); //plays sound immediatly, first played sound (works fine)

        //button1
        Button myButton = (Button) findViewById(R.id.button1);
        //stuff
        myButton.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(lastClickedButton == v){
                   //stuff
                    return;
                }
                //stuff
                mediaPlayer.play(pathAudio1); //play sound when clicked (error)
            }
        });

        //button2
        myButton = (Button) findViewById(R.id.button2);
       //stuff
        myButton.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(lastClickedButton == v){
                    //stuff
                    return;
                }
                //stuff
                mediaPlayer.play(pathAudio2); //play sound, same problem
            }
        });

       //goes on like this some more times...
    }

    public void logIn(View v, String right){
        //stuff

        if(right.equals("true")){
           //stuff
            try {
                AssetFileDescriptor descriptor = getAssets().openFd("Right");
                mediaPlayer.play(descriptor); //play sound from assets
                Intent myIntent = new Intent(getApplication(), playGame.class);
                startActivity(myIntent);
            }catch (IOException e){
            }
        }else{
          //stuff
            try {
                AssetFileDescriptor descriptor = getAssets().openFd("Wrong");
                mediaPlayer.play(descriptor); //play sound from assets
                Intent myIntent = new Intent(getApplication(), playGame.class);
                startActivity(myIntent);
            }catch (IOException e){
            }
        }
    }
}

应用程序会播放我的代码中的 cmets 中提到的第一个声音。当我单击一个应该启动另一个声音的按钮时,我收到以下错误:

03-16 23:07:38.478  13646-13646/com.example.cello.myownquiz E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.IllegalStateException
            at android.media.MediaPlayer.setDataSource(Native Method)
            at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1005)

我的 MediaPlayer 课程是否正常,或者我是否缺少某些内容,具体取决于状态?这门课是唯一需要释放的地方吗?还是我也必须把它放在我的活动中的某个地方?

有人看到我的错误吗? mediaPlayer的这个问题花了我一整天的时间尝试,希望你能帮助我......

【问题讨论】:

  • 首先使用mediaPlayer.stop();安全停止第一首歌曲并使用mediaPlayer.reset()重置它,然后设置新的数据源并开始播放!

标签: android android-mediaplayer


【解决方案1】:

mp.release(); 更改为mp.reset();

公共无效重置()

将 MediaPlayer 重置为未初始化状态。调用该方法后,需要通过设置数据源并调用prepare()重新初始化。

公共无效释放()

释放与此 MediaPlayer 对象关联的资源。使用完 MediaPlayer 后调用此方法被认为是一种很好的做法。特别是,每当应用程序的 Activity 暂停(调用其 onPause() 方法)或停止(调用其 onStop() 方法)时,应调用此方法以释放 MediaPlayer 对象,除非应用程序有特殊需要保持对象周围。除了占用不必要的资源(例如内存和编解码器的实例)外,如果不再需要 MediaPlayer 对象,则未能立即调用该方法还可能导致移动设备持续消耗电池,如果没有,其他应用程序播放失败设备上支持同一编解码器的多个实例。即使支持同一编解码器的多个实例,当同时使用不必要的多个实例时,可能会出现一些性能下降。

你需要把物体放在身边。

你可以通过简单的方式做到这一点

        MediaPlayer mediaPlayer = new MediaPlayer();
        mediaPlayer.setDataSource(context, ringtone);
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MEDIA);
        mediaPlayer.prepare();
        mediaPlayer.start();

【讨论】:

    【解决方案2】:

    我也有这个问题,但我用过:

    public void play(String name){
        try {
            AssetFileDescriptor afd = getAssets().openFd(name);
            if(myPlayer == null){
                myPlayer = new MediaPlayer();
            }
            myPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            myPlayer.prepare();
            myPlayer.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    然后停下来:

    public void stopPlayer(){
        if(myPlayer!= null && myPlayer.isPlaying()){
            myPlayer.stop();
            myPlayer = null;
        }else{
            myPlayer = null;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-02
      • 2018-06-09
      • 2017-02-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多