【问题标题】:for loop using a raw music array androidfor循环使用原始音乐数组android
【发布时间】:2011-06-15 17:52:08
【问题描述】:

我目前正在尝试创建一个 for 循环,它将在其中播放原始文件,完成后,它将继续播放数组中的下一个声音文件。它当前正在一次播放所有文件。关于我如何解决这个问题的任何建议?我认为完成监听器可能存在问题,但不确定。谢谢。

我的代码:

package com.example.mediatest;



    int[] myMusic = {R.raw.caralarm, R.raw.phonebusysignal, R.raw.phoneoffhook};



    MediaPlayer mp = new MediaPlayer();



   for (int y =0; y<3; y++){
       mp = MediaPlayer.create(this, myMusic[y]);
       mp.start();
       mp.setOnCompletionListener(new OnCompletionListener(){

        @Override
        public void onCompletion(MediaPlayer mp) {
            // TODO Auto-generated method stub

        }

       });
   }

【问题讨论】:

    标签: android arrays for-loop media-player


    【解决方案1】:

    您可以创建单独的 MediaPlayer 对象,首先启动,然后在 onCompletion 中启动下一个。对于可扩展的解决方案,请尝试以下方法:

    int[] myMusic = {R.raw.caralarm, R.raw.phonebusysignal, R.raw.phoneoffhook};
    int mCompleted = 0;
    
    MediaPlayer mp = MediaPlayer.create(this, myMusic[0]);
    
    mp.setOnCompletionListener(new OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            mCompleted++;
            mp.reset();
            if (mCompleted < myMusic.length()) {
                try {
                    AssetFileDescriptor afd = getResources().openRawResourceFd(myMusic[mCompleted]);
                    if (afd != null) {
                        mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                        afd.close();
                        mp.prepare();
                    }
                } catch (Exception ex) {
                    // report a crash
                }
            } else {
                // done with media player
                mp.release();
                mp = null;
            }
        }
    });
    
    mp.start();
    

    一种更简单的方法(稍微浪费资源)是:

    int[] myMusic = {R.raw.caralarm, R.raw.phonebusysignal, R.raw.phoneoffhook};
    int mNext;
    OnCompletionListener mListener = new OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            mp.release();
            startNextFile();
        }
    };
    
    @Override
    public void onCreate() {
        // usual onCreate stuff here, then...
    
        // either here or whenever you want to start the sequence
        mNext = 0;
        startNextFile();
    }
    
    void startNextFile() {
        if (mNext < myMusic.length) {
            MediaPlayer mp = MediaPlayer.create(this, myMusic[mNext++]);
            mp.setOnCompletionListener(mListener);
            mp.start();
        }
    }
    

    【讨论】:

    • 我尝试了您的建议,方法是在 MediaPlayer mp = new MediaPlayer(this, myMusic[0]); 出现错误,其中“构造函数 MediaPlayer(mediatest, int) 未定义”。我解决了它,但仍然没有成功。我做错了吗?
    • 对不起。那应该是MediaPlayer mp = MediaPlayer.create(this, myMusic[0]);。我会修复代码。
    • 我对您建议的代码顺序有点困惑,因为我收到“无法解析为变量”的错误。你的意思是public void startNextFile(){
    • 哪一行给出错误? startNextFile 不需要 公开;它不会从包外部调用。 (您甚至可以将其声明为私有,尽管这会强制编译器生成一个访问函数,以便可以从内部类方法 onCompletion 调用它。)
    • mNextmyMusicmListenerstartNextFile
    【解决方案2】:

    这是在继续循环中播放歌曲的工作代码。

    public class MainActivity extends Activity 
    {
    private int[] tracks = {R.raw.explosion,R.raw.pianothingy_one,R.raw.car_horn_x};
    int mCompleted = 0;
    
    public void onCreate(Bundle savedInstanceState) 
    {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
    
     MediaPlayer mp = MediaPlayer.create(this, tracks[0]);
     mp.setOnCompletionListener(new OnCompletionListener() 
     {
         @Override
         public void onCompletion(MediaPlayer mp)
         {
             mCompleted++;
             mp.reset();
             if (mCompleted < tracks.length) 
             {
                 try
                 {
                     AssetFileDescriptor afd = getResources().openRawResourceFd(tracks[mCompleted]);
                     if (afd != null) 
                     {
                         mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                         afd.close();
                         mp.prepare();
                         mp.start();
                     }
                 }
                 catch (Exception ex) 
                 {
                    ex.printStackTrace();
                 }
    
             } 
             else if (mCompleted>=tracks.length) 
             {
                 mCompleted =0;
                 try
                 {
                     AssetFileDescriptor afd = getResources().openRawResourceFd(tracks[mCompleted]);
                     if (afd != null) 
                     {
                         mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                         afd.close();
                         mp.prepare();
                         mp.start();
                     }
                 }
                 catch (Exception ex) 
                 {
                    ex.printStackTrace();
                 }
             }
             else
             {
                 mCompleted=0;
                  mp.release();
                  mp = null;
             }
    
         }
     });
    
     mp.start();
    

    【讨论】:

      【解决方案3】:

      创建一个 MediaPlayers 数组会更容易,因为您只有 3 个。您应该只启动第一个并设置 onCompletionListeners,您将在其中启动下一个播放器。希望这会有所帮助。

      【讨论】:

      • 这是个好主意。我现在会处理这个,让你知道它是如何工作的
      • 这就是我想出的MediaPlayer mp1 = MediaPlayer.create(this, myMusic[0]);MediaPlayer mp2 = MediaPlayer.create(this, myMusic[1]);MediaPlayer mp3 = MediaPlayer.create(this, myMusic[2]); final MediaPlayer [] mediaMp = {mp1, mp2, mp3}; mediaMp[0].start();mediaMp[0].setOnCompletionListener(new OnCompletionListener(){@Override public void onCompletion(MediaPlayer mp) {mediaMp[1].start(); mediaMp[1].setOnCompletionListener(new OnCompletionListener(){public void onCompletion(MediaPlayer mp) { mediaMp[2].start();}。问题是它有效,但必须有更短的方法
      【解决方案4】:
       int flag=0;
       int track; 
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_player);
          NextSongOnline()
          //here in my code i keept all sogns in araayList<> and by using mySongs i am parsing the arraylist that intented from another activity. 
          //mySongs = (ArrayList) bundle.getParcelableArrayList("songs");
      }
      
      
      public void NextSongOnLine(){
          if (flag == 0){
              track = position;
          }
          flag = 1;
          if (track == position){
              position = ((position + 1)%mySongs.size());
              Uri uri3 = Uri.parse(mySongs.get(position).toString());
              myMediaPlayer = MediaPlayer.create(getApplicationContext(),uri3);
      
              sname = mySongs.get(position).getName().toString();
              songTitle.setText(sname);
      
              myMediaPlayer.start();
              seekBar.setMax(myMediaPlayer.getDuration()/1000);
      
              //set End time of music
              endTimeText.setText(createTimerLabel(myMediaPlayer.getDuration()/1000));
      
          }
          track++;
          myMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
              // after one song completion this override method will be called with next position of song which is holding the counter "track". and that's how the loop will be continuing. 
              @Override
              public void onCompletion(MediaPlayer mp) {
                  NextSongOnLine();
                  Toast.makeText(getApplicationContext(),"Auto Playing Next Song",Toast.LENGTH_SHORT).show();
              }
          });
      }
      

      }

      【讨论】:

      • 虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
      猜你喜欢
      • 2010-09-20
      • 2021-09-18
      • 1970-01-01
      • 2019-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多