简体   繁体   English

音乐播放器的实现

[英]Music player implementation

I am new to Android. 我是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. 我正在尝试创建一个音乐播放器,该音乐播放器将根据计数(由Rc变量控制)和基于按钮顺序(由BitCount变量控制)播放特定的MP3。 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. 我的问题是,当UI处于前景时一切正常,但是当屏幕进入背景时音乐也开始运行(可以让音乐在背景中运行),但是当我再次将UI从后台移到前景时,比单击停止按钮我无法停止音乐,它会连续播放。 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.. 您将必须创建一个名为MediaPlayerService的服务,该服务将处理所有与媒体相关的操作,例如播放,暂停等。

You can read about service over here: http://developer.android.com/guide/components/services.html 您可以在这里阅读有关服务的信息: 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. 如果需要媒体播放器的示例,可以查看RandomMusicPlayer,这是android在android示例项目中提供的优秀媒体播放器示例。

Here is my implementation of MediaPlayerService 这是我对MediaPlayerService的实现

MediaPlayerService Class: 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 Class: 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);
}
}

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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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