当前位置: 首页 > 知识库问答 >
问题:

Android MediaPlayer-setDataSource和发布-IllegalStateException

上官凯歌
2023-03-14

我编写了自己的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){
            }
        }
    }
}

应用程序播放我在代码中的注释中提到的第一个声音。当我点击一个应该启动另一个声音的按钮时,我得到以下错误:

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的这个问题花了我一整天的时间,希望你能帮我。。。

共有2个答案

蒙弘图
2023-03-14

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

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;
    }
}
佟阳飙
2023-03-14

将mp.release更改为mp.reset

公共无效重置()

将MediaPlayer重置为未初始化状态。调用此方法后,必须通过设置数据源并调用prepare()再次初始化它。

公开作废()

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

你需要保持物体在周围。

你可以用一种简单的方法

        MediaPlayer mediaPlayer = new MediaPlayer();
        mediaPlayer.setDataSource(context, ringtone);
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MEDIA);
        mediaPlayer.prepare();
        mediaPlayer.start();
 类似资料:
  • 构建 当项目开发完毕,只需要运行一行命令就可以打包你的应用: # 打包正式环境 npm run build:prod # 打包预发布环境 npm run build:stage 构建打包成功之后,会在根目录生成 dist 文件夹,里面就是构建打包好的文件,通常是 ***.js 、***.css、index.html 等静态文件。 如果需要自定义构建,比如指定 dist 目录等,则需要通过 co

  • 打包和部署, 我们必须要会. 我们要有追求,做一个会运维的编程好手. 做个DevOps. 就算公司有明确要求, 部署专门有运维人员,我们在他们做部署时,也要搬个板凳过去旁观,参与. 运维人员也特别乐于开发人员陪他们一起发布.

  • 发布和订阅 Meteor 服务端可以通过Meteor.publish发布文档集,同时客户端可以通过Meteor.subscribe订阅这些发布。 任何客户端订阅的文档都可以通过find方法进行查询使用。 默认情况下,每个新创建的 Meteor 应用包含有 autopublish 包,它会自动为每个客户端发布所有可用的文档。 为了可以更细化的控制不同客户端所接收的数据文档,首先应该在终端移除 aut

  • 一旦源代码tarball已经从稳定的发布分支产生,发布过程公共部分便已经开始。但是在tarball进入公开之前,必须经过少量开发者的确认,通常需要三位或者更多。确认不仅仅是检测发布的明显缺陷;理想情况下,开发者应该下载tarball,在干净的系统上构建并安装,运行回归测试包Chapter 8, 管理志愿者的(见the section called “自动测试”),然后执行一些手工测试。假如通过了这

  • 维护同时的平行发布包含了如何完成日常开发的暗示。特别是应该遵守每次提交只包含一个单独逻辑变更的铁律,绝不要在一次提交中混杂不相关的变更。如果一次提交的变更太大,或具有破坏性,可以分为N此提交,每次提交都是一个整体变更的分区子集,而且不包含与整体变更无关的内容。 这里是一个未经慎重考虑进行提交的例子: ------------------------------------------------

  • 这是我第一次编写一个非常基本的JavaScript库,现在我打算发布它。我将它作为一个函数编写,用户可以通过CDN简单地导入JavaScript文件。我也打算把它发布到NPM,这样用户就可以把它和JS捆绑程序一起使用了。 我创建了另一个文件来匹配node.js格式,基本上,我在函数之前添加了,这一切都起作用了。所以,现在我得到了两个代码基本相同的文件,一个用于CDN,一个用于NPM。有没有办法把这