【问题标题】:Android background audio with a live audio stream带有实时音频流的 Android 背景音频
【发布时间】:2019-01-01 06:45:22
【问题描述】:

在过去的三天里,我的第一个 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;
        }
    }
}

任何帮助将不胜感激。

【问题讨论】:

    标签: android audio android-service


    【解决方案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) {
    
    
            }
        };
    

    其中service是activityMusicService service;中的音乐服务对象

    【讨论】:

    • 我觉得你简直把我的脑子炸了。我会试一试,看看效果如何。
    • 另外该应用只播放一个静态URL,它不会改变,也不能由用户改变。
    • 要播放不同的歌曲,您需要将歌曲列表传递给服务。如果你想每次播放一首歌曲然后修改 songRequest(String url) 并在方法参数 service.songRequest(url) 方法中传递 url 并播放 songList 的那个 url 瞬间。
    • 什么是必需的进口。自动导入似乎错过了很多。
    • asim 这是您的个人代码还是在某处可用?似乎有很多我没有的 MainActivity 方法调用,一些我没有的常量和一些 UI 元素
    【解决方案2】:

    因此,感谢 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) {
    
            }
        };
    }
    

    服务启动就好了,我只需要学习如何访问服务对象来实现播放暂停功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-16
      • 1970-01-01
      • 2012-07-20
      • 2016-10-13
      • 1970-01-01
      • 2012-12-21
      • 1970-01-01
      • 2016-05-12
      相关资源
      最近更新 更多