Android comes equipped with a built-in media player API. For one of the projects, I had to customize the Android Media player to:
– re-skin UI
– Retrieve the media from a remote URL source
– integrate Twitter, Facebook and Email support
– play, pause, stop modes for the media player

NOTE: Regard this post, MORE SO on coding the media player, rather than the social integration of Twitter and Facebook.

Screenshot

File: media_player_view.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_gravity="center"
	android:background="@drawable/background" android:layout_width="fill_parent"
	android:layout_height="fill_parent">

	<FrameLayout android:layout_alignParentTop="true"
		android:id="@+id/top_fragment" android:layout_width="wrap_content"
		android:layout_height="wrap_content">
		<ImageView android:id="@+id/mixTapeHeaderLogo" android:src="@drawable/mix_tape_header_logo"
			android:layout_gravity="center" android:layout_width="wrap_content"
			android:paddingTop="50dip" android:layout_height="wrap_content" />
		<include layout="@layout/top_event_date_fragment"
			android:layout_width="wrap_content" android:layout_height="wrap_content"
			android:paddingBottom="30dip" />
	</FrameLayout>

	<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
		android:id="@+id/scrollView" android:layout_width="fill_parent"
		android:layout_below="@+id/top_fragment" android:layout_above="@+id/social_media_mix_fragment"
		android:layout_height="wrap_content">
		<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
			android:paddingLeft="20dip" android:paddingRight="20dip"
			android:orientation="vertical" android:layout_width="fill_parent"
			android:layout_height="wrap_content">
			<TextView android:id="@+id/musicMixTitle" android:gravity="center"
				android:paddingBottom="10dip" android:text="Song Name"
				android:textColor="@color/brown" android:textStyle="bold"
				android:textSize="32sp" android:layout_width="fill_parent"
				android:layout_height="wrap_content" />
			<TextView android:id="@+id/musicMixArtist" android:gravity="center"
				android:paddingBottom="30dip" android:text="Song Artist"
				android:textColor="@color/brown" android:textStyle="bold"
				android:textSize="14sp" android:layout_width="fill_parent"
				android:layout_height="wrap_content" />

			<include layout="@layout/media_player_fragment" android:id="@+id/media_player_fragment"
				android:layout_gravity="center" android:layout_width="fill_parent"
				android:layout_height="wrap_content" />

			<TextView android:id="@+id/malibu_disclaimer_fragment_textview"
				android:text="@string/static_malibu_disclaimer_text"
				android:textColor="@color/brown" android:gravity="center"
				android:paddingTop="10dip" android:paddingBottom="10dip"
				android:layout_width="wrap_content" android:layout_height="wrap_content" />
		</LinearLayout>
	</ScrollView>

	<include layout="@layout/social_media_mix_fragment" android:id="@+id/social_media_mix_fragment"
		android:layout_gravity="center" android:layout_alignParentBottom="true"
		android:layout_width="fill_parent" android:layout_height="wrap_content" />
</RelativeLayout>

File: media_player_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/mediaPlayerLayout" android:orientation="vertical"
	android:paddingBottom="80dip" android:gravity="center"
	android:layout_width="fill_parent" android:layout_height="wrap_content">

	<LinearLayout android:orientation="horizontal"
		android:gravity="center" android:layout_width="fill_parent"
		android:layout_height="wrap_content">

		<ImageView android:id="@+id/mediaStopButton" android:src="@drawable/media_stop_button_selector"
			android:paddingLeft="10dip" android:paddingRight="10dip"
			android:layout_width="wrap_content" android:layout_height="wrap_content" />

		<ImageView android:id="@+id/mediaPlayButton" android:src="@drawable/media_play_button_selector"
			android:paddingLeft="10dip" android:paddingRight="10dip"
			android:layout_width="wrap_content" android:layout_height="wrap_content" />
			
		<ImageView android:id="@+id/mediaPauseButton" android:src="@drawable/media_pause_button_selector"
			android:paddingLeft="10dip" android:paddingRight="10dip"
			android:layout_width="wrap_content" android:layout_height="wrap_content" />

	</LinearLayout>
</LinearLayout>

File: MediaPlayerView.java

package com.malibu.views.mediaplayer;

import java.io.IOException;

import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.Facebook.DialogListener;
import com.facebook.android.FacebookError;
import com.pernod_ricard.malibu_rum.android.R;
import com.malibu.app.config.Config;
import com.malibu.app.legal.TermsAndConditionsScreen;
import com.malibu.app.utils.AuthHttpRequest;
import com.malibu.controllers.social.Twitter;
import com.malibu.models.music.MusicMix;

/**
 * @author wdavid01
 * 
 */
public class MediaPlayerScreen extends Activity implements OnClickListener, OnSeekBarChangeListener
  {
    private static final String tag = MediaPlayerScreen.class.getName();
    private Context context;

    private MediaPlayer mMediaPlayer = null;
    private int playbackPosition = 0;
    private boolean hasPressedPlayed = false;
    private boolean hasPressedPaused = false;
    private boolean hasPressedStopped = false;
    private final boolean hasPressedRewind = false;
    private final boolean hasPressedForward = false;

    // Control buttons
    private ImageView stopButton = null;
    private ImageView playButton = null;
    private ImageView pauseButton = null;

    // Social media buttons
    private TextView disclaimer;
    private ImageView socialMediaFacebookButton = null;
    private ImageView socialMediaTwitterButton = null;
    private ImageView socialMediaEmailButton = null;

    // Remote Music File
    private String mediaUrl = "http://akamai.mindblossom.net/malibu/music/malibu.mp3";
    private TextView topEventDateTextview;
    private SharedPreferences prefs;
    private Facebook facebook;
    private AsyncFacebookRunner asyncRunner;

    private final Handler handler = new Handler();
    private final Runnable runner = new Runnable()
      {
        @Override
        public void run()
          {
            setData();
          }
      };
    private MusicMix mix;
    private ProgressDialog dialog;
    private TextView socialMediaShare;
    private TextView musicMixTitle;
    private TextView musicMixArtist;

    @Override
    public void onCreate(Bundle savedInstanceState)
      {
        super.onCreate(savedInstanceState);
        Log.d(tag, getResources().getString(R.string.CREATING_VIEW) + MediaPlayerScreen.class.getName());
        setContentView(R.layout.media_player_view);
        context = this;

        prefs = getSharedPreferences(Config.PREFS, Context.MODE_PRIVATE);

        facebook = new Facebook(Config.FACEBOOK_APP_ID);
        facebook.setAccessToken(prefs.getString(Config.FACEBOOK_ACCESS_TOKEN, null));
        facebook.setAccessExpires(prefs.getLong(Config.FACEBOOK_EXPIRES, 0));

        asyncRunner = new AsyncFacebookRunner(facebook);

        topEventDateTextview = (TextView) findViewById(R.id.top_event_date_textview);
        topEventDateTextview.setText(prefs.getString(Config.PREFS_CURRENT_EVENT_TITLE, ""));

        socialMediaShare = (TextView) findViewById(R.id.social_media_share);
        socialMediaShare.setOnClickListener(this);

        musicMixTitle = (TextView) findViewById(R.id.musicMixTitle);
        musicMixArtist = (TextView) findViewById(R.id.musicMixArtist);

        // Initial Play button
        pauseButton = (ImageView) this.findViewById(R.id.mediaPauseButton);
        pauseButton.setOnClickListener(this);
        playButton = (ImageView) this.findViewById(R.id.mediaPlayButton);
        playButton.setOnClickListener(this);
        stopButton = (ImageView) this.findViewById(R.id.mediaStopButton);
        stopButton.setOnClickListener(this);
        // Init bottom navigation fragment
        initBottomNavigationFragment();

        getData();
      }

    @Override
    public void onDestroy()
      {
        super.onDestroy();
        Log.d(tag, getResources().getString(R.string.DESTROYING_VIEW));
        killMediaPlayer();
      }

    public void getData()
      {
        dialog = ProgressDialog.show(this, "", getResources().getString(R.string.Loading));
        Thread thread = new Thread()
          {

            @Override
            public void run()
              {
                try
                  {
                    JsonParser jp = AuthHttpRequest.getJsonParser("musicMix", "mix");
                    ObjectMapper mapper = new ObjectMapper();

                    mix = mapper.readValue(jp, MusicMix.class);
                    handler.post(runner);
                  }
                catch (JsonParseException e)
                  {
                    e.printStackTrace();
                  }
                catch (JsonMappingException e)
                  {
                    e.printStackTrace();
                  }
                catch (IOException e)
                  {
                    e.printStackTrace();
                  }
              }
          };
        thread.start();
      }

    private void setData()
      {
        if (mix != null)
          {
            musicMixArtist.setText(mix.attendeeName);
            musicMixTitle.setText(mix.name);
            mediaUrl = mix.url;
          }
        dialog.dismiss();
      }

    private void initBottomNavigationFragment()
      {
        disclaimer = (TextView) this.findViewById(R.id.malibu_disclaimer_fragment_textview);
        disclaimer.setOnClickListener(this);
        socialMediaFacebookButton = (ImageView) this.findViewById(R.id.social_media_facebook);
        socialMediaFacebookButton.setOnClickListener(this);
        socialMediaTwitterButton = (ImageView) this.findViewById(R.id.social_media_twitter);
        socialMediaTwitterButton.setOnClickListener(this);
        socialMediaEmailButton = (ImageView) this.findViewById(R.id.social_media_email);
        socialMediaEmailButton.setOnClickListener(this);
      }

    private void killMediaPlayer()
      {
        Log.d(tag, "Closing MediaPlayer ....!");
        if (mMediaPlayer != null)
          {
            try
              {
                Log.d(tag, "Releasing MediaPlayer ....!");
                mMediaPlayer.release();
              }
            catch (Exception e)
              {
                Log.d(tag, e.getMessage());
              }
          }
      }

    private void startPlay(String url) throws IllegalArgumentException, IllegalStateException, IOException
      {

        Log.d(tag, mediaUrl);

        if (hasPressedPaused == true && hasPressedPlayed == true)
          {

            playbackPosition = mMediaPlayer.getCurrentPosition();
            Log.d(tag, "Resume @: " + playbackPosition);
            mMediaPlayer.seekTo(playbackPosition);
            mMediaPlayer.start();
          }
        else if (hasPressedStopped == true)
          {
            Log.d(tag, "Start...");
            killMediaPlayer();

            Log.d(tag, "Starting MediaPlayer ....!");

            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDataSource(mediaUrl);
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            hasPressedPlayed = true;
          }
        else
          {
            Log.d(tag, "Start...");
            killMediaPlayer();

            Log.d(tag, "Starting MediaPlayer ....!");
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDataSource(mediaUrl);
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            hasPressedPlayed = true;
          }
      }

    private void pause()
      {
        Log.d(tag, "Pausing media player...");
        mMediaPlayer.pause();
        playbackPosition = mMediaPlayer.getCurrentPosition();
        hasPressedPaused = true;
      }

    @Override
    public void onClick(View v)
      {
        if (v == disclaimer)
          {
            Intent intent = new Intent(this, TermsAndConditionsScreen.class);
            startActivity(intent);
          }

        if (v == playButton)
          {
            try
              {
                startPlay(getMediaUrl());
              }
            catch (IllegalArgumentException e)
              {
                e.printStackTrace();
              }
            catch (IllegalStateException e)
              {
                e.printStackTrace();
              }
            catch (IOException e)
              {
                e.printStackTrace();
              }
          }
        if (v == pauseButton)
          {
            if (mMediaPlayer != null)
              {
                Log.d(tag, "MediaPlayer paused...");
                pause();
              }
          }
        if (v == stopButton)
          {
            if (mMediaPlayer != null)
              {
                Log.d(tag, "MediaPlayer stopped...");
                mMediaPlayer.stop();
                hasPressedPlayed = false;
                hasPressedStopped = true;
                playbackPosition = 0;
              }
          }

        // social media
        if (v == socialMediaFacebookButton)
          {
            Log.d(tag, getResources().getString(R.string.VIEW_CLICKED) + "Facebook Connect ...");
            Toast.makeText(this, "Facebook Connect", Toast.LENGTH_SHORT).show();

            String description = "I'm listening to " + mix.name + " by " + mix.attendeeName + ".";

            Bundle params = new Bundle();
            params.putString("description", description);
            params.putString("link", mix.musicMixUrl);

            facebook.dialog(this, "stream.publish", params, new DialogListener()
              {
                @Override
                public void onComplete(Bundle values)
                  {
                  }

                @Override
                public void onFacebookError(FacebookError e)
                  {
                  }

                @Override
                public void onError(DialogError e)
                  {
                  }

                @Override
                public void onCancel()
                  {
                  }
              });
          }

        if (v == socialMediaTwitterButton)
          {
            String tweet = "IÕm listening to " + mix.name + " by " + mix.attendeeName + ". " + mix.musicMixUrl + " via #stationinvasion";
            new Twitter(this, tweet);
          }

        if (v == socialMediaEmailButton)
          {
            Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
            String description = "I'm listening to " + mix.name + " by " + mix.attendeeName + ".\n\n" + mix.musicMixUrl;

            emailIntent.setType("plain/text");
            emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Listening to a music mix | Malibu Station Invasion");
            emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, description);

            startActivity(Intent.createChooser(emailIntent, "Send mail..."));
          }
      }

    private void setMediaUrl(String mediaUrl)
      {
        this.mediaUrl = mediaUrl;
      }

    private String getMediaUrl()
      {
        return mediaUrl;
      }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
      {
        seekBar.setProgress(mMediaPlayer.getCurrentPosition());
      }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar)
      {
        // TODO Auto-generated method stub

      }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar)
      {
        // TODO Auto-generated method stub

      }
  }
Advertisements