title: Buffering update not reaching 100% in seek bar attached with MediaPlayer
body: <p>Here I have developed an app which does streaming of audio file stored in a server.
  This is done using <code>MediaPlayer</code> class. The current playback position and buffering level of song is shown in a custom <code>Seekbar</code>. <br>
  So far I have managed to show the buffering progress as secondary progress in seekbar, synchronize the primary progress of seekbar with MediaPlayer playback, and play,pause and stop the playback on respective button clicks.<br>
  But now I am stuck with the problem of buffering progress not showing greater than around 86 to 89 percent and same is reflected in seekbar secondary progress i.e. buffering progress in seekbar does not increase after (86-89 percent) .I have captured the buffering percentage in the log and attaching the relevant log details below.<br></p>
  
  <pre><code>07-02 14:21:34.484 14537-14559/com.appy.unofficialsultanapp I/MediaPlayer: prepared
  07-02 14:21:34.484 14537-14537/com.appy.unofficialsultanapp E/MediaPlayer: Should have subtitle controller already set
  07-02 14:21:34.494 14537-14537/com.appy.unofficialsultanapp I/Choreographer: Skipped 366 frames!  The application may be doing too much work on its main thread.
  07-02 14:21:34.514 14537-14537/com.appy.unofficialsultanapp E/MediaPlayer: Should have subtitle controller already set
  07-02 14:21:34.544 14537-14537/com.appy.unofficialsultanapp I/Buffering: 5
  07-02 14:21:35.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 8
  07-02 14:21:36.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 15
  07-02 14:21:37.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 29
  07-02 14:21:38.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 43
  07-02 14:21:39.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 59
  07-02 14:21:40.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 75
  07-02 14:21:41.524 14537-14537/com.appy.unofficialsultanapp I/Buffering: 89
  07-02 14:22:31.034 14537-14537/com.appy.unofficialsultanapp E/MediaPlayer-JNI: QCMediaPlayer mediaplayer NOT present
  07-02 14:22:31.034 14537-14710/com.appy.unofficialsultanapp D/MediaHTTPConnection: filterOutInternalHeaders: key=User-Agent, val= stagefright/1.2 (Linux;Android 5.1.1)
  07-02 14:22:31.034 14537-14559/com.appy.unofficialsultanapp D/MediaHTTPConnection: proxy null port 0
  07-02 14:22:33.554 14537-14559/com.appy.unofficialsultanapp D/MediaHTTPConnection: mTotalSize_1=4673664
      mTotalSize_2=4673664
  07-02 14:22:37.004 14537-14560/com.appy.unofficialsultanapp I/MediaPlayer: prepared
  07-02 14:22:37.004 14537-14537/com.appy.unofficialsultanapp E/MediaPlayer: Should have subtitle controller already set
  07-02 14:22:37.004 14537-14537/com.appy.unofficialsultanapp I/Choreographer: Skipped 357 frames!  The application may be doing too much work on its main thread.
  07-02 14:22:37.034 14537-14537/com.appy.unofficialsultanapp E/MediaPlayer: Should have subtitle controller already set
  07-02 14:22:37.054 14537-14537/com.appy.unofficialsultanapp I/Buffering: 3
  07-02 14:22:38.034 14537-14537/com.appy.unofficialsultanapp I/Buffering: 6
  07-02 14:22:39.034 14537-14537/com.appy.unofficialsultanapp I/Buffering: 10
  07-02 14:22:40.034 14537-14537/com.appy.unofficialsultanapp I/Buffering: 17
  07-02 14:22:41.034 14537-14537/com.appy.unofficialsultanapp I/Buffering: 27
  07-02 14:22:42.044 14537-14537/com.appy.unofficialsultanapp I/Buffering: 40
  07-02 14:22:43.044 14537-14537/com.appy.unofficialsultanapp I/Buffering: 56
  07-02 14:22:44.044 14537-14537/com.appy.unofficialsultanapp I/Buffering: 70
  07-02 14:22:45.044 14537-14537/com.appy.unofficialsultanapp I/Buffering: 86
  07-02 14:22:49.914 14537-14537/com.appy.unofficialsultanapp D/yuan: onVisibilityChanged----android.widget.ListView{2b9dfca7 VFED.VC. .F...... 20,83-700,1066 #7f040024 app:id/list}
  07-02 14:22:55.004 14537-14555/com.appy.unofficialsultanapp W/MediaPlayer-JNI: MediaPlayer finalized without being released
  </code></pre>
  
  <p>I am also attaching the screenshot of buffered level of the song in seekbar, highlighted with red.<a href="https://i.stack.imgur.com/UBWKY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/UBWKY.png" alt="Screenshot of buffered level"></a><br>
  I have done a great deal of research on web to search for its reason and solutions, but none of them worked for me.Even though when seekbar is dragged to a position ahead of buffered song position(white strip in screenshot)) after around 86%, song plays without any issue, but secondary progress gets stuck before that as shown in screenshot.<br><br>
  Here is the code which does overall interaction between <code>MediaPlayer</code> and <code>SeekBar</code></p>
  
  <p><em>Code snippet from Songs class created in Songs.java</em><br></p>
  
  <pre><code>private void primarySeekBarProgressUpdater() {         /**method to update 
  primary progress of seekbar**/
      seekBar.setProgress((int) (((float) mediaPlayer.getCurrentPosition() / 
  mediaFileLengthInMilliseconds) * 100));
      tvElapsedTime.setText(getTimeString(mediaPlayer.getCurrentPosition()));
      if (mediaPlayer.isPlaying()) {
          Runnable notification = new Runnable() {
              @Override
              public void run() {
                  primarySeekBarProgressUpdater();
              }
          };
          handler.postDelayed(notification, 1000);
      }
  }
  
  @Override
  public void onClick(View v) {         /**onClick event handler to handle 
  play, pause and stop button clicks for mediaplayer **/
      if (v.getId() == R.id.buttonPlay) {
          if (mediaPlayer != null) {
              mediaPlayer.start();
              imPause.setVisibility(View.VISIBLE);
              imPlay.setVisibility(View.INVISIBLE);
              primarySeekBarProgressUpdater();
          }
      } else if (v.getId() == R.id.buttonPause) {
          mediaPlayer.pause();
          imPlay.setVisibility(View.VISIBLE);
          imPause.setVisibility(View.INVISIBLE);
          primarySeekBarProgressUpdater();
      } else if (v.getId() == R.id.buttonStop) {
          if (mediaPlayer != null) {
              mediaPlayer.stop();
              seekBar.setProgress(0);
              seekBar.setSecondaryProgress(0);
              imPlay.setVisibility(View.VISIBLE);
              imPause.setVisibility(View.INVISIBLE);
          }
      } else if (v.getId() == R.id.buttonPlay &amp;&amp; !itemClicked) {
          Toast.makeText(getApplicationContext(), "Please touch a song to start 
  playing it.", Toast.LENGTH_LONG).show();
      }
  }
  
  @Override
  public boolean onTouch(View v, MotionEvent event) {   
      if (v.getId() == R.id.seekBar) {
          /** Seekbar onTouch event handler. Method which seeks MediaPlayer to 
  seekBar primary progress position*/
          if (mediaPlayer != null) {
              SeekBar sb = (SeekBar) v;
              int playPositionInMilliseconds = (mediaFileLengthInMilliseconds / 
      100) * sb.getProgress();
              mediaPlayer.seekTo(playPositionInMilliseconds);
  
  tvElapsedTime.setText(getTimeString(mediaPlayer.getCurrentPosition()));
          }
      }
      return false;
  }
  
  public String getTimeString(long millis) {     /**method to convert passed 
  milliseconds to minutes and seconds and return in form of string**/
      StringBuffer buf = new StringBuffer();
      int mins = (int) ((millis % (1000 * 60 * 60)) / (1000 * 60));
      int secs = (int) (((millis % (1000 * 60 * 60)) % (1000 * 60)) / 1000);
  
      buf.append(String.format("%02d", mins)).append(":")
              .append(String.format("%02d", secs));
      return buf.toString();
  }
  
  
  @Override
  protected void onPause() {
      super.onPause();
  }
  
  @Override
  protected void onDestroy() {
      super.onDestroy();
  }
  
  @Override
  public void onBackPressed() {
  
      if (mediaPlayer != null) {
          mediaPlayer.stop();
          mediaPlayer.release();
      }
  
      super.onBackPressed();
  }
  </code></pre>
  
  <blockquote>
    <p>Below is the code snippet of same class when listitem i.e any song is clicked</p>
  </blockquote>
  
  <pre><code>        list.setAdapter(adapter);
          list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  
              @Override
              public void onItemClick(AdapterView&lt;?&gt; parent, View view, final 
              int position, long id) {
                  list.setItemChecked(position, true);
                  url = songdetails.get(position).getUrl(); // your URl
  
                  if (mediaPlayer != null) {
                      mediaPlayer.stop();
                  }
  
                  mediaPlayer = new MediaPlayer(); // create instance of 
  mediaplayer here
                  mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                  try {
                      mediaPlayer.setDataSource(url);
                      mediaPlayer.prepare();
                      itemClicked = true;
  
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
                  mediaFileLengthInMilliseconds = mediaPlayer.getDuration();// 
  gets the song length in milliseconds from URL
  
                  mediaPlayer.setOnPreparedListener(new 
  MediaPlayer.OnPreparedListener() {
                      @Override
                      public void onPrepared(MediaPlayer mp) {
                          mp.start();
                          imPlay.setVisibility(View.INVISIBLE);
                          imPause.setVisibility(View.VISIBLE);
                          primarySeekBarProgressUpdater();
  
  tvEndTime.setText(getTimeString(mediaFileLengthInMilliseconds));
                          mediaPlayer.setOnBufferingUpdateListener(new 
  MediaPlayer.OnBufferingUpdateListener() {
                              @Override
                              public void onBufferingUpdate(MediaPlayer mp, int 
  percent) {
                                  if (percent &lt; seekBar.getMax()) {
                                      seekBar.setSecondaryProgress(percent);  
  /** This is the point where secondary progress is set on buffering update **/
                                      Log.i("Buffering", "" + percent);   /** 
  and this is the point where tat buffered percentage is captured in logcat **/
                                  }
                              }
                          });
                          mediaPlayer.setOnCompletionListener(new 
  MediaPlayer.OnCompletionListener() {
                              @Override
                              public void onCompletion(MediaPlayer mp) {
                                  mp.start();
                              }
                          });
                      }
                  });
                  primarySeekBarProgressUpdater();
              }
          });
  </code></pre>
  
  <p>So my buffering progress is not reaching to 100% as I expect it to do.</p>