Search code examples
androidandroid-service-binding

Error binding MediaPlayer service to Activity


Been following the tutorial below: [1]: http://www.codeproject.com/Articles/258176/Adding-Background-Music-to-Android-App

On the step "Starting, Pausing, Resuming and Stopping the Music Follow the given steps:

Step 1: First bind the service to the activity by calling doBindService on your activity's onCreate as passing an intent to the service."

I have added the binding service by just including: doBindService(); in my onCreate(); method, was wondering why it isn't working? Don't need an in depth explanation, but would be useful to get it working, found the way some parts of the tutorial are worded is a little confusing.

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cct.mad.lab"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="19" />

    <application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >  
    <service android:name=".MusicService" android:enabled="true"/>
    <activity
        android:name="cct.mad.lab.MainMenu"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".GameActivity"
        android:label="@string/app_name" >

     </activity>
</application>

</manifest>

Music Service Class:

package cct.mad.lab;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnErrorListener;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;

public class MusicService extends Service  implements MediaPlayer.OnErrorListener{

private final IBinder mBinder = new ServiceBinder();
MediaPlayer mPlayer;
private int length = 0;

public MusicService() { }

public class ServiceBinder extends Binder {
     MusicService getService()
     {
        return MusicService.this;
     }
}

@Override
public IBinder onBind(Intent arg0){return mBinder;}

@Override
public void onCreate (){
  super.onCreate();

   mPlayer = MediaPlayer.create(this, R.raw.soundtrack);
   mPlayer.setOnErrorListener(this);

   if(mPlayer!= null)
    {
        mPlayer.setLooping(true);
        mPlayer.setVolume(100,100);
    }


    mPlayer.setOnErrorListener(new OnErrorListener() {

  public boolean onError(MediaPlayer mp, int what, int
      extra){

        onError(mPlayer, what, extra);
        return true;
    }
      });
}

@Override
public int onStartCommand (Intent intent, int flags, int startId)
{
     mPlayer.start();
     return START_STICKY;
}

public void pauseMusic()
{
    if(mPlayer.isPlaying())
    {
        mPlayer.pause();
        length=mPlayer.getCurrentPosition();

    }
}

public void resumeMusic()
{
    if(mPlayer.isPlaying()==false)
    {
        mPlayer.seekTo(length);
        mPlayer.start();
    }
}

public void stopMusic()
{
    mPlayer.stop();
    mPlayer.release();
    mPlayer = null;
}

@Override
public void onDestroy ()
{
    super.onDestroy();
    if(mPlayer != null)
    {
    try{
     mPlayer.stop();
     mPlayer.release();
        }finally {
            mPlayer = null;
        }
    }
}

public boolean onError(MediaPlayer mp, int what, int extra) {

    Toast.makeText(this, "music player failed", Toast.LENGTH_SHORT).show();
    if(mPlayer != null)
    {
        try{
            mPlayer.stop();
            mPlayer.release();
        }finally {
            mPlayer = null;
        }
    }
    return false;
}
}

And then finally the Activity from which I am attempting to bind the Service to, GameActivity:

package cct.mad.lab;

import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Window;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class GameActivity extends Activity {

GameView gameView;// Reference the gameView
MusicService musicplayer;

public boolean mIsBound = false;
private MusicService mServ;
private ServiceConnection Scon =new ServiceConnection(){

    public void onServiceConnected(ComponentName name, IBinder
     binder) {
        mServ = ((MusicService.ServiceBinder) binder).getService();
    }

    public void onServiceDisconnected(ComponentName name) {
        mServ = null;
    }
    };

    public void doBindService(){
        Intent bindIntent = new Intent(this,MusicService.class);
         mIsBound = bindService(bindIntent,Scon,this.BIND_AUTO_CREATE);
    }

     public void doUnbindService()
    {
        if(mIsBound)
        {
            unbindService(Scon);
            mIsBound = false;
        }
    }


protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    doBindService();
    Intent recieve = getIntent();
    String message = recieve.getExtras().getString("MESSAGE");
    // remove title bar
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    // Set the layout
    setContentView(R.layout.game_view_container);
    // Get the id of the layout
    RelativeLayout mainscreen = (RelativeLayout) findViewById(R.id.mainscreen);
    // Make the GameView
    gameView = new GameView(this,message);
    // Get  data from intent and config gameView here

    this.doBindService();
    Intent music = new Intent(this,MusicService.class);
    startService(music);

    gameView.setLayoutParams(new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.MATCH_PARENT));
    // Add GameView
    mainscreen.addView(gameView);
}

/* Called when activity is done and should be closed. 
 * The ActivityResult is propagated back to whoever launched via         onActivityResult()
 */
public void finish(){
    Intent returnIntent = new Intent();
    returnIntent.putExtra("GAME_SCORE",(gameView.getHitCount()));
    setResult(RESULT_OK, returnIntent);
    doUnbindService();
    super.finish();
}


}

Solution

  • I edit this answer to make it clean. The problem is that MediaPlayer.create() returns null. According to doc it happens if creation failed, so I guess it is something wrong with file format or file itself. So, please check supported audio formats here.