I am building a song player. The issue is with the ImageView for album art not getting updated for songs. When I play the first song, the ImageView is properly set. However when next songs get played, the ImageView isn't updated at all. Even when I play the same song after another song.
Here is my code:
The ImageView album_art and MediaPlayer mp are declared in the MusicPlayer class before onCreate().
onCreate():
protected void onCreate(Bundle savedInstanceState)
{
//other stuff
album_art = findViewById(R.id.album_art);
playSong(); //this method handles the song player
}
playSong():
public void playSong()
{
//other stuff like initializing mp
Bitmap art = getArt();
Bitmap resized = Bitmap.createScaledBitmap(art, 125, 125, true);
album_art.setImageBitmap(resized);
nextSong(); //sets onCompleteListener
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
}
nextSong()
public void nextSong()
{
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//set next song
album_art.setImageDrawable(null);
}
});
}
What I tried so far:
Initializing album_art in playSong() and setting it to null in nextSong().
Setting a non resized image in playSong()
Checked logs and verified that the getArt() function works perfectly.
None of these things were able to set the ImageView with the proper image after the first song.
Related
Hello there, i have just created a basic android app which plays different musics on button tap..
The app just worked fine for the first couple of seconds but when i just keep on tapping and tapping , at some point it stops playing the music and just crashed...
I am unable to figure out what the problem is ..Please help me make it work..
Thanks.
Here is my code :-
public class MainActivity extends AppCompatActivity {
MediaPlayer mediaPlayer;
public void PlayMusic(View view)
{
int ID = view.getId();
String NameID = view.getResources().getResourceEntryName(ID);
int sound= getResources().getIdentifier(NameID,"raw","com.example.pickachu.mypatatap");
mediaPlayer = MediaPlayer.create(this,sound);
mediaPlayer.start();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
The sound is not playing after multiple taps because you must be getting IllegalStateException because you are not releasing the Mediaplayer object and Mediaplayer Lifecycles are not managed properly when you tap multiple times.
You can use setOnCompletionListener(MediaPlayer.OnCompletionListener listener) to release mediaPlayer after completion of sound as:
mediaPlayer = MediaPlayer.create(this,sound);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.reset();
mp.release();
mediaplayer = null;
}
});
mediaPlayer.start();
pass uri instead string
mediaPlayer= MediaPlayer.create(this, Uri.parse(Environment.getExternalStorageDirectory().getPath()+ "/Music/music.mp3"));
mediaPlayer.setLooping(true);
mpintro.start();
I am a beginner. So far I have created an app that counts. I created a button which displays the text but it should also play the whistle sound.
I displayed my java code below.
/**
* Displays the winning team.
*/
public void displayForWinner(String score) {
TextView scoreView = (TextView) findViewById(R.id.textView);
scoreView.setText(String.valueOf(score));
}
To play a short sound effect, create an empty MediaPlayer object:
MediaPlayer mMediaPlayer;
Next, assign a MediaPlayer to it using your context, and sound (Place your sound file under app/src/main/res/raw/) :
mMediaPlayer = MediaPlayer.create(MyActivity.this,R.raw.whistle_sound);
Finally, when you're ready to play your sound, call:
mMediaPlayer.start();
-EDIT-
To make the text change after your sound has completed, use this:
public class MyActivity extends Activity {
MediaPlayer mMediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
mMediaPlayer = MediaPlayer.create(MyActivity.this,R.raw.whistle_sound);
}
public void displayForWinner(String score) {
final String FinalScore = score;
mMediaPlayer.start();
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
TextView scoreView = (TextView) findViewById(R.id.textView);
scoreView.setText(String.valueOf(FinalScore));
}
});
}
}
Also, consider trimming your audio clip to reduce delay.
I want to get paths for videos from server and then play them using a surfaceView.
I can do it if I use another activity class to play videos after received paths. But I am trying to play in the same activity.
I am getting paths in the background using an AsyncTask. This AsyncTask is executed in onCreate() method. After got paths in onPostExecute(), I want to play videos in SurfaceView.
But SurfaceView is created before I receive those paths. So I tried to use SurfaceView's addCallback() in onPostExecute(). But it looks not possible.
How I do this? Using SurfaceView, is there no way to play videos on the same activity after got resource paths from server?
Oh yeah, I found a solution. I will post it here so that it will help to someone like me. Because everywhere I check a solution for this, didn't followed this way.
Your activity class:
public class PlayActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private SurfaceHolder sh;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//getResource is your AsyncTask
//I will not post it here because it is not the problem we had
getResource _gR = new attemptGetStream(p1, p2);
_gR.execute();
//initiate components
SurfaceView sV = (SurfaceView) findViewById(R.id.main);
assert null != sV : "Surface is null";
sV.getHolder().addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder sHolder) {
//this is the solution.
//only assign holder to a variable but don’t initiate MediaPlayer here
//because we don’t have resource paths yet
//we will initiate MediaPlayer in postExecute method and
//attach to this holder from there
sh = sHolder;
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
log("Surface changed");
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
log("Surface destroyed");
}
//this is our method called from onPostExecute() in our getResource AsyncTask
public void play(String path){
//here initiate the MediaPlayer and assign dataSource
//attach the player to sh(which is our surface holder
try{
MediaPlayer mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDisplay(sh);//sh is the surface holder
mMediaPlayer.setDataSource(getApplicationContext(), path);//path is what we got from onPostExecute method in AsyncTask
mMediaPlayer.prepareAsync();//i use prepareAsync method here so it will not hog the phone
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mP.start();
}
});
}catch (Exception e){//use exception types as you like
e.printStackTrace();
}
}
}
Could someone show me or teach me how I can download 5 or more mp3 in a file and playing them in my app. I've searched about it but all of people how has asked this, nothing explained it well. I don't want to download only one mp3, but multiple mp3s in a file.here is main.java
public class StreamingMp3Player extends Activity implements OnClickListener, OnTouchListener, OnCompletionListener, OnBufferingUpdateListener{
private ImageButton buttonPlayPause;
private SeekBar seekBarProgress;
public EditText editTextSongURL;
private MediaPlayer mediaPlayer;
private int mediaFileLengthInMilliseconds; // this value contains the song duration in milliseconds. Look at getDuration() method in MediaPlayer class
private final Handler handler = new Handler();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initView();
}
/** This method initialise all the views in project*/
private void initView() {
buttonPlayPause = (ImageButton)findViewById(R.id.ButtonTestPlayPause);
buttonPlayPause.setOnClickListener(this);
seekBarProgress = (SeekBar)findViewById(R.id.SeekBarTestPlay);
seekBarProgress.setMax(99); // It means 100% .0-99
seekBarProgress.setOnTouchListener(this);
editTextSongURL = (EditText)findViewById(R.id.EditTextSongURL);
editTextSongURL.setText(R.string.testsong_20_sec);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
}
/** Method which updates the SeekBar primary progress by current song playing position*/
private void primarySeekBarProgressUpdater() {
seekBarProgress.setProgress((int)(((float)mediaPlayer.getCurrentPosition()/mediaFileLengthInMilliseconds)*100)); // This math construction give a percentage of "was playing"/"song length"
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(notification,1000);
}
}
#Override
public void onClick(View v) {
if(v.getId() == R.id.ButtonTestPlayPause){
/** ImageButton onClick event handler. Method which start/pause mediaplayer playing */
try {
mediaPlayer.setDataSource(editTextSongURL.getText().toString()); // setup song from http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3 URL to mediaplayer data source
mediaPlayer.prepare(); // you must call this method after setup the datasource in setDataSource method. After calling prepare() the instance of MediaPlayer starts load data from URL to internal buffer.
} catch (Exception e) {
e.printStackTrace();
}
mediaFileLengthInMilliseconds = mediaPlayer.getDuration(); // gets the song length in milliseconds from URL
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
buttonPlayPause.setImageResource(R.drawable.button_pause);
}else {
mediaPlayer.pause();
buttonPlayPause.setImageResource(R.drawable.button_play);
}
primarySeekBarProgressUpdater();
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if(v.getId() == R.id.SeekBarTestPlay){
/** Seekbar onTouch event handler. Method which seeks MediaPlayer to seekBar primary progress position*/
if(mediaPlayer.isPlaying()){
SeekBar sb = (SeekBar)v;
int playPositionInMillisecconds = (mediaFileLengthInMilliseconds / 100) * sb.getProgress();
mediaPlayer.seekTo(playPositionInMillisecconds);
}
}
return false;
}
#Override
public void onCompletion(MediaPlayer mp) {
/** MediaPlayer onCompletion event handler. Method which calls then song playing is complete*/
buttonPlayPause.setImageResource(R.drawable.button_play);
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
/** Method which updates the SeekBar secondary progress by current song loading from URL position*/
seekBarProgress.setSecondaryProgress(percent);
}
You'll need to use 3rd party libraries to support MP3 playback, as it is not included in the standard library. See Wikipedia for a list of alternatives.
For the downloading part, use an URLConnection to get an InputStream on the file and write it to a FileOutputStream. This might help, too: Working unbuffered Streams
I have some videos using videoView. everything is running well, but when the video is finished nothing happens, the phone stay on dark screen waiting to pres play again or the blink back on the phone.
I want that when videos is finished, go back to the activity before. this is my code.
public class chapterone extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.videoplayer);
VideoView videoView =
(VideoView)this.findViewById(R.id.videoView);
MediaController mc = new MediaController(this);
videoView.setMediaController(mc);
videoView.setVideoURI(Uri.parse(
"http://video.com/episode/" +
"cotton1.mp4"));
/* videoView.setVideoPath(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES) +
"/movie.mp4");
*/
videoView.requestFocus();
videoView.start();
}
}
the URL is only an example.
videoView.setOnCompletionListener(completionListener);
OnCompletionListener completionListener=new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.stop();
chapterone.this.finish();
}
};
i hope can help i found this, but i am not sure if is correct uset it
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
#Override
public void onCompletion(MediaPlayer mp){
// invoke your activity here
Intent i = new Intent(chapterone.this, videoserie.class);
startActivity(i);
}
});