musicplayer.MusicActivity.java Source code

Java tutorial

Introduction

Here is the source code for musicplayer.MusicActivity.java

Source

/*   
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package musicplayer;

import java.util.TimerTask;

import musicplayer.MusicService.LocalBinder;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

import com.crossconnect.activity.ArticleActivity;
import com.crossconnect.activity.MainActivity;
import com.crossconnect.activity.audio.AudioPlayerBibleFragment;
import com.crossconnect.activity.audio.AudioPlayerDownloadedFragment;
import com.crossconnect.model.SwordBibleText;
import com.crossconnect.swipeytabs.SwipeyTabFragment;
import com.crossconnect.swipeytabs.SwipeyTabs;
import com.crossconnect.swipeytabs.SwipeyTabsAdapter;
import com.crossconnect.actions.R;

/** 
 * Main activity: shows media player buttons. This activity shows the media player buttons and
 * lets the user click them. No media handling is done here -- everything is done by passing
 * Intents to our {@link MusicService}.
 * */
public class MusicActivity extends FragmentActivity implements OnClickListener {
    /**
     * The URL we suggest as default when adding by URL. This is just so that the user doesn't
     * have to find an URL to test this sample.
     */
    final String SUGGESTED_URL = "http://www.vorbis.com/music/Epoq-Lepidoptera.ogg";

    ImageButton mPlayButton;
    ImageButton mPauseButton;
    ImageButton mSkipButton;
    ImageButton mRewindButton;
    Button mStopButton;
    Button mEjectButton;
    SeekBar mSeekBar;
    TextView mTimeText;
    TextView mTitleText;
    private static final String[] TITLES = { "BIBLE", "MY RESOURCES" };

    private SwipeyTabs mTabs;

    private ViewPager mViewPager;

    private SwipeyTabsPagerAdapter adapter;

    String book;
    int chapter;
    String translation;

    /**
     * Called when the activity is first created. Here, we simply set the event listeners and
     * start the background service ({@link MusicService}) that will handle the actual media
     * playback.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.music_view);

        mPlayButton = (ImageButton) findViewById(R.id.playbutton);
        mPauseButton = (ImageButton) findViewById(R.id.pausebutton);
        mSkipButton = (ImageButton) findViewById(R.id.skipbutton);
        mRewindButton = (ImageButton) findViewById(R.id.rewindbutton);
        //        mStopButton = (Button) findViewById(R.id.stopbutton);
        //        mEjectButton = (Button) findViewById(R.id.ejectbutton);
        mSeekBar = (SeekBar) findViewById(R.id.SeekBar);
        mSeekBar.setOnSeekBarChangeListener(seekBarChangeListener);
        mTitleText = (TextView) findViewById(R.id.songTitleText);
        mTimeText = (TextView) findViewById(R.id.timeText);

        mPlayButton.setOnClickListener(this);
        mPauseButton.setOnClickListener(this);
        mSkipButton.setOnClickListener(this);
        mRewindButton.setOnClickListener(this);
        //        mStopButton.setOnClickListener(this);
        //        mEjectButton.setOnClickListener(this);

        //Start service with initilise, else if bind service was the thing that started
        //then the service will kill itself once unBound
        startService(new Intent(MusicService.ACTION_INITIALISE));

        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        mTabs = (SwipeyTabs) findViewById(R.id.swipeytabs);

        adapter = new SwipeyTabsPagerAdapter(this, getSupportFragmentManager());
        mViewPager.setAdapter(adapter);
        mTabs.setAdapter(adapter);
        mViewPager.setOnPageChangeListener(mTabs);
        mViewPager.setCurrentItem(0);

        try {
            book = getIntent().getExtras().getString("Book");
            chapter = getIntent().getExtras().getInt("Chapter");
            translation = getIntent().getExtras().getString("Translation");
        } catch (NullPointerException e) {
            //Default to John if it isn't called from within the passage
            book = "John";
            chapter = 1;
            translation = "ESV";
        }

        ImageView up = (ImageView) findViewById(R.id.title_bar_icon);
        up.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                Intent i = new Intent(MusicActivity.this, MainActivity.class);
                startActivity(i);
            }

        });

    }

    private class SwipeyTabsPagerAdapter extends FragmentPagerAdapter implements SwipeyTabsAdapter {

        private final Context mContext;

        public SwipeyTabsPagerAdapter(Context context, FragmentManager fm) {
            super(fm);

            this.mContext = context;
        }

        @Override
        public Fragment getItem(int position) {
            if (position == 0) {
                AudioPlayerBibleFragment audioFragment = new AudioPlayerBibleFragment();
                audioFragment.setBibleText(new SwordBibleText(book, chapter, translation));
                return audioFragment;

            }

            if (position == 1) {
                return new AudioPlayerDownloadedFragment();
            }

            //            if (position == 2) {
            //                return new BookmanagerCommentaryFragment();
            //            }

            return SwipeyTabFragment.newInstance(TITLES[position]);
        }

        @Override
        public int getCount() {
            return TITLES.length;
        }

        public TextView getTab(final int position, SwipeyTabs root) {
            TextView view = (TextView) LayoutInflater.from(mContext).inflate(R.layout.swipey_tab_indicator, root,
                    false);
            view.setText(TITLES[position]);
            view.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    mViewPager.setCurrentItem(position);
                }
            });

            return view;
        }

    }

    @Override
    public void onClick(View target) {
        // Send the correct intent to the MusicService, according to the button that was clicked
        if (target == mPlayButton)
            startService(new Intent(MusicService.ACTION_PLAY));
        else if (target == mPauseButton)
            startService(new Intent(MusicService.ACTION_PAUSE));
        else if (target == mSkipButton)
            startService(new Intent(MusicService.ACTION_SKIP));
        else if (target == mRewindButton)
            startService(new Intent(MusicService.ACTION_REWIND));
        else if (target == mStopButton)
            startService(new Intent(MusicService.ACTION_STOP));
        else if (target == mEjectButton) {
            showUrlDialog();
        }
    }

    /** 
      * Shows an alert dialog where the user can input a URL. After showing the dialog, if the user
      * confirms, sends the appropriate intent to the {@link MusicService} to cause that URL to be
      * played.
      */
    void showUrlDialog() {
        AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this);
        alertBuilder.setTitle("Manual Input");
        alertBuilder.setMessage("Enter a URL (must be http://)");
        final EditText input = new EditText(this);
        alertBuilder.setView(input);

        input.setText(SUGGESTED_URL);

        alertBuilder.setPositiveButton("Play!", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dlg, int whichButton) {
                // Send an intent with the URL of the song to play. This is expected by
                // MusicService.
                Intent i = new Intent(MusicService.ACTION_URL);
                Uri uri = Uri.parse(input.getText().toString());
                i.setData(uri);
                startService(i);
            }
        });
        alertBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dlg, int whichButton) {
            }
        });

        alertBuilder.show();
    }

    //Begin binding
    MusicService mService;
    boolean mBound = false;

    /** Defines callbacks for service binding, passed to bindService() */
    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            Log.e("ServiceConnection", "BOUND SERVICE!");
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
            mBound = false;
        }
    };

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }

    class UpdateTimeTask extends TimerTask {

        @Override
        public void run() {
            mService.getCurrentPosition();
            mService.getDuration();
        }

    }

    private Handler mHandler = new Handler();

    private static Runnable mUpdateTimeTask;

    @Override
    public void onResume() {
        super.onResume();
        Log.d("MainActivity", "Starting Refresh Timer");
        mUpdateTimeTask = new Runnable() {

            @Override
            public void run() {
                //             Log.e("MainActivity", "RUN JOB!");
                if (mBound) {
                    int duration = (int) Math.round(((double) mService.getDuration()) / 1000);
                    int curPosition = (int) Math.round(((double) mService.getCurrentPosition()) / 1000);
                    ;
                    //               Log.e("RefreshTimer", "Duration: " + duration + " CurrentPosition:" + curPosition);

                    if (duration != 0 && curPosition != 0) {
                        mSeekBar.setMax(duration);
                        mSeekBar.setProgress(curPosition);
                        mTitleText.setText(mService.getSongTitle());
                        mTimeText.setText(secondsToText(curPosition) + "/" + secondsToText(duration));

                    } else {

                        //TODO: probably should just make it so that stop and start works rather than change this
                        //                  Log.e("MainActivity", "Duration fail");
                        //                  mTitleText.setText("");
                    }

                } else {
                    Intent intent = new Intent(MusicActivity.this, MusicService.class);
                    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
                }
                mHandler.postDelayed(this, 500);
            }

        };
        mUpdateTimeTask.run();
    }

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

        //Stop the looping
        mHandler.removeCallbacks(mUpdateTimeTask);
    }

    // Seek using seek bar
    private OnSeekBarChangeListener seekBarChangeListener = new OnSeekBarChangeListener() {

        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (fromUser == true) {
                Log.e("MainActivity", "Progress:" + progress);
                mService.seekTo(mService.getDuration() * progress / seekBar.getMax());
            }
        }

        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        public void onStopTrackingTouch(SeekBar seekBar) {
        }

    };

    /**
     * utility method to convert seconds to readable text
     * @param seconds
     * @return
     */
    private String secondsToText(int seconds) {
        // If single digit need to pad the seconds with a zero
        String zero = "";
        if ((seconds % 60) < 10) {
            zero = "0";
        }
        return (String.valueOf(seconds / 60) + ":" + zero + String.valueOf((seconds % 60)));
    }

}