1

I writting a music application play music with url get from website. In code of me, i using method prepared() and app work. But method prepared() block UI this makes me uncomfortable... I want using method prepareAsync()... But i don't know use it :(. I'm newbie with Android Programing. Please edit my code...!

I speak English bad. Sorry for the inconvenience

Code here :

Function playSong()

private void playSong(String urlData) {
        btnPlay = (ImageButton) findViewById(R.id.btnPlay);
        seekBar = (SeekBar) findViewById(R.id.seekBar);
        btnPlay.setOnClickListener(this);
        seekBar.setMax(99);
        seekBar.setOnTouchListener(this);
        mPlay = new MediaPlayer();
        mPlay.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mPlay.setOnBufferingUpdateListener(this);
        mPlay.setOnCompletionListener(this);
        try {
            mPlay.setDataSource(urlData);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

@Override
    public void onPrepared(MediaPlayer mp) {
        if (mPlay != null) {
            mPlay.start();
            btnPlay.setImageResource(R.drawable.pause_icon);
        } else {
            mPlay.pause();
            btnPlay.setImageResource(R.drawable.play);
        }
        mPlay.start();
        primaryUpdateSeekBar();
    }

Function onClick use play

@Override
    public void onClick(View view) {
        if (view.getId() == R.id.btnPlay) {
            try {
                mPlay.prepare();
            } catch (Exception e) {
                e.printStackTrace();
            }
            LenghData = mPlay.getDuration();
            if (!mPlay.isPlaying()) {
                mPlay.start();
                btnPlay.setImageResource(R.drawable.pause_icon);
            } else {
                mPlay.pause();
                btnPlay.setImageResource(R.drawable.play);
            }
            primaryUpdateSeekBar();
        }
    }

Functions of Seekbar

private void primaryUpdateSeekBar() {
        seekBar.setProgress((int) (((float) mPlay.getCurrentPosition() / LenghData) * 100));
        if (mPlay.isPlaying()) {
            Runnable notification = new Runnable() {
                @Override
                public void run() {
                    long totalDuration = mPlay.getDuration();
                    long currentDuration = mPlay.getCurrentPosition();
                    tvTotalTime.setText(Utils.getTimeString(totalDuration));
                    tvCurrentTime.setText(Utils.getTimeString(currentDuration));
                    primaryUpdateSeekBar();
                }
            };
            handler.postDelayed(notification, 1000);
        }

    }

    @Override
    public void onBackPressed() {
        if (mPlay.isPlaying()) {
            mPlay.stop();
        }
        super.onBackPressed();
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        seekBar.setSecondaryProgress(percent);
    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        btnPlay.setImageResource(R.drawable.play);
        seekBar.setProgress(0);
        seekBar.setSecondaryProgress(0);
        tvTotalTime.setText("00:00");
        tvCurrentTime.setText("");
        try {
            playSong(ifChangeCheck);
            mPlay.prepareAsync();
            mPlay.setOnPreparedListener(this);
            mPlay.setLooping(true);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        if (view.getId() == R.id.seekBar) {
            SeekBar seekbar = (SeekBar) view;
            int playPositioninMiliseconds = (LenghData / 100)
                    * seekbar.getProgress();
            mPlay.seekTo(playPositioninMiliseconds);
        }
        return false;
    }

Final

@Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        switch (group.getCheckedRadioButtonId()) {
        case R.id.rad32Kb:
            String aftercheck32 = "";
            int checkLinkIsPlay32 = urlDataSource.lastIndexOf("/") - 3;
            String subString32 = urlDataSource.substring(checkLinkIsPlay32);
            if (subString32.contains("128")) {
                aftercheck32 = urlDataSource.replace("/128/", "/32/").replace(
                        ".mp3", ".m4a");
            } else if (subString32.contains("320")) {
                aftercheck32 = urlDataSource.replace("/320/", "/32/").replace(
                        ".mp3", ".m4a");
            } else if (subString32.contains("m4a")) {
                aftercheck32 = urlDataSource.replace("/m4a/", "/32/");
            }
            ifChangeCheck = aftercheck32;
            try {
                if (mPlay != null) {
                    mPlay.stop();
                    mPlay.reset();
                }
                playSong(ifChangeCheck);
                mPlay.setLooping(true);
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
            break;
        case R.id.rad128Kb:
            try {
                if (mPlay != null) {
                    ifChangeCheck = urlDataSource;
                    mPlay.stop();
                    mPlay.reset();
                }
                playSong(urlDataSource);
                mPlay.setLooping(true);
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
            break;
        case R.id.rad320Kb:
            String aftercheck320 = "";
            int checkLinkIsPlay320 = urlDataSource.lastIndexOf("/") - 3;
            String subLink320 = urlDataSource.substring(checkLinkIsPlay320);
            if (subLink320.contains("/32")) {
                aftercheck320 = urlDataSource.replace("/32/", "/320/").replace(
                        ".m4a", ".mp3");
            } else if (subLink320.contains("128")) {
                aftercheck320 = urlDataSource.replace("/128/", "/320/");
            } else if (subLink320.contains("m4a")) {
                aftercheck320 = urlDataSource.replace("/m4a/", "/320/")
                        .replace(".m4a", ".mp3");
            }
            ifChangeCheck = aftercheck320;
            try {
                if (mPlay != null) {
                    mPlay.stop();
                    mPlay.reset();
                }
                playSong(ifChangeCheck);
                mPlay.setLooping(true);
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
            break;
        case R.id.rad500:
            String aftercheck500 = "";
            int checkLinkIsPlay500 = urlDataSource.lastIndexOf("/") - 3;
            String subLink500 = urlDataSource.substring(checkLinkIsPlay500);
            if (subLink500.contains("/32")) {
                aftercheck500 = urlDataSource.replace("/32/", "/m4a/");

            } else if (subLink500.contains("128")) {
                aftercheck500 = urlDataSource.replace("/128/", "/m4a/")
                        .replace(".mp3", ".m4a");
            } else if (subLink500.contains("320")) {
                aftercheck500 = urlDataSource.replace("/320/", "/m4a/")
                        .replace(".mp3", ".m4a");
            }
            ifChangeCheck = aftercheck500;
            try {
                if (mPlay != null) {
                    mPlay.stop();
                    mPlay.reset();
                }
                playSong(ifChangeCheck);
                mPlay.setLooping(true);
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
            break;
        default:
            break;
        }

    }

Above is all code in class PlayMusicActivity of me... And thanks for helping me

Iris Louis
  • 297
  • 6
  • 19

1 Answers1

0

Call the prepareAsync() method from the playsong method, as it will starting buffering the audio immediately. When enough audio has buffered the onPrepared method will be called and audio will play

private void playSong(String urlData) {
    btnPlay = (ImageButton) findViewById(R.id.btnPlay);
    seekBar = (SeekBar) findViewById(R.id.seekBar);
    btnPlay.setOnClickListener(this);
    seekBar.setMax(99); 
    seekBar.setOnTouchListener(this);
    mPlay = new MediaPlayer();
    mPlay.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mPlay.setOnBufferingUpdateListener(this);
    mPlay.setOnCompletionListener(this);
    try { 
        mPlay.setDataSource(urlData);
        mPlay.prepareAsync();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } 
} 
  • I Edit my code. But Logcat give me error 07-26 01:55:27.326: E/MediaPlayer(1291): stop called in state 4 07-26 01:55:27.326: E/MediaPlayer(1291): error (-38, 0) 07-26 01:55:27.330: E/MediaPlayer(1291): error (1, -2147483648) 07-26 01:55:27.642: E/MediaPlayer(1291): Error (1,-2147483648) 07-26 01:55:27.646: E/MediaPlayer(1291): prepareAsync called in state 4 – Iris Louis Jul 26 '14 at 01:57
  • 1
    You are calling player method in a state where you should not. You have to respect the MediaPlayer state diagram. See http://developer.android.com/reference/android/media/MediaPlayer.html#StateDiagram – joao2fast4u Jul 29 '14 at 00:11
  • @joao2fast4u problem has been solved :D thank you :) – Iris Louis Jul 29 '14 at 01:41