I'm creating a mediaplayer service to play a media file from internet, like this:
public class MyService extends Service{
private static final String TAG = "MyService";
MediaPlayer mediaPlayer;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
Log.d(TAG, "onCreate");
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
#Override
public void onDestroy() {
Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
Log.d(TAG, "onDestroy");
mediaPlayer.stop();
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
Log.d(TAG, "onStart");
String rtsp;
Bundle re= intent.getExtras();
rtsp=re.getString("rtsp");
try {
mediaPlayer.setDataSource(rtsp);
mediaPlayer.prepare();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mediaPlayer.start();
}
}
Now I want to get the seekbar from the activity like this:
SeekBar seekbar= (SeekBar)findviewbyid(R.id.seekbar);
But I can't :( Please help me how to do that!
EDIT
I found another way to solve my problem without using Bind service :)
Here it is:
In your service class, create a static method like this:
public static void setMainActivity(Player_Activity mainActivity)
{
MAIN_ACTIVITY=mainActivity;
}
Ofcourse, you must declare a static varible:
private static Player_Activity MAIN_ACTIVITY;
Next, in your activity, before you call the startService(), you must call this method to set the main activity to your service like this:
MyService.setMainActivity(Player_Activity.this);
Intent myservice= new Intent(this,MyService.class);
startService(myservice);
And finally you can do anything with your activity in your service like this:
final TextView tv_test=(TextView)MAIN_ACTIVITY.findViewById(R.id.textview);
That's all! Hope this help :)
Forgive me if I get some mistake about English ;), my English skill is not good :)
I know that it has been already answered. But I tried the below code which worked for me.May be useful for someone.
public class MediaPlayerService extends Service implements MediaPlayer.OnPreparedListener,MediaPlayer.OnCompletionListener{
String ExactPath;
int total,CurrentPosition;
MediaPlayer mp;
private final IBinder mBinder=new LocalBinder();
public class LocalBinder extends Binder {
MediaPlayerService getService(){
return MediaPlayerService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public void onCreate() {
mp=new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setOnPreparedListener(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
ExactPath=intent.getStringExtra("pos");
PrepareMediaPlayer();
if(!mp.isPlaying()){
mp.start();
}else{
mp.pause();
}
return START_STICKY;
}
public void PrepareMediaPlayer(){
try {
mp.setDataSource(ExactPath);
mp.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}catch (IllegalStateException e){ }
catch(IllegalFormatException e){ }
}
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mp.start();
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
stopSelf();
}
public int seekBarGetCurrentPosition(){ //This method is created to get SongCurrentPosition from mediaplayer for seekbar
if(mp!=null&&mp.isPlaying()){
CurrentPosition=mp.getCurrentPosition();
}
return CurrentPosition;
}
#Override
public void onDestroy() {
if(mp.isPlaying()){
mp.stop();
}
mp.release();
}
}
Note:In service class I had issue in getting MediaPlayer duration. I am not getting correct result when my activity requests duration from service. So I have implemented a method which gets the duration right from the activity. Hope you can fix duration in service itself. But this code worked for me.
Then in your Activity, after onCreate() method.
/**The below method songDuration() is created as substitution for getMediaPlayerDuration() method
* if getMediaPlayerDuration() failed to get the duration from mediaPlayer via service this method
* helps to avoid returning zero or null value . Because it has been observed that service takes
* quite a long time to return a value, if it is called frequently with in a span of seconds say, pressing
* Next button continuously.
*/
public int songDuration(){
MediaMetadataRetriever mmr=new MediaMetadataRetriever();
mmr.setDataSource(path);
String Dur=mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
Integer Duration=Integer.parseInt(Dur);
return Duration;
}
#Override
protected void onStart() {
super.onStart();
Intent intent=new Intent(Player.this,MediaPlayerService.class);
bindService(intent,mServiceConnection, Context.BIND_AUTO_CREATE);
getSeekBarStatus();//This method is called onBinding process so that it gets updated with player.
}
#Override
protected void onStop() {
super.onStop();
if(ServiceBinding){
unbindService(mServiceConnection);
ServiceBinding=false;
}
}
//This method gets the MediaPlayer Duration from service.
public int getMediaPlayerDuration(){
if(ServiceBinding){
if(mediaPlayerServiceObject.mp!=null){
Duration=mediaPlayerServiceObject.seekBarDuration();
}
}
return Duration;
}
//This method get MediaPlayerCurrent Position from service
public int getMediaPlayerCurrentPosition(){
if(ServiceBinding){
if(mediaPlayerServiceObject.mp!=null){
currentPosition=mediaPlayerServiceObject.seekBarGetCurrentPosition();
}
}
return currentPosition;
}
//This method is used to update seekBar status by getting Player Current Position from service.
public void getSeekBarStatus(){
new Thread(new Runnable() {
#Override
public void run() {
int total=songDuration();
int CurrentPosition=0;
seekBar.setMax(total);
while(CurrentPosition<total){
try {
Thread.sleep(1000);
CurrentPosition=getMediaPlayerCurrentPosition();
Log.d(TAG,String.valueOf(CurrentPosition));
} catch (InterruptedException e) {
return;
}seekBar.setProgress(CurrentPosition);
}
}
}).start();
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(final SeekBar seekBar, int ProgressValue, boolean fromUser) {
// if(fromUser){
// mp.seekTo(ProgressValue);
//}
final long Minutes=((ProgressValue/1000)/60);
final int Seconds=((ProgressValue/1000)%60);
SongProgress.setText(Minutes+":"+Seconds);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
private ServiceConnection mServiceConnection=new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
MediaPlayerService.LocalBinder binder=(MediaPlayerService.LocalBinder)iBinder;
mediaPlayerServiceObject=binder.getService();
ServiceBinding=true;
getSeekBarStatus();
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
stopService(PlayerServiceIntent);
onStop();
ServiceBinding=false;
}
};
You are playing media in service so to communicate with service you have to bind activity with service.
For more information about Bind see below document
Click here
EDIT
Also see below tutorial
Click Here
Related
I made a simple music player which can play some songs in the background.
Going to the homescreen and reopen the app through notification works as well.
The only Problem I have is that if I press the back button(going to parent activity) in the music player activity my app crashes. There are two classes, the activity MP3Player.java and the service MP3Service.jave.
I am getting the following error:
java.lang.RuntimeException: Unable to destroy activity {package/package.MP3Player}: java.lang.IllegalArgumentException: Service not registered: package.MP3Player$1#b135b300
Do you know any advide?
Thanks in advance!
EDIT1:
I bound my player like this in my player activity:
MP3Player.java(Activity)
playIntent = new Intent(this, MP3Service.class);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
I used this tutorial and modified it.
EDIT 3:
Now I get this error:
java.lang.RuntimeException: Unable to stop service package.MP3Service#b13a6f80: java.lang.IllegalStateException
MP3Service.java
public void onCreate() {
super.onCreate();
songPosn = 0;
player = new MediaPlayer();
initMusicPlayer();
}
public void initMusicPlayer() {
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
...
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public void setList(ArrayList<Song> theSongs) {
songs = theSongs;
}
public class MusicBinder extends Binder {
MP3Service getService() {
return MP3Service.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return musicBind;
}
#Override
public boolean onUnbind(Intent intent) {
player.stop();
player.release();
return false;
}
public void playSong() {
player.reset();
Song playSong = songs.get(songPosn);
try {
player.setDataSource(getApplicationContext(),
Uri.parse(playSong.getPath()));
} catch (Exception e) {
Log.e("MUSIC SERVICE", "Error setting data source", e);
}
player.prepareAsync();
}
public void pauseMusic() {
if (player.isPlaying()) {
player.pause();
length = player.getCurrentPosition();
}
}
public void resumeMusic() {
if (player.isPlaying() == false) {
player.seekTo(this.length);
player.start();
} else {
Toast.makeText(getApplicationContext(),
"Please select a song to play", Toast.LENGTH_LONG).show();
}
}
public void stopMusic() {
player.stop();
player.release();
player = null;
}
// set the song
public void setSong(int songIndex) {
songPosn = songIndex;
}
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
#Override
public void onDestroy() {
super.onDestroy();
if (player != null) {
try {
player.stop();
player.release();
} finally {
player = null;
}
}
}
MP3Player.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mp3_player);
getActionBar().setDisplayHomeAsUpEnabled(true);
songList = getSongList();
listAdapter = new PlayListAdapter(this, songList);
listMusic.setAdapter(listAdapter);
listMusic.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int pos,
long arg3) {
currentSongPos = pos;
musicSrv.setSong(currentSongPos);
musicSrv.playSong();
}
});
}
private ServiceConnection musicConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicBinder binder = (MusicBinder) service;
musicSrv = binder.getService();
musicSrv.setList(songList);
musicBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
#Override
protected void onStart() {
super.onStart();
if (playIntent == null) {
playIntent = new Intent(this, MP3Service.class);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
}
...
protected void onDestroy() {
if (musicBound) {
stopService(playIntent);
unbindService(musicConnection);
musicSrv = null;
}
super.onDestroy();
}
Service not registered means it wasn't bound to service during unbindService() call.
Read about service lifecycle on : API Guide: Services
EDIT:
Try to add:
protected void onDestroy() {
if(musicBound){
stopService(playIntent);
unbindService(musicConnection);
musicSrv=null;
}
super.onDestroy();
}
EDIT 2:
Sorry my fault, you need to call first stopService() and then unbindService()
The Android documentation for stopService() states:
Note that if a stopped service still has ServiceConnection objects bound to it with the BIND_AUTO_CREATE set, it will not be destroyed
until all of these bindings are removed. See the Service documentation
for more details on a service's lifecycle.
I have 4 activities in my android app.When the first activity is created, it starts music in the background. Now when the user goes from 1st activity to the 2nd activity I want the song to continue without any interruption. The song should stop only when the user is out of the app.
Right now the music stops when I am going out of one activity and starts from the beginning in the next activity.
Keep the player in the background as a static reference. Then let it know if you are moving within the app or out of it. Here is how I would do it. I am using a class named DJ for this purpose.
public class DJ {
private static MediaPlayer player;
private static boolean keepMusicOn;
public static void iAmIn(Context context){
if (player == null){
player = MediaPlayer.create(context, R.raw.music1);
player.setLooping(true);
try{
player.prepare();
}
catch (IllegalStateException e){}
catch (IOException e){}
}
if(!player.isPlaying()){
player.start();
}
keepMusicOn= false;
}
public static void keepMusicOn(){
keepMusicOn= true;
}
public static void iAmLeaving(){
if(!keepMusicOn){
player.pause();
}
}
}
Now from your Activity call the DJ like this.(Let him know if you would like to keep the music on)
public void onPause() {
super.onPause();
DJ.iAmLeaving();
}
public void onResume(){
super.onResume();
DJ.iAmIn(this);
}
public void buttonOnClick(View view){
DJ.keepMusicOn();
Intent intent = new Intent(this, TheOtherActivity.class);
startActivity(intent);
}
I did it this way and I'm pleased with the result:
1st create the service:
public class LocalService extends Service
{
// This is the object that receives interactions from clients. See RemoteService for a more complete example.
private final IBinder mBinder = new LocalBinder();
private MediaPlayer player;
/**
* Class for clients to access. Because we know this service always runs in
* the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder
{
LocalService getService()
{
return LocalService.this;
}
}
#Override
public void onCreate()
{
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
// We want this service to continue running until it is explicitly stopped, so return sticky.
return START_STICKY;
}
#Override
public void onDestroy()
{
destroy();
}
#Override
public IBinder onBind(Intent intent)
{
return mBinder;
}
public void play(int res)
{
try
{
player = MediaPlayer.create(this, res);
player.setLooping(true);
player.setVolume(0.1f, 0.1f);
player.start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void pause()
{
if(null != player && player.isPlaying())
{
player.pause();
player.seekTo(0);
}
}
public void resume()
{
try
{
if(null != player && !player.isPlaying())
{
player.start();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void destroy()
{
if(null != player)
{
if(player.isPlaying())
{
player.stop();
}
player.release();
player = null;
}
}
}
2nd, create a base activity and extend all your activities in witch you wish to play the background music from it:
public class ActivityBase extends Activity
{
private Context context = ActivityBase.this;
private final int [] background_sound = { R.raw.azilum_2, R.raw.bg_sound_5 };
private LocalService mBoundService;
private boolean mIsBound = false;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
doBindService();
}
#Override
protected void onStart()
{
super.onStart();
try
{
if(null != mBoundService)
{
Random rand = new Random();
int what = background_sound[rand.nextInt(background_sound.length)];
mBoundService.play(what);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
#Override
protected void onStop()
{
super.onStop();
basePause();
}
protected void baseResume()
{
try
{
if(null != mBoundService)
{
mBoundService.resume();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
protected void basePause()
{
try
{
if(null != mBoundService)
{
mBoundService.pause();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
private ServiceConnection mConnection = new ServiceConnection()
{
public void onServiceConnected(ComponentName className, IBinder service)
{
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. Because we have bound to a explicit
// service that we know is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
mBoundService = ((LocalService.LocalBinder) service).getService();
if(null != mBoundService)
{
Random rand = new Random();
int what = background_sound[rand.nextInt(background_sound.length)];
mBoundService.play(what);
}
}
public void onServiceDisconnected(ComponentName className)
{
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
// Because it is running in our same process, we should never
// see this happen.
mBoundService = null;
if(null != mBoundService)
{
mBoundService.destroy();
}
}
};
private void doBindService()
{
// Establish a connection with the service. We use an explicit
// class name because we want a specific service implementation that
// we know will be running in our own process (and thus won't be
// supporting component replacement by other applications).
Intent i = new Intent(getApplicationContext(), LocalService.class);
bindService(i, mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
private void doUnbindService()
{
if (mIsBound)
{
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
#Override
protected void onDestroy()
{
super.onDestroy();
doUnbindService();
}
}
And that's it, now you have background sound in all the activities that are extended from ActivityBase.
You can even control the pause / resume functionality by calling basePause() / baseResume().
Don't forget to declare the service in manifest:
<service android:name="com.gga.screaming.speech.LocalService" />
The idea is that you should not play music from the activity itself. On Android, Activities, and other contexts, have life cycles. It means they will live...and die. And when dead, they can't do anything any more.
So you gotta find something with a lifecycle that lasts more than a single activity if you want the music to live longer.
The easiest solution is an Android service. You can find a good thread here : Android background music service
I implemented everything I've found here, but my service is not starting yet.
What I need to do is to start playing a radio station when the user clicks on a button, and only stop it when he clicks it again. I don't want the radio to be stopped if the application get closed.
When I test the code I'm sending, nothing happens.
Manifest:
<service
android:name=".RadioService"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:exported="false"
>
</service>
Service Code:
package com.po.portelaonline.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class RadioService extends Service {
Player player;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return Service.START_NOT_STICKY;
}
#Override
public void onCreate(){
player = new Player();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy(){
player.stopThread();
}
}
Player class code:
package com.po.portelaonline.service;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import com.po.portelaonline.classes.Util;
class Player extends Thread {
volatile boolean running = true;
#Override
public void run() {
MediaPlayer player = new MediaPlayer();
try {
player.setDataSource(Util.getRadioUrl());
player.setOnPreparedListener(oplPlayer);
player.prepareAsync();
while (running) {
Player.sleep(500);
}
player.release();
player = null;
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopThread() {
running = false;
}
OnPreparedListener oplPlayer = new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
};
}
And I'm calling this way:
Intent i = new Intent(getApplicationContext(), RadioService.class);
if(getApplicationContext().startService(i) == null){
findViewById(R.id.btnPlayStop).setBackgroundDrawable(getApplicationContext().getResources().getDrawable(R.drawable.stop));
}else{
getApplicationContext().stopService(i);
findViewById(R.id.btnPlayStop).setBackgroundDrawable(getApplicationContext().getResources().getDrawable(R.drawable.play));
}
Try this code for service class.
You don't need to create MediaPlayer object in separate thread. player.prepareAsync(); is already asynchronous.
EDIT:
The path to the RadioService class into the AndroidManifest.xml should be absolute: android:name="com.po.portelaonline.service.RadioService"
public class RadioService extends Service implements OnPreparedListener, OnErrorListener{
MediaPlayer mPlayer;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startPlayer();
return Service.START_NOT_STICKY;
}
#Override
public void onCreate(){
initMediaPlayer();
}
private void initMediaPlayer () {
mPlayer = new MediaPlayer();
mPlayer.setOnPreparedListener(this);
mPlayer.setOnErrorListener(this);
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setWakeMode(getApplicationContext(),
PowerManager.PARTIAL_WAKE_LOCK);
}
private void startPlayer(){
player.setDataSource(Util.getRadioUrl());
player.prepareAsync();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy(){
mPlayer.release();
}
#Override
public void onPrepared (MediaPlayer mp) {
mp.start();
}
#Override
public boolean onError (MediaPlayer mp, int what, int extra) {
Log.e("RadioService OnError", "what="+what+" extra="+extra);
return false;
}
}
i guess it should be
if(getApplicationContext().startService(i) != null)
instead of if(getApplicationContext().startService(i) == null)
You are immediately stopping the service after you start it.
Am still new to android, but i followed a tutorial online in developing a radio Application, now this is the problem am encountering, i want this radio to keep playing, so that the app user can keep using the app or other application while the radio plays in the background. The radio stops playing when the user leave the streaming page.
private void startPlaying() {
buttonStopPlay.setEnabled(true);
buttonPlay.setEnabled(false);
player.start();
}
private void initializeMediaPlayer() {
player = new MediaPlayer();
try {
player.setDataSource(" radio URL");
player.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
player.start();
}
});
player.prepareAsync();
buttonStopPlay.setEnabled(true);
buttonPlay.setEnabled(true);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
player.setOnBufferingUpdateListener(new OnBufferingUpdateListener() {
public void onBufferingUpdate(MediaPlayer mp, int percent) {
playSeekBar.setSecondaryProgress(percent);
Log.i("Buffering", "" + percent);
}
});
}
#Override
protected void onPause() {
super.onPause();
if (player.isPlaying()) {
player.pause();
buttonStopPlay.setEnabled(false);
buttonPlay.setEnabled(true);
}
}
refer this link
Intent svc=new Intent(this, BackgroundSoundService.class);
startService(svc);
public class BackgroundSoundService extends Service {
private static final String TAG = null;
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.idil);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
I have a service bound to an activity. The activity is a ListView of playable files. The service plays a certain audio file, passed from the Activty. In the previous version I hadn't had the Service bind, so when clicking multiple times on a play element, multiple instances of sounds would occur. I thought I could solve this by binding the service, so I would communicate every time with the same instance, however it still plays multiple files if they are clicked. Maybe i understood the concept of binding wrong, I'm not sure, the android documentation is sometimes a bit vague and misleading. Here is my code, thanks for any input.
Activity:
public class ViewSounds extends ListActivity {
private PlayService myService;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
// Bind Service
Intent intent = new Intent(ViewSounds.this, PlayService.class);
getApplicationContext().bindService(intent, serviceConncetion, BIND_AUTO_CREATE);
// Get list vars
String[] lex_names = getResources().getStringArray(R.array.lex_names);
//final String[] lex_files = getResources().getStringArray(R.array.lex_files);
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_sounds, lex_names));
final ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//int playFile = getResources().getIdentifier(lex_files[position], "raw", getPackageName());
myService.playAudio();
}
});
}
private ServiceConnection serviceConncetion = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
myService = ((PlayService.MyBinder)service).getService();
}
#Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
myService = null;
}
};
#Override
public void onDestroy(){
super.onDestroy();
unbindService(serviceConncetion);
}
}
Service:
public class PlayService extends Service {
MediaPlayer player;
private final IBinder binder = new MyBinder();
#Override
public IBinder onBind(Intent intent) {
return binder;
}
public class MyBinder extends Binder {
PlayService getService() {
return PlayService.this;
}
}
#Override
public void onCreate() {
super.onCreate();
}
public void playAudio(){
// I hardcoded the file name for this preview
player = MediaPlayer.create(this, R.raw.no_harm);
player.setLooping(false); // Set looping
if (!player.isPlaying()) {
player.start();
}
}
public void onStart(Intent intent, int startId){
super.onStart(intent, startId);
Toast.makeText(this,"Service created ...", Toast.LENGTH_LONG).show();
// Get veriable from Activity
// int extras;
// extras = intent.getExtras().getInt("playFile");
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
You should stop playback of previous file before playing another file. In your code you actually creating new MediaPlayer for each new media file.
Here is how your playAudio should look like:
public void playAudio(){
// I hardcoded the file name for this preview
if(player != null){
player.release();
}
player = MediaPlayer.create(this, R.raw.no_harm);
player.setLooping(false); // Set looping
if (!player.isPlaying()) {
player.start();
}
}
But you should avoid creation of new media players for each new playback. You could do this next way:
public void playAudio(){
// I hardcoded the file name for this preview
if(player == null){
player = new MediaPlayer();
}
if(player.isPlaying()){
player.stop();
}
player.reset();
player.setLooping(false);
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){
#Override
void onPrepared(MediaPlayer mp){
mp.play();
}
});
player.prepareAsync();
}
You should also use onSetErrorListener(...) and onSetComlpletionListener(...) for more control over the player. So that your activity can react on state changes in MediaPlayer.