2011-03-09 4 views
3

미디어 플레이어 앱을 제작 중입니다. 미디어를 재생할 때 검색 바가 자동으로 진행되도록 검색 바를 동기화하려고합니다. 여기 내 소스 코드입니다 :Android 미디어 플레이어 및 검색 바 동기화 문제

public class MusicDroid extends ListActivity implements 
     SeekBar.OnSeekBarChangeListener, Runnable { 

    private int cur_time = 0; 
    private SeekBar seekbar; 
    int song_dur = 0; 
    GroveService gs; 
    public Chronometer timer; 
    int timer_time = 0; 

    @Override 
    public void onCreate(Bundle icicle) { 
     try { 
      super.onCreate(icicle); 
      setContentView(R.layout.songlist); 
      gs = new GroveService(); 
      gs.updateSongList(); 
     } catch (NullPointerException e) { 
      Log.v(getString(R.string.app_name), e.getMessage()); 
     } 
     seekbar = (SeekBar) findViewById(R.id.SeekBar01); 
     timer = (Chronometer) findViewById(R.id.Chronometer01); 
     seekbar.setOnSeekBarChangeListener(this); 
     // this.bindService(new Intent(this, GroveService.class), conn, 
     // Context.BIND_AUTO_CREATE); 
     ArrayAdapter<String> songList = new ArrayAdapter<String>(this, 
       R.layout.song_item, gs.songs); 
     setListAdapter(songList); 
     timer.setOnChronometerTickListener(new OnChronometerTickListener() { 
      @Override 
      public void onChronometerTick(Chronometer arg0) { 
       // TODO Auto-generated method stub 
       seekbar.setProgress(cur_time); 
      } 
     }); 
    } 

    protected void onListItemClick(ListView l, View v, int position, long id) { 
     timer.stop(); 
     timer.start(); 
     gs.playSong(position, 0); 
    } 

    /* 
    * private ServiceConnection conn= new ServiceConnection(){ 
    * 
    * @Override public void onServiceConnected(ComponentName arg0, IBinder 
    * arg1) { Log.v("Status:","Service Connected to player"); // TODO 
    * Auto-generated method stub tprog= new Thread(new Runnable(){ 
    * 
    * }); tprog.setPriority(Thread.MIN_PRIORITY); tprog.start(); } 
    * 
    * @Override public void onServiceDisconnected(ComponentName arg0) { // TODO 
    * Auto-generated method stub 
    * 
    * } }; 
    */ 
    // code for menu based media player controls 
    /* 
    * public boolean onOptionsItemSelected(MenuItem item) { switch 
    * (item.getItemId()) { case R.id.prev: gs.prevSong(); break; case 
    * R.id.play: gs.playSong(gs.songindex,cur_time); break; case R.id.pause: 
    * gs.mp.getDuration(); gs.mp.pause(); break; case R.id.nxt: gs.nextSong(); 
    * break; } return true; } 
    */ 

    public void myClickHandler(View view) { 
     switch (view.getId()) { 
     case R.id.ImageButton01: 
      gs.prevSong(); 
      timer.stop(); 
      seekbar.setMax(gs.getSongDuration(gs.songindex)); 
      Log.v("SeekBar Max", String.valueOf(seekbar.getMax())); 
      timer.start(); 
      break; 
     case R.id.ImageButton02: 
      Thread t=new Thread(); 
      t.start(); 
      gs.playSong(gs.songindex, cur_time); 
      timer.start(); 
      seekbar.setMax(gs.getSongDuration(gs.songindex)); 
      Log.v("SeekBar Max", String.valueOf(seekbar.getMax())); 
      break; 
     case R.id.ImageButton03: 
      cur_time = gs.getCurrentDuration(gs.songindex); 

       if(gs.mp.isPlaying()){ 
       timer_time=Integer.parseInt((String)timer.getText()); 
       timer.stop(); 
       timer.setBase(timer_time); 
       Log.v("Timer Time",String.valueOf(timer_time)); } 
       gs.mp.pause(); 
      seekbar.setMax(gs.getSongDuration(gs.songindex)); 
      Log.v("SeekBar Max", String.valueOf(seekbar.getMax())); 
      break; 
     case R.id.ImageButton04: 
      gs.nextSong(); 
      timer.stop(); 
      timer.start(); 
      seekbar.setMax(gs.getSongDuration(gs.songindex)); 
      Log.v("SeekBar Max", String.valueOf(seekbar.getMax())); 
      break; 
     } 
    } 

    @Override 
    public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) { 
     // TODO Auto-generated method stub 
     gs.mp.seekTo(arg1); 
    } 

    @Override 
    public void onStartTrackingTouch(SeekBar arg0) { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void onStopTrackingTouch(SeekBar arg0) { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void run() { 
     // TODO Auto-generated method stub 
     int currentPosition = 0; 
     int total = gs.mp.getDuration(); 
     seekbar.setMax(total); 
     while (gs.mp != null && currentPosition < total) { 
      try { 
       Thread.sleep(1000); 
       currentPosition = gs.mp.getCurrentPosition(); 
      } catch (InterruptedException e) { 
       return; 
      } catch (Exception e) { 
       return; 
      } 
      seekbar.setProgress(currentPosition); 
     } 
    } 
} 

음악 재생을 수행하는 서비스 클래스입니다. 코드는 여기에 있습니다 :

class Mp3Filter implements FilenameFilter { 
    public boolean accept(File dir, String name) { 
     return (name.endsWith(".mp3")); 
    } 
} 

public class GroveService extends Service { 
    static final String MEDIA_PATH = new String("/sdcard/"); 
    List<String> songs = new ArrayList<String>(); 
    MediaPlayer mp = new MediaPlayer(); 
    int songindex = 0; 
    int duration=0; 
    //MusicDroid md; 
    @Override 
    public IBinder onBind(Intent arg0) { 
     // TODO Auto-generated method stub 
     return null; 
    } 
    public void onCreate() 
    { 
     super.onCreate(); 
     updateSongList(); 
     //md=new MusicDroid(); 
    } 

    public void updateSongList() { 
     File home = new File(MEDIA_PATH); 
     if (home.listFiles(new Mp3Filter()).length > 0) { 
      for (File file : home.listFiles(new Mp3Filter())) { 
       songs.add(file.getName()); 
      }         
     } 
    } 
    public void playSong(final int position, final int cur_pos) { 
     try {      
      mp.reset();   
      mp.setDataSource(MEDIA_PATH + songs.get(position)); 
      mp.prepare(); 
      //song_dur=mp.getDuration(); 
      mp.seekTo(cur_pos); 
      mp.start(); 
      duration=position; 
      mp.setOnCompletionListener(new OnCompletionListener() { 
       public void onCompletion(MediaPlayer arg0) { 
        nextSong(); 
       } 
      });   
     } catch (IOException e) { 
      Log.v(getString(R.string.app_name), e.getMessage()); 
     } 
    }  

    public void nextSong() { 
     if (++songindex >= songs.size()) 
      songindex = 0; 
     else 
      playSong(songindex,0); 
    } 

    public void prevSong() { 
     songindex--; 
     if (songindex > 0) 
      playSong(songindex,0); 
     else { 
      songindex = 0; 
      playSong(songindex,0); 
     } 
    } 
    public int getSongDuration(int index) 
    { 
     duration=mp.getDuration(); 
     Log.v("Song Duration", String.valueOf(duration)); 
     return duration; 
    } 
    public int getCurrentDuration(int index){ 
     int current_position; 
     current_position=mp.getCurrentPosition(); 
     Log.v("Current Dur:",String.valueOf(current_position)); 
     return current_position; 
    } 
} 

답변

6

MediaPlayer를 당신이있는 당신이 내 시스템이 코드는 잘 작동이 코드를 시도

mMediaPlayer.setOnPreparedListener(new OnPreparedListener() 
      { 
      @Override 
      public void onPrepared(final MediaPlayer mp) 
      { 
       seekBar.setMax(mp.getDuration()); 
        new Thread(new Runnable() { 

          @Override 
          public void run() { 
            while(mp!=null && mp.getCurrentPosition()<mp.getDuration()) 
            { 
             seekBar.setProgress(mp.getCurrentPosition()); 
             Message msg=new Message(); 
             int millis = mp.getCurrentPosition(); 

             msg.obj=millis/1000; 
             mHandler.sendMessage(msg); 
             try { 
              Thread.sleep(100); 
             } 
             catch (InterruptedException e) { 
              e.printStackTrace(); 
             } 
            } 
          } 
        }).start(); 

      } 
     }); 
+1

seekBar가 final 인 경우를 제외하고는 스레드로부터 안전하지 않습니다. 이를 처리하는 더 좋은 방법이 있습니다. 즉 Handler와 다양한 send * 메소드를 사용하는 것입니다. – skyler

8

을 따를로 찾는 동기화 할 수 있습니다 onPreparedListener 설정할 수 있습니다. 이것은 내 string.xml입니다

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
android:id="@+id/widget31" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
xmlns:android="http://schemas.android.com/apk/res/android"> 
    <Button 
     android:text="@string/play_str" 
     android:textSize="15pt" 
     android:textStyle="bold" 
     android:id="@+id/ButtonPlayStop" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"/> 
    <SeekBar 
     android:id="@+id/SeekBar01" 
     android:layout_height="wrap_content" 
     android:layout_width="fill_parent" 
     android:layout_below="@id/ButtonPlayStop"/> 
</RelativeLayout> 

:

package san.san; 

    import android.app.Activity; 
    import android.media.MediaPlayer; 
    import android.os.Bundle; 
    import android.os.Handler; 
    import android.view.MotionEvent; 
    import android.view.View; 
    import android.view.View.OnClickListener; 
    import android.view.View.OnTouchListener; 
    import android.widget.Button; 
    import android.widget.SeekBar; 

    public class Mp3player extends Activity { 

     private Button buttonPlayStop; 
     private MediaPlayer mediaPlayer; 
     private SeekBar seekBar; 

     private final Handler handler = new Handler(); 

     // Here i override onCreate method. 
     // 
     // setContentView() method set the layout that you will see then 
     // the application will starts 
     // 
     // initViews() method i create to init views components. 
     @Override 
     public void onCreate(Bundle icicle) { 
       super.onCreate(icicle); 
       setContentView(R.layout.main); 
       initViews(); 

     } 

     // This method set the setOnClickListener and method for it (buttonClick()) 
     private void initViews() { 
      buttonPlayStop = (Button) findViewById(R.id.ButtonPlayStop); 
      buttonPlayStop.setOnClickListener(new OnClickListener() {public void onClick(View v) {buttonClick();}}); 

      mediaPlayer = MediaPlayer.create(this, R.raw.sound41772); 

      seekBar = (SeekBar) findViewById(R.id.SeekBar01); 
      seekBar.setMax(mediaPlayer.getDuration()); 
      seekBar.setOnTouchListener(new OnTouchListener() {public boolean onTouch(View v, MotionEvent event) { 
       seekChange(v); 
       return false; } 
      }); 

     } 

     public void startPlayProgressUpdater() { 
      seekBar.setProgress(mediaPlayer.getCurrentPosition()); 

      if (mediaPlayer.isPlaying()) { 
       Runnable notification = new Runnable() { 
        public void run() { 
         startPlayProgressUpdater(); 
        } 
       }; 
       handler.postDelayed(notification,1000); 
      }else{ 
       mediaPlayer.pause(); 
       buttonPlayStop.setText(getString(R.string.play_str)); 
       seekBar.setProgress(0); 
      } 
     } 

     // This is event handler thumb moving event 
     private void seekChange(View v){ 
      if(mediaPlayer.isPlaying()){ 
       SeekBar sb = (SeekBar)v; 
       mediaPlayer.seekTo(sb.getProgress()); 
      } 
     } 

     // This is event handler for buttonClick event 
     private void buttonClick(){ 
      if (buttonPlayStop.getText() == getString(R.string.play_str)) { 
       buttonPlayStop.setText(getString(R.string.pause_str)); 
       try{ 
        mediaPlayer.start(); 
        startPlayProgressUpdater(); 
       }catch (IllegalStateException e) { 
        mediaPlayer.pause(); 
       } 
      }else { 
       buttonPlayStop.setText(getString(R.string.play_str)); 
       mediaPlayer.pause(); 
      } 
     } 
    } 

내 main.xml에 인이 내 매니페스트 파일입니다

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <string name="app_name">Android mp3 player</string> 
    <string name="play_str">PLAY</string> 
    <string name="pause_str">PAUSE</string> 
</resources> 

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="san.san" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk android:minSdkVersion="8" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:name=".Mp3player" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 
0

당신이 필요 onProgressChanged() 메서드 내에서 약간의 코드를 변경하십시오.

이 코드를보십시오 :

public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) { 
    // TODO Auto-generated method stub 
      if(arg2){ 
       gs.mp.seekTo(arg1); 
      } 
} 

또한 코드가 내 컴퓨터 및 에뮬레이터에서 잘 작동 .This 내 아래 코드로 볼 수있다.

내 자바 코드 :

내 XML 코드는이 링크에서 찾을 수 있습니다

public class MainActivity extends AppCompatActivity { 

MediaPlayer player; 
//Handler seekHandler = new Handler(); 
AudioManager audioManager; 
SeekBar musicseek; 

public void play(View view) 
{ 
    player.start(); 
} 
public void pause(View view) 
{ 
    player.pause(); 
} 

public void stop(View view) 
{ 
    player.stop(); 
} 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 
    player=MediaPlayer.create(this,R.raw.music); 
    audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 
    int maxvol= audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 
    int curvol= audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 

    SeekBar bar=(SeekBar) findViewById(R.id.seekBar); 
     bar.setMax(maxvol); 
     bar.setProgress(curvol); 
     musicseek= (SeekBar) findViewById(R.id.musicSeek); 

    musicseek.setMax(player.getDuration()); 
    musicseek.setProgress(player.getCurrentPosition()); 

    final Handler han = new Handler(); 

    Runnable myRunnable = new Runnable() { 
     @Override 
     public void run() { 

      musicseek.setProgress(player.getCurrentPosition()); 
      han.postDelayed(this, 1000); 
     } 
    }; 

    myRunnable.run(); 

    musicseek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){ 

     @Override 
     public void onStartTrackingTouch(SeekBar seekBar) { 

     } 

     @Override 
     public void onStopTrackingTouch(SeekBar seekBar) { 

     } 

     @Override 
     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 

      if(fromUser){ 
       player.seekTo(progress); 
      } 
     } 
    }); 

    bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){ 

     @Override 
     public void onStartTrackingTouch(SeekBar seekBar) { 

     } 

     @Override 
     public void onStopTrackingTouch(SeekBar seekBar) { 

     } 

     @Override 
     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
      //String temp=Integer.toString(progress); 
      //Log.i("seekbar ",temp); 

      audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,progress,0); 
     } 
    }); 

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
    fab.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) 
        .setAction("Action", null).show(); 
     } 
    }); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 

    //noinspection SimplifiableIfStatement 
    if (id == R.id.action_settings) { 
     return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 

가} : https://pastebin.com/a2Sdr0bB

난이 도움이되기를 바랍니다! .

관련 문제