Android-плеер для 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; } } 

    В MediaPlayer вы можете установить onPreparedListener, в котором вы можете синхронизировать свой поиск так, как следует

     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(); } }); 

    Попробуйте этот код, этот код отлично работает в моей системе.

      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"?> <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> 

    Это мой string.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> 

    Вам нужно немного изменить код внутри метода onProgressChanged ().

    Попробуйте этот код:

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

    Вы также можете посмотреть мой ниже код. Этот код хорошо работает на моем компьютере и эмуляторе.

    Мой код Java:

     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); } 

    }

    Мой Xml-код можно найти по этой ссылке: https://pastebin.com/a2Sdr0bB

    Надеюсь, это поможет !!! ,