具有实时音频流的Android背景音频

时间:2019-01-01 06:45:23

标签: android audio android-service

最近三天,我突飞猛进,并绑定了我的第一个android应用程序。这是我最后的障碍。如何让我的应用运行后台服务,使音频继续播放?我尝试了几个示例,但它们基于播放本地(或流式)mp3文件,而不是实时(Icecast)mp3流。

这是我目前的代码,除背景音频外,其他所有功能都可用。

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {

    private ImageButton btn;
    private ImageView img;
    private boolean playPause;
    private MediaPlayer mediaPlayer;

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

        btn = findViewById(R.id.playPause);
        img = findViewById(R.id.radioTower);

        mediaPlayer = new MediaPlayer();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            public boolean onError(MediaPlayer mp, int what, int extra) {
                mp.reset();
                return false;
            }
        });
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            public void onPrepared(MediaPlayer mp) {
                //mp.start();
            }
        });
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!playPause) {
                    if(!mediaPlayer.isPlaying()) {
                        mediaPlayer.start();
                        btn.setBackgroundResource(R.drawable.ic_rounded_pause_button);
                        img.setImageResource(R.drawable.ic_toweron);
                        img.setAlpha(1.0f);
                        playPause = true;
                    }
                } else {
                    if(mediaPlayer.isPlaying()) {
                        mediaPlayer.pause();
                        btn.setBackgroundResource(R.drawable.ic_play_button);
                        img.setImageResource(R.drawable.ic_toweroff);
                        img.setAlpha(0.3f);
                        playPause = false;
                    }
                }
            }
        });

        try {
            mediaPlayer.setDataSource("http://bbcmedia.ic.llnwd.net/stream/bbcmedia_radio2_mf_p");
            mediaPlayer.prepareAsync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected void onStop() {
        super.onStop();

        if (mediaPlayer != null) {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
            }
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

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

        if (mediaPlayer != null) {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.stop();
            }
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }
}

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

使用服务播放音频文件的活动瞬间。 这是简单的代码,说明如何在服务中使用媒体播放器。

public class MusicService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener, MediaPlayer.OnBufferingUpdateListener {

    //region "member variable"
    boolean isServiceRunning = false;
    ArrayList<Song> PlayerList = new ArrayList<>();
    MediaPlayer mediaPlayer;
    int position = 0;
    MainActivity mainActivity;
    private final IBinder mBinder = new LocalBinder();
    int playingMood;
    private final static int MAX_VOLUME = 15;
    Toast toast;
    public static MusicService objService;
    //endregion

    //region "service method"


    @Override
    public void onCreate() {
        objService = this;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        try {
            isServiceRunning = true;

            if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
//                showNotification(false);
            } else if (intent.getAction().equals(Constants.ACTION.PREV_ACTION)) {
                playPrevious();
            } else if (intent.getAction().equals(Constants.ACTION.PLAY_ACTION)) {
                play();

            } else if (intent.getAction().equals(Constants.ACTION.NEXT_ACTION)) {
                playNext();
            } else if (intent.getAction().equals(
                    Constants.ACTION.STOPFOREGROUND_ACTION)) {
                stop();
                stopForeground(true);
                stopSelf();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        isServiceRunning = false;
        objService = null;
    }

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


    //returns the instance of the service
    public class LocalBinder extends Binder {
        public MusicService getServiceInstance() {
            return MusicService.this;
        }
    }

    public void registerClient(MainActivity activity) {
        mainActivity = activity;
    }
    //endregion


    //region "Media player"

    public void SongRequest() {
        try {
            if (mediaPlayer != null) {
                mediaPlayer.release();
                mediaPlayer = null;
            }

            //Handel UI on main activity
            mainActivity.showPlayer();
            mediaPlayer = new MediaPlayer();
            mainActivity.updatePlayerUI();
            prepareMediaPlayer(PlayerList.get(position).getUrl());
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    void showToast(String text) {
        if (toast != null)
            toast.cancel();
        toast = Toast.makeText(App.getContext(), text, Toast.LENGTH_LONG);
        toast.show();
    }


    @Override
    public void onPrepared(MediaPlayer mp) {
        // try {
            mediaPlayer.start();
            mainActivity.checkPlaying(true);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        try {
            mainActivity.sentUpdateBroadcast(true);
            if (playingMood == 1) {
                mediaPlayer.start();
            }
            if (playingMood == 2) {
                playNext();
            }

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        if (mainActivity != null)
            mainActivity.updateProgressBuffer(percent);
        if (percent == 1)
            mainActivity.showPlayer();

    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        try {
            Log.i("MediaPlayer", "error");

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return false;
    }




    void startPrepare(String url) {

        prepareMediaPlayer(url);

    }



    void prepareMediaPlayer(String url) {
        try {
            mediaPlayer.setDataSource(url);
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setOnPreparedListener(MusicService.this);
            mediaPlayer.setOnErrorListener(MusicService.this);
            mediaPlayer.setOnCompletionListener(MusicService.this);
            mediaPlayer.setOnBufferingUpdateListener(MusicService.this);
            mediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //endregion

    //region "media player method"
    public boolean play() {
        if (mediaPlayer != null) {
            switchButton();
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();

                return false;
            } else {
                mediaPlayer.start();
                return true;
            }
        }

        return false;

    }

    void switchButton() {

        mainActivity.checkPlaying(!mediaPlayer.isPlaying());
    }

    public void stop() {
        try {
            if (mediaPlayer != null) {
                mediaPlayer.release();
                mediaPlayer = null;
            }
            isServiceRunning = false;
            if (mainActivity != null) {
                mainActivity.ShowPlayer(0);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void playNext() {
        if (position < PlayerList.size() - 1) {
            position++;
            mediaPlayer.stop();
            SongRequest();
        }
    }


    public void playPrevious() {
        if (position > 0) {
            position--;
            mediaPlayer.stop();
            SongRequest();
        }
    }


    public void onError() {

    }


    public void onCompletion() {

    }


    public void onCleanMemory() {

    }


    public void initilizePlayerList(ArrayList<Song> list, int position) {
        this.PlayerList = list;
        this.position = position;
    }

    public boolean isplaying() {

        return mediaPlayer == null ? false : mediaPlayer.isPlaying();
    }

    public boolean isRunning() {

        return isServiceRunning;
    }

    public Song getCurrentSong() {
        if (PlayerList != null && PlayerList.size() != 0 && PlayerList.size() >= position) {
            return PlayerList.get(position);
        }
        return null;
    }

    public MediaPlayer getMediaPlayer() {
        return mediaPlayer;
    }

    public void seekTo(int duration) {
        if (mediaPlayer != null) {
            mediaPlayer.seekTo(duration);
        }
    }

    public int getMood() {
        return playingMood;
    }

    public void setMood(int mood) {
        playingMood = mood;
    }

    public void setVolume(int soundVolume) {
        if (mediaPlayer != null) {
            final float volume = (float) (1 - (Math.log(MAX_VOLUME - soundVolume) / Math.log(MAX_VOLUME)));
            mediaPlayer.setVolume(volume, volume);
        }
    }

    //endregion
}

您可以从这样的活动开始服务。

   public void startMusicService() {
        Intent serviceIntent = new Intent(MainActivity.this, MusicService.class);
        serviceIntent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
        startService(serviceIntent);
        bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
    }

停止服务请使用此代码

public void stopMusicService() {
    if (service != null) {
        try {
            service.stop();
            unbindService(mConnection);
            stopService(new Intent(MainActivity.this, service.getClass()));
            service = null;
        } catch (IllegalArgumentException ex) {
            stopService(new Intent(MainActivity.this, service.getClass()));
            service = null;
            ex.printStackTrace();
        }
    }
}

对于具有活动的绑定服务,请使用此

private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                                       IBinder _service) {

            MusicService.LocalBinder binder = (MusicService.LocalBinder) _service;
            service = binder.getServiceInstance(); //Get instance of your service!
            service.registerClient(MainActivity.this); //Activity register in the service as client for callabcks!
            if (listHolder != null) {
                initilizeSongsList(listHolder.list, listHolder.position);
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {


        }
    };

其中服务是活动MusicService service;中的音乐服务对象

答案 1 :(得分:0)

感谢asim,这是单个实时流URL的有效服务。

public class StreamService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {
    public static final String ACTION_PLAY = "com.example.action.PLAY";
    private static final String STREAM_URL = "...";
    private static final String TEST_URL = "https://www.nasa.gov/mp3/586447main_JFKwechoosemoonspeech.mp3";

    MainActivity mainActivity;
    MediaPlayer mediaPlayer = null;
    WifiManager.WifiLock wifiLock;

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    public class LocalBinder extends Binder {
        public StreamService getServiceInstance() {
            return StreamService.this;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent.getAction().equals(ACTION_PLAY)) {
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
            mediaPlayer.setOnErrorListener(this);
            mediaPlayer.setOnPreparedListener(this);
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            wifiLock = ((WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE))
                    .createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "mylock");
            wifiLock.acquire();
            try {
                // Set the stream URL location
                mediaPlayer.setDataSource(TEST_URL);
                // prepareAsync must be called after setAudioStreamType and setOnPreparedListener
                mediaPlayer.prepareAsync();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return START_STICKY;
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        // ... react appropriately ...
        // The MediaPlayer has moved to the Error state, must be reset!
        return false;
    }

    void switchButton() {
        mainActivity.checkPlaying(!mediaPlayer.isPlaying());
    }

    public boolean play() {
        if (mediaPlayer != null) {
            //switchButton();
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();
                return false;
            } else {
                mediaPlayer.start();
                return true;
            }
        }
        return false;
    }

    public void stop() {
        try {
            if (mediaPlayer != null) {
                mediaPlayer.release();
                mediaPlayer = null;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /** Called when MediaPlayer is ready */
    public void onPrepared(MediaPlayer player) {
        //player.start();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if( wifiLock != null) wifiLock.release();
        if (mediaPlayer != null) mediaPlayer.release();
    }

    public void registerClient(MainActivity activity) {
        mainActivity = activity;
    }

    public boolean isplaying() {

        return mediaPlayer == null ? false : mediaPlayer.isPlaying();
    }
}

主要活动中实现了哪些

public class MainActivity extends AppCompatActivity {

    private ImageButton btn;    // Play | Pause toggle button
    private ImageView img;      // Radio tower image that alternates between on and off
    StreamService service;

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

        // Bind the view buttons to local variables
        btn = findViewById(R.id.playPause);
        img = findViewById(R.id.radioTower);

        startStream();

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (service.isplaying()) {
                    Log.d("pause","Pause Playback");
                } else {
                    Log.d("play", "Start Playback");
                }

            }
        });
    }

    public void startStream() {
        Intent serviceIntent = new Intent(MainActivity.this, StreamService.class);
        serviceIntent.setAction(StreamService.ACTION_PLAY);
        startService(serviceIntent);
        bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
    }

    public void stopStream() {
        if (service != null) {
            try {
                service.stop();
                unbindService(mConnection);
                stopService(new Intent(MainActivity.this, service.getClass()));
                service = null;
            } catch (IllegalArgumentException ex) {
                stopService(new Intent(MainActivity.this, service.getClass()));
                service = null;
                ex.printStackTrace();
            }
        }
    }

    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                                       IBinder _service) {

            StreamService.LocalBinder binder = (StreamService.LocalBinder) _service;
            service = binder.getServiceInstance(); //Get instance of your service!
            service.registerClient(MainActivity.this); //Activity register in the service as client for callabcks!
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {

        }
    };
}

服务开始正常,我只需要学习如何访问服务对象即可实现播放暂停功能。