Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)

like image 493
Ederson dos Santos Avatar asked Feb 22 '13 20:02

Ederson dos Santos


2 Answers

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

like image 103
Robert Avatar answered Oct 01 '22 15:10

Robert


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

like image 20
petey Avatar answered Oct 01 '22 15:10

petey