音乐播放器实施

时间:2014-03-15 13:01:51

标签: java android mp3 audio-player

我是Android新手。我试图创建一个音乐播放器,它将根据计数播放特定的MP3(由Rc变量控制)并基于按钮序列(由BitCount变量控制)应该改变。我点击了一个停止按钮,我可以停止音乐。

我的问题是,当UI处于前台时,一切正常,但是当屏幕进入后台时,音乐也开始运行(它可以让音乐在后台运行)但是当我再次从后台运行我的UI时前景比点击停止按钮我无法停止音乐,它会持续运行。当我正在旋转我的手机时,会发生同样的问题。

代码:

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

}

1 个答案:

答案 0 :(得分:3)

当您关闭应用时,您的活动会被销毁,因此对您的媒体播放器变量的引用会丢失。当您重新创建ur活动时,您将获得一组新的引用,因此您无法阻止它。

您必须创建一个名为MediaPlayerService的服务名称,它将处理所有与媒体相关的操作,如播放,暂停等。

您可以在此处阅读有关服务的信息: http://developer.android.com/guide/components/services.html

如果你想要一个媒体播放器的例子,你可以查看RandomMusicPlayer,这是android在android示例项目中提供的一个优秀的媒体播放器示例。

以下是我的MediaPlayerService实现

MediaPlayerService类:

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类:

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

媒体播放器事件监听器

package com.cyberinsane.musicplayerlibrary;

public interface IMediaPlayer {

public void onAudioPlay();

public void onAudioPause();

public void onAudioStop();

public void onError();

}

最后是我的清单文件

<?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>