2017-07-27 5 views
0

サービスでオーディオを再生しようとしていて、アダプタ内のシークバーアイテムを更新しようとしています。しかし、私はサービスからオーディオの時間を得ることができません。また、recyclerviewをスクロールするときに、現在再生中のシークバーアイテムを更新するのではなく、複数のアイテムビューが更新されます。私は以下のコードを試しました。サービスからのオーディオの持続時間を取得し、アダプタ内のシークバー項目に設定する方法は?

public class LocalService extends Service { 

boolean mBound = false; 

private final IBinder mBinder = new LocalBinder(); 
private String path = ""; 
private int timer; 

private static MediaPlayer mediaPlayer = new MediaPlayer(); 
// Random number generator 

/** 
* Class used for the client Binder. Because we know this service always 
* runs in the same process as its clients, we don't need to deal with IPC. 
*/ 
public class LocalBinder extends Binder { 

    public LocalService getService() { 
     // Return this instance of LocalService so clients can call public methods 

     return LocalService.this; 
    } 
} 

@Override 
public IBinder onBind(Intent intent) { 

    return mBinder; 
} 

/** 
* method for clients 
*/ 
public int getTotalTime() { 

    return mediaPlayer.getDuration(); 
} 

public int getDuration() { 
    // Log.v("player duration",timer+""); 
    try { 
     if (mediaPlayer != null && mediaPlayer.isPlaying()) { 
      Log.v("playing", (mediaPlayer.getCurrentPosition()/1000) + ""); 
      return mediaPlayer.getCurrentPosition()/1000; 
     } else { 
      //Log.v("not playing", (mediaPlayer.getCurrentPosition()/1000) + ""); 
      return 0; 
     } 
    }catch (IllegalStateException i) 
    { 
     i.printStackTrace(); 
     return 0; 
    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
     return 0; 
    } 

} 

@Override 
public void onCreate() { 
    super.onCreate(); 

    try { 
     mediaPlayer = new MediaPlayer(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

public void setAudio(String path) 
{ 
    try { 

      mediaPlayer.setDataSource(path); 



    } catch (IOException e) { 
     e.printStackTrace(); 

    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 

} 

public void playAudio() { 
    Log.v("audio path", path); 

    try { 

     mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
      @Override 
      public void onPrepared(MediaPlayer mp) { 
       mediaPlayer.prepareAsync(); 
       mediaPlayer.start(); 
       timer=mediaPlayer.getDuration(); 

       Log.v("total timer1",timer+""); 

      } 
     }); 


     mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 
      @Override 
      public void onCompletion(MediaPlayer mp) { 
       timer=0; 
       mediaPlayer.stop(); 
       mediaPlayer.reset(); 
       //mediaPlayer.release(); 
      } 
     }); 



    } catch (Exception e) { 

     e.printStackTrace(); 
    } 
} 



@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

    return START_STICKY; 
} 

@Override 
public void unbindService(ServiceConnection conn) { 
    super.unbindService(conn); 

    mediaPlayer.reset(); 
    mediaPlayer.release(); 
} 


@Override 
public void onDestroy() { 
    super.onDestroy(); 
    mediaPlayer.reset(); 
    mediaPlayer.release(); 

} 

サービスはアダプタコンストラクタから開始されます。リサイクルの特殊なアダプタで

Intent intent = new Intent(mContext, LocalService.class); 
    mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 

プレーヤーの項目をクリックし、あなたのアダプタクラス内

vhItemHolder.playPauseImageView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       currentlyPlayingPosition = position; 

       if (mBound) { 

        Log.v("service","bound"); 

        //Make sure you update Seekbar on UI thread 
        mService.setAudio(audioDirectory+messageArrayList.get(position).getmMediaValue()); 

        mPlayer=new MediaPlayer(); 
        try { 
         mPlayer.setDataSource(audioDirectory+messageArrayList.get(position).getmMediaValue()); 
         mPlayer.prepareAsync(); 
         vhItemHolder.seekBar.setMax(mPlayer.getDuration()); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 

        mService.playAudio(); 

        Log.v("duration",(mService.getTotalTime())+""); 

        vhItemHolder.seekBar.setMax(mService.getTotalTime()); 

        mHandler.removeCallbacks(null); 

        mHandler=new Handler(); 

        ((DoctorActivity)mContext).runOnUiThread(new Runnable() { 

         @Override 
         public void run() { 

          num = mService.getDuration(); 
          Log.v("progress",num+""); 
          vhItemHolder.seekBar.setProgress((num)); 
          vhItemHolder.runningTimerTextView.setText(convertMilliToMinutes((long)mService.getDuration())); 

          mHandler.postDelayed(this, 50); 
         } 
        }); 
       } 
       else 
       { 
        Log.v("service","not bound"); 
       } 

答えて

0

: あなたがviewHolderのplayPauseImageViewのonClickListenerでのMediaPlayerの新しいオブジェクト(Mplayerの)を作り、その上にsetDataSource()メソッドを呼び出していますこのローカルmPlayerオブジェクトのデータソースをLocalServiceクラスのmediaPlayerオブジェクトに設定しません。

mService.playAudio()およびmService.getDuration()メソッドを呼び出すと、setDataSource()メソッドがまだ呼び出されていないLocalServiceクラスのmediaPlayerオブジェクトにアクセスするため、間違った期間を返して再生できなくてはなりません。

あなたは、以下のようなあなたのアダプタクラスで変更を行う必要があります。

vhItemHolder.playPauseImageView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      currentlyPlayingPosition = position; 

      if (mBound) { 

       Log.v("service","bound"); 

       //Make sure you update Seekbar on UI thread 
       mService.setAudio(audioDirectory+messageArrayList.get(position).getmMediaValue()); 

       mPlayer = mService.mediaPlayer;// or mPlayer = LocalService.mediaPlayer; as being static object. 
    //rather new MediaPlayer(); 
       try { 
        mPlayer.setDataSource(audioDirectory+messageArrayList.get(position).getmMediaValue()); 
        mPlayer.prepareAsync(); 
        vhItemHolder.seekBar.setMax(mPlayer.getDuration()); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

       mService.playAudio(); 

       Log.v("duration",(mService.getTotalTime())+""); 

       vhItemHolder.seekBar.setMax(mService.getTotalTime()); 

       mHandler.removeCallbacks(null); 

       mHandler=new Handler(); 

       ((DoctorActivity)mContext).runOnUiThread(new Runnable() { 

        @Override 
        public void run() { 

         num = mService.getDuration(); 
         Log.v("progress",num+""); 
         vhItemHolder.seekBar.setProgress((num)); 
         vhItemHolder.runningTimerTextView.setText(convertMilliToMinutes((long)mService.getDuration())); 

         mHandler.postDelayed(this, 50); 
        } 
       }); 
      } 
      else 
      { 
       Log.v("service","not bound"); 
      } 
関連する問題