Ederson dos Santos
Ederson dos Santos

Reputation: 105

Correct method to use MediaPlayer in android app

sorry my english, but I'm from Brazil and I used the google translator.

Well, I'm struggling in this application where I am trying to make a streaming an online radio, works fine in version 2.2, but version 4.0 does not work. No error occurs, simply does not work. Below is my code.

I appreciate any help.

package com.radiomiriam;
import java.io.IOException;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

public class Main extends Activity {
public String url = "http://69.64.48.96:9880";
public MediaPlayer player = new MediaPlayer();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    play();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

public void stop(){
    Toast.makeText(getApplicationContext(), "Finalizando...", Toast.LENGTH_SHORT).show();
    if(player.isPlaying()){
        player.stop();
    }
}

public void play(){
    if(player.isPlaying()){
        Toast.makeText(getApplicationContext(), "Já está em execução!", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(getApplicationContext(), "Preparando...", Toast.LENGTH_SHORT).show();
        player.setAudioStreamType(AudioManager.STREAM_MUSIC);
        player.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
        try {
            player.setDataSource(url);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            player.prepare();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        player.start();
    }
}

public void onClick(View v) {
    final int id = v.getId();
    switch (id) {
    case R.id.btnPlay:
        play();
        break;
    case R.id.btnStop:
        stop();
        break;
    }
}
}

Hello, excuse my insistence but I still have not found the solution to my problem and do not know how to solve, I have once again asking for your help to solve this problem.

The application runs in versions 2.x and 3.x but not in version 4.x. Below is a link to download the project, to which you can take a look and help me.

http://nsi.inf.br/RadioMiriam.rar (removed)

Upvotes: 5

Views: 9520

Answers (4)

Robert
Robert

Reputation: 148

i downloaded your project and it actually returns error Code: E/MediaPlayer( 1976): error (-38, 0)

It is caused by starting mediaplayer before it is prepared.

I have made few changes and it started to work. You should :

  1. Set onPrepared listener on MediaPlayer (i.e. in onCreate)

    player.setOnPreparedListener(new OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
        }
    });
    
  2. Remove player.start() from your play() method

  3. Set datasource in this way (in your play() method)

    player.setDataSource(this, Uri.parse("http://69.64.48.96:9880/"));
    

It works on my HTC Sensation with Android 4.0.3

If you need any assistance please let me know.

EDIT: i forgot, i also removed

player.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);

It is redundant

Upvotes: 6

Mr.Me
Mr.Me

Reputation: 9286

It is always better in android to do any IO work on a background thread.

And that includes MediaPlayer . but in MediaPlayer case you already have prepareAsync() method to prepare the MediaPlayer in the background for you.

A good way to do that is like this:

package com.radiomiriam;
import java.io.IOException;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

public class Main extends Activity  implements OnPreparedListener{
public String url = "http://69.64.48.96:9880";
public MediaPlayer player = new MediaPlayer();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    play();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

public void stop(){
    Toast.makeText(getApplicationContext(), "Finalizando...", Toast.LENGTH_SHORT).show();
    if(player.isPlaying()){
        player.stop();
    }
}

public void play(){
    if(player.isPlaying()){
        Toast.makeText(getApplicationContext(), "J? est? em execuç?o!", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(getApplicationContext(), "Preparando...", Toast.LENGTH_SHORT).show();
        player.setAudioStreamType(AudioManager.STREAM_MUSIC);
        player.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
        try {
            player.setDataSource(url);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            player.setOnPreparedListener(this);
            player.prepareAsync();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    }
}
@Override
public void onPrepared(MediaPlayer mp) {
    // TODO Auto-generated method stub
    mp.start();
}
public void onClick(View v) {
    final int id = v.getId();
    switch (id) {
    case R.id.btnPlay:
        play();
        break;
    case R.id.btnStop:
        stop();
        break;
    }
}
}

Also it is always a good practice to read the documentations, so here is a link to MediaPlayer API : MediaPlayer

Upvotes: 0

petey
petey

Reputation: 17160

The prepare() call is probably blocking the UI thread (which android 4.0 hates it when you do that)

You will need to this work in a background thread like an asynctask. Here is a anonymous version of implementing AsyncTask to run play() in the background.

public void onClick(View v) {
    final int id = v.getId();
    switch (id) {
    case R.id.btnPlay:
        new AsyncTask<Void, Void, Void>(){
            @Override
            protected Void doInBackground(Void... voids) {
                play();
                return null;
            }
        }.execute();
        break;
    case R.id.btnStop:
        stop();
        break;
    }
}

You will need to read up a bit about MediaPlayer's states (playing, preparing, stopped, etc) to learn why calling prepare will block the UI thread (

for more info on AsyncTasks

Upvotes: 2

Adamantium
Adamantium

Reputation: 118

You haven't set any link between buttons in your .xml file and your code. onClick method is never called even though you are pressing the buttons.

Replace your onCreate method with this:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button playButton = (Button) findViewById(R.id.btnPlay);
    playButton.setOnClickListener(this);
    Button stopButton = (Button) findViewById(R.id.btnStop);
    stopButton.setOnClickListener(this);
    play();
}

Upvotes: 0

Related Questions