【问题标题】:Getting a problem in Media Player Library in android在 android 的媒体播放器库中出现问题
【发布时间】:2020-02-17 17:18:14
【问题描述】:

我正在尝试制作一个音乐应用程序,它可以从 firebase 加载 Song Url、Song name 和 Artist name。我有两个活动,一个是 ExtrasActivity。ExtrasActivity 包含一个 recyclerview,它将歌曲加载到列表中,当我们单击项目时,它会将 songUrl、SongName 和 ArtistName 发送到另一个名为 StackActivity 的活动。我在 StackActivity 中遇到问题,例如播放歌曲时,如果我返回单击并播放另一首歌曲,那么有时它可以正常工作,但有时它会一起播放两首歌曲。 我尝试了很多方法来解决这个问题,但它们都不能正常工作我认为我的 StackActivity 有问题。

这是我的 StackActivity:-

public class StackActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener {

    private MediaPlayer mediaPlayer;
    private Boolean isPlaying = false;

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

        SeekBar Song_playing_seekbar;

        TextView songInfoSong = findViewById(R.id.song_info_song);
        TextView songInfoArtist = findViewById(R.id.song_info_artist);

        songInfoSong.setText(getIntent().getStringExtra("Name"));
        songInfoArtist.setText(getIntent().getStringExtra("Artist"));

        mediaPlayer = new MediaPlayer();

        playSong();

    }

    private void playSong() {
        final FirebaseStorage storage = FirebaseStorage.getInstance();

        StorageReference storageReference = storage.getReferenceFromUrl(getIntent().getStringExtra("SongUrl"));

        storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
            @Override
            public void onSuccess(Uri uri) {

                try {


                    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                    final String url = uri.toString();
                    mediaPlayer.setDataSource(url);
                    mediaPlayer.setOnPreparedListener(StackActivity.this);
                    mediaPlayer.prepareAsync();


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

                }


            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.i("TAg", "aFailed");
            }
        });


    }

    @Override
    public void onPrepared(final MediaPlayer mediaPlayer) {

        CheckIfSongIsPlayingOrNot();

        if (isPlaying == false) {
            mediaPlayer.start();
        } else if (isPlaying == true) {
            mediaPlayer.stop();
        }

    }

    private void CheckIfSongIsPlayingOrNot() {
        if (mediaPlayer.isPlaying()) {
            isPlaying = true;
        } else if (!mediaPlayer.isPlaying()) {
            isPlaying = false;
        }
    }

因此,如果您发现任何问题,请帮助我进行改进。

【问题讨论】:

    标签: java android firebase


    【解决方案1】:

    这是由于每次启动 StackActivity 时都会重新创建 MediaPlayer。我什至想知道为什么这不会每次都发生。更准确地说,旧的MediaPlayer 实例永远不会停止,甚至更重要的是不会发布。您应该仔细查看MediaPlayer docs 以了解这些状态。

    但对于这种特定情况,我会尝试定义一个 MediaPlayer Singleton

    public class MediaPlayerSingleton implements MediaPlayer.OnPreparedListener {
    
        private static MediaPlayerSingleton instance = null;
        private MediaPlayer mediaPlayer = null;
    
        private MediaPlayerSingleton() {
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setOnPreparedListener(this);
        }
    
        public static MediaPlayerSingleton getInstance() {
            if (instance == null) {
                instance = new MediaPlayerSingleton();
            }
            return instance;
        }
    
        @Override
        public void onPrepared(MediaPlayer mediaPlayer) {   
            resume();
        }
    
        /**
         * This will load the given URL into the media player.
         * @param url The URL string from the Firebase Uri.
         */
        public void play(String url) {  
            try {
                mediaPlayer.reset()
                mediaPlayer.setDataSource(url);
                mediaPlayer.prepareAsync();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public void pause() {
            mediaPlayer.pause();
        }
    
        public void resume() {
            mediaPlayer.start();
        }
    
        public void stop() {
            mediaPlayer.stop();
        }
    
        public void release() {
            mediaPlayer.release();
        }
    }
    

    然后您可以在 StackActivity 中使用它。

    public class StackActivity extends AppCompatActivity {
    
        // your onCreate() but leave out the MediaPlayer references
    
        private void playSong() {
            FirebaseStorage storage = FirebaseStorage.getInstance();
            StorageReference storageReference = storage.getReferenceFromUrl(getIntent().getStringExtra("SongUrl"));
    
            storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                @Override
                public void onSuccess(Uri uri) {
                    MediaPlayerSingleton.getInstance().play(uri.toString());
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Log.i("TAg", "aFailed");
                }
            });
        }
    }
    

    但请务必在您的起始活动的onDestroy()(例如ExtrasActivity)中调用此单例的release() 函数,如下所示:

    @Override
    protected void onDestroy() {
        super.onDestroy();
        MediaPlayerSingleton.getInstance().release();
    }
    

    必须这样做才能释放内存。

    只是对我提供的单例示例的附注。这只是一个可以改进的简单示例,例如对 MediaPlayer 实例进行额外的空检查。但它应该给你一点基础。

    【讨论】:

    • 抱歉这么说你能更新我的代码吗?
    • 但是当我点击返回并播放另一首歌曲时出现问题然后它不播放下一首歌曲它只播放一首歌曲
    • 您的意思是当您返回并单击另一首歌曲时它会完全停止播放?
    • 我想做一个功能,比如当我点击 ExtrasActivity 上的歌曲时,它会发送 songUrl Songplayingactivity,如果我点击返回并播放下一首歌曲,它会停止上一首歌曲并像 Spotify 一样播放新歌
    • 我更新了代码。现在它应该停止上一首歌曲并开始加载新歌曲并在之后播放。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-27
    相关资源
    最近更新 更多