简体   繁体   中英

Music player implementation

I am new to Android. I'm trying to create a music player which will play specific MP3 based on the count (controlled by Rc variable) and based on the button sequence (controlled by BitCount variable) should change. And I have one stop button by clicking which I should be able to stop the music.

My problem is everything is working fine when UI is on foreground but when screen goes to background then also music start running (it's OK let music be running on background) but when once again I bring my UI from background to foreground than by clicking stop button I am unable to stop the music, it runs continuously. This same problem is happening when I am rotating my mobile.

Code:

package com.example.tallite;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.app.Activity;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;
public class MainActivity extends Activity   implements OnSeekBarChangeListener  {

    MediaPlayer OurSong;

    public  Handler handler1 = new Handler();   
    Button Start;
    Button Stop;     
    Button Button21;
    Button Button22;

    Button StopButton;
    public int GProgreess=0;
    int Rc=0;
    int BitCount=6;
    int SeekPos=0;
    int Period=500;


    int BreakVar=0;
    Thread myThread ;
    public TextView text1,text2,text3,text4;
    private SeekBar bar;
    private TextView textProgress,textAction;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toast.makeText(this, "onCreate()", Toast.LENGTH_LONG).show();

        text1 = (TextView)findViewById(R.id.textbit1);
        text2 = (TextView)findViewById(R.id.textbit2);
        text3 = (TextView)findViewById(R.id.textbit3);
        text4 = (TextView)findViewById(R.id.textbit4);
        Button21=(Button)findViewById(R.id.button21);
        Button22=(Button)findViewById(R.id.button22);

        StopButton=(Button)findViewById(R.id.buttonstop);
        bar = (SeekBar)findViewById(R.id.seekBar1);
        textProgress = (TextView)findViewById(R.id.textViewProgress);
        OurSong=MediaPlayer.create(MainActivity.this,R.raw.a);
        try {
            OurSong.prepare();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        bar.setOnSeekBarChangeListener(this); // set seekbar listener.
        /*handler1.post(runnable1);
        stopPlaying();*/


        StopButton.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v)
            {   


                stopPlaying();

                BitCount=5;
                handler1.removeCallbacks(runnable1);



            }/****End of on clk******/

        });/*****End of set on clk listener*****/

        Button21.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v)
            {           

                stopPlaying();  
                Rc=0;
                BitCount=13;                 

                 handler1.removeCallbacks(runnable1);

                    handler1.post(runnable1);

            }/****End of on clk******/

        });/*****End of set on clk listener*****/
        Button22.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v)
            {   



                stopPlaying();

                Rc=0;
                BitCount=15;                 

                 handler1.removeCallbacks(runnable1);

                    handler1.post(runnable1);


            }/****End of on clk******/

        });/*****End of set on clk listener*****/







    }

    @Override
    protected void onStart() {
    //the activity is become visible.
    super.onStart();
    /*handler1.removeCallbacks(runnable1);*/

    }
    @Override
    protected void onPause() {
         super.onPause();


        }
    @Override
    protected void onResume() {

    super.onResume();



    }
    @Override
    protected void onStop() {
    //the activity is no longer visible.
    super.onStop();
    Toast.makeText(this, "onStop()", Toast.LENGTH_LONG).show();
    }
    @Override
    protected void onDestroy() {
    //The activity about to be destroyed.
    super.onDestroy();
    Toast.makeText(this, "onDestroy()", Toast.LENGTH_LONG).show();
    }



     private void stopPlaying() 
     {
            if (OurSong != null) 
            {
                OurSong.stop();
                OurSong.release();
                OurSong = null;
           }
     }

/* private void stopPlaying() 
     {

                OurSong.stop();
                OurSong.release();



        }*/



        public Runnable runnable1= new Runnable() {
            @Override
            public void run() {
                if(BitCount==13)
                {
                    text1.setText("1");
                    text2.setText(""+Rc);
                    text3.setText(""+BitCount);
                if(Rc==0||Rc==6||Rc==10)
                {

                    stopPlaying();
                    OurSong=MediaPlayer.create(MainActivity.this,R.raw.a);
                    OurSong.start();



                }


                if(Rc==2||Rc==4||Rc==8||Rc==12)
                {
                    stopPlaying();
                    OurSong=MediaPlayer.create(MainActivity.this,R.raw.b);
                    OurSong.start();


                }
                if(Rc==13)
                {
                    stopPlaying();
                    OurSong=MediaPlayer.create(MainActivity.this,R.raw.c);                   
                    OurSong.start();

                }

                Rc++;
                if(Rc>BitCount)
                {
                    text4.setText(""+Rc);
                    Rc=0;
                }

            }/****End of bitcount=13****/
            if(BitCount==15)
            {
                text1.setText("2");
                text2.setText(""+Rc);
                text3.setText(""+BitCount);
                    if(Rc==0||Rc==8||Rc==12)
                    {
                        stopPlaying();
                        OurSong=MediaPlayer.create(MainActivity.this,R.raw.a);          
                        OurSong.start();


                    }


                    if(Rc==2||Rc==4||Rc==6||Rc==10||Rc==14)
                    {
                        stopPlaying();
                        OurSong=MediaPlayer.create(MainActivity.this,R.raw.b);
                        OurSong.start();

                        /* Toast.makeText(getApplicationContext(), "-",
                      Toast.LENGTH_LONG).show();*/

                    }
                    if(Rc==15)
                    {
                        stopPlaying();
                        OurSong=MediaPlayer.create(MainActivity.this,R.raw.c);               
                        OurSong.start();

                        /*Toast.makeText(getApplicationContext(), "|",
                      Toast.LENGTH_LONG).show();*/

                    }

                    Rc++;
                    if(Rc>BitCount)
                    {
                        text4.setText(""+Rc);
                        Rc=0;
                    }
                }/***End of bitcount=15***/




                    if(BitCount==5)
                    {
                        text1.setText("Rc"+Rc);
                        stopPlaying();
                    }
                    if(BitCount==6)
                    {
                        text1.setText("x"+Rc);
                        stopPlaying();
                    }

                handler1.postDelayed(runnable1, Period);

                }
            };
    public void onProgressChanged(SeekBar seekBar, int progress,
            boolean fromUser) {

        GProgreess=progress+20;

        textProgress.setText("Bit/Minute: "+(progress+20));

    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {


    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

        seekBar.setSecondaryProgress(seekBar.getProgress());
        SeekPos=GProgreess;
        Period=(int)(30000/SeekPos);    
        /*textProgress.setText("Period: "+Period);*/
    }

    @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;
    }

}

When you close your app, ur activity is destroyed and hence reference to ur media player variable is lost. When you recreate ur activity you get a new set of reference and hence ur unable to stop it.

You will have to create a Service name it as MediaPlayerService which will deal with all media related actions like play, pause etc..

You can read about service over here: http://developer.android.com/guide/components/services.html

If you want an example for media player, you can check RandomMusicPlayer, an excellent media player example provided by android in android sample projects.

Here is my implementation of MediaPlayerService

MediaPlayerService Class:

package com.cyberinsane.musicplayerlibrary;

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

public class MediaPlayerService extends Service implements OnCompletionListener, OnPreparedListener, OnErrorListener {

private static final int NOTIFICATION_ID = 1;
public static final String INTENT_URL = "url";

public enum MediaState {
    Playing, Paused, Stopped
}

private MediaState mState = MediaState.Stopped;
private MediaPlayer mPlayer;

private NotificationManager mNotificationManager;

public String mCurrentUrl = "";

public static final String ACTION_TOGGLE_PLAYBACK = "com.cyberinsane.musicplayerlibrary.action.TOGGLE_PLAYBACK";
public static final String ACTION_PLAY = "com.cyberinsane.musicplayerlibrary.action.PLAY";
public static final String ACTION_PAUSE = "com.cyberinsane.musicplayerlibrary.action.PAUSE";
public static final String ACTION_STOP = "com.cyberinsane.musicplayerlibrary.action.STOP";

@Override
public void onCreate() {
    super.onCreate();
    mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null) {
        String action = intent.getAction();
        String url = intent.getExtras().getString(INTENT_URL);
        if (url != null) {
            if (!url.equals(mCurrentUrl)) {
                mCurrentUrl = url;
                mState = MediaState.Stopped;
                relaxResources(true);
                processPlayRequest();
            } else {
                if (action.equals(ACTION_TOGGLE_PLAYBACK)) {
                    processTogglePlaybackRequest();
                } else if (action.equals(ACTION_PLAY)) {
                    processPlayRequest();
                } else if (action.equals(ACTION_PAUSE)) {
                    processPauseRequest();
                } else if (action.equals(ACTION_STOP)) {
                    processStopRequest(false);
                }
            }
        }
    }

    return START_STICKY;
}

private void processTogglePlaybackRequest() {
    if (mState == MediaState.Paused || mState == MediaState.Stopped) {
        processPlayRequest();
    } else {
        processPauseRequest();
    }
}

private void processPlayRequest() {
    try {
        if (mState == MediaState.Stopped) {
            createMediaPlayerIfNeeded();
            mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mPlayer.setDataSource(getApplicationContext(), Uri.parse(mCurrentUrl));
            mPlayer.prepare();

        } else if (mState == MediaState.Paused) {
            mState = MediaState.Playing;
            setUpAsForeground("Playing...");
            if (!mPlayer.isPlaying()) {
                mPlayer.start();

                if (mIMediaPlayer != null) {
                    mIMediaPlayer.onAudioPlay();
                }
            }
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

private void processPauseRequest() {
    if (mState == MediaState.Playing) {
        mState = MediaState.Paused;
        mPlayer.pause();
        relaxResources(false);

        if (mIMediaPlayer != null) {
            mIMediaPlayer.onAudioPause();
        }
    }
}

private void processStopRequest(boolean force) {
    if (mState == MediaState.Playing || mState == MediaState.Paused || force) {
        mState = MediaState.Stopped;
        relaxResources(true);
        stopSelf();
    }
}

private void createMediaPlayerIfNeeded() {
    if (mPlayer == null) {
        mPlayer = new MediaPlayer();
        mPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
        mPlayer.setOnPreparedListener(this);
        mPlayer.setOnCompletionListener(this);
        mPlayer.setOnErrorListener(this);
    } else
        mPlayer.reset();
}

private void relaxResources(boolean releaseMediaPlayer) {
    stopForeground(true);

    if (releaseMediaPlayer && mPlayer != null) {
        mPlayer.reset();
        mPlayer.release();
        mPlayer = null;
    }
}

@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
    Toast.makeText(getApplicationContext(), "Media player error! Resetting.", Toast.LENGTH_SHORT).show();
    Log.e("MusicPlayer", "Error: what=" + String.valueOf(what) + ", extra=" + String.valueOf(extra));

    mState = MediaState.Stopped;
    relaxResources(true);

    if (mIMediaPlayer != null) {
        mIMediaPlayer.onError();
    }
    return true; // true indicates we handled the error
}

@Override
public void onPrepared(MediaPlayer mp) {
    mState = MediaState.Playing;
    updateNotification("Playing...");
    if (!mPlayer.isPlaying()) {
        mPlayer.start();
        if (mIMediaPlayer != null) {
            mIMediaPlayer.onAudioPlay();
        }
    }
}

@Override
public void onCompletion(MediaPlayer mp) {
    mState = MediaState.Stopped;
    relaxResources(true);
    stopSelf();
    if (mIMediaPlayer != null) {
        mIMediaPlayer.onAudioStop();
    }
}

/**
 * Updates the notification.
 */
private void updateNotification(String text) {
    mNotificationManager.notify(NOTIFICATION_ID, buildNotification(text).build());
}

private void setUpAsForeground(String text) {
    startForeground(NOTIFICATION_ID, buildNotification(text).build());
}

private NotificationCompat.Builder buildNotification(String text) {
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this.getApplicationContext());
    builder.setSmallIcon(R.drawable.ic_launcher)
            .setOngoing(true)
            .setContentTitle("Cyberinsane MusicPlayer")
            .setContentText(text)
            .setContentIntent(
                    PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(),
                            MediaPlayerActivity.class), PendingIntent.FLAG_UPDATE_CURRENT))
            .setContentInfo("Awesome");

    return builder;
}

@Override
public void onDestroy() {
    mState = MediaState.Stopped;
    relaxResources(true);
}

public class LocalBinder extends Binder {
    MediaPlayerService getService() {
        return MediaPlayerService.this;
    }
}

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

private final IBinder mBinder = new LocalBinder();
private IMediaPlayer mIMediaPlayer;

public MediaPlayer getMediaPlayer() {
    return mPlayer;
}

public void setIMediaPlayer(IMediaPlayer mediaPlayer) {
    mIMediaPlayer = mediaPlayer;

}

public MediaState getMediaState() {
    return mState;
}

public boolean isPlaying() {
    return (mState == MediaState.Playing);
}

public String getCurrentUrl() {
    return mCurrentUrl;
}

public long duration() {
    if (mPlayer != null) {
        return mPlayer.getDuration();
    }
    return 0;
}

public long position() {
    if (mPlayer != null) {
        return mPlayer.getCurrentPosition();
    }
    return 0;
}

public void seekTo(long position) {
    if (mPlayer != null) {
        mPlayer.seekTo((int) position);
    }
}

}

MediaPlayerActivity Class:

package com.cyberinsane.musicplayerlibrary;

import java.io.File;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class MediaPlayerActivity extends Activity implements IMediaPlayer {

private ImageButton mButtonPlay;
private EditText mEditTextUrl;
private SeekBar mSeekBarProgress;

private boolean mIsBound;
private String mExtStorePath;

private MediaPlayerService mMediaService;

private Handler mSeekHandler = new Handler();

private Runnable mSeekRunnable = new Runnable() {
    @Override
    public void run() {
        seekStartUpdation();
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.media_player_activity);

    mButtonPlay = (ImageButton) findViewById(R.id.buttonPlay);
    mEditTextUrl = (EditText) findViewById(R.id.editTextURL);
    mSeekBarProgress = (SeekBar) findViewById(R.id.seekBarMediaProgress);
    mExtStorePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;

    doBindService();
    initListeners();
}

private void initListeners() {
    mButtonPlay.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            String urlExt = mEditTextUrl.getText().toString();
            if (urlExt != null && !urlExt.equals("")) {
                String url = mExtStorePath + urlExt;
                startService(new Intent(MediaPlayerService.ACTION_TOGGLE_PLAYBACK).putExtra(
                        MediaPlayerService.INTENT_URL, url));
            }
        }
    });

    mSeekBarProgress.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            mMediaService.seekTo(seekBar.getProgress());
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
            // empty
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            // empty
        }
    });
}

@Override
protected void onResume() {
    super.onResume();
    doBindService();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    doUnbindService();
}

@Override
protected void onPause() {
    super.onPause();
    doUnbindService();
}

private ServiceConnection mConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName className, IBinder service) {
        mMediaService = ((MediaPlayerService.LocalBinder) service).getService();
        mMediaService.setIMediaPlayer(MediaPlayerActivity.this);
        setControlState();
    }

    @Override
    public void onServiceDisconnected(ComponentName className) {
        mMediaService = null;
    }
};

private void doBindService() {
    bindService(new Intent(MediaPlayerActivity.this, MediaPlayerService.class), mConnection,
            Context.BIND_AUTO_CREATE);
    mIsBound = true;
}

private void doUnbindService() {
    if (mIsBound) {
        unbindService(mConnection);
        mIsBound = false;
    }
}

@Override
public void onAudioPlay() {
    setPlayerState(true);
}

@Override
public void onAudioPause() {
    setPlayerState(false);
}

@Override
public void onAudioStop() {
    setPlayerState(false);
    mSeekBarProgress.setProgress(0);
}

@Override
public void onError() {
    // handle errors here
}

private void setControlState() {
    if (mMediaService.isPlaying()) {
        mEditTextUrl.setText(mMediaService.getCurrentUrl().replace(mExtStorePath, ""));
        setPlayerState(true);
    } else {
        setPlayerState(false);
    }
}

public void setPlayerState(boolean isPlaying) {
    if (isPlaying) {
        mButtonPlay.setImageResource(R.drawable.ic_pause);
        mSeekBarProgress.setMax((int) mMediaService.duration());
        seekStartUpdation();
    } else {
        mButtonPlay.setImageResource(R.drawable.ic_play);
        seekStopUpdate();
    }
}

public void seekStartUpdation() {
    mSeekBarProgress.setProgress((int) mMediaService.position());
    mSeekHandler.postDelayed(mSeekRunnable, 1000);
}

public void seekStopUpdate() {
    mSeekHandler.removeCallbacks(mSeekRunnable);
}
}

Media Player Event Listener

package com.cyberinsane.musicplayerlibrary;

public interface IMediaPlayer {

public void onAudioPlay();

public void onAudioPause();

public void onAudioStop();

public void onError();

}

And finally my Manifest file

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

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

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.cyberinsane.musicplayerlibrary.MediaPlayerActivity"
        android:label="@string/app_name"
        android:launchMode="singleTask" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service
        android:name="com.cyberinsane.musicplayerlibrary.MediaPlayerService"
        android:exported="false" >
        <intent-filter>
            <action android:name="com.cyberinsane.musicplayerlibrary.action.TOGGLE_PLAYBACK" />
            <action android:name="com.cyberinsane.musicplayerlibrary.action.PLAY" />
            <action android:name="com.cyberinsane.musicplayerlibrary.action.PAUSE" />
            <action android:name="com.cyberinsane.musicplayerlibrary.action.SKIP" />
            <action android:name="com.cyberinsane.musicplayerlibrary.action.REWIND" />
            <action android:name="com.cyberinsane.musicplayerlibrary.action.STOP" />
        </intent-filter>
    </service>
</application>

</manifest>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM