Получение проблемы в библиотеке медиаплеера в Android - PullRequest
0 голосов
/ 21 октября 2019

Я пытался создать музыкальное приложение, которое загружает URL-адрес песни, имя песни и имя исполнителя из firebase. У меня есть два действия, одно из которых - ExtrasActivity .ExtrasActivity содержит представление переработчика, которое загружает песню в список, и когда мы нажимаем на элемент, оно отправляет 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;
        }
    }

Так что если вы найдете какие-либоПроблема, пожалуйста, помогите мне улучшить это.

1 Ответ

0 голосов
/ 22 октября 2019

Это связано с тем, что MediaPlayer воссоздается при каждом запуске StackActivity. Мне даже интересно, почему это не происходит каждый раз. Точнее, старый экземпляр MediaPlayer никогда не останавливается и даже не выпускается. Вы должны более внимательно изучить документы MediaPlayer , чтобы понять состояния.

Но для этого конкретного случая я бы попытался определить 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");
            }
        });
    }
}

Но обязательно вызовите функцию release() этого синглтона в вашей начальной активности onDestroy() (например, ExtrasActivity) вот так:

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

Это нужно сделать, чтобы освободить память.

Просто примечание к приведенному мною одиночному примеру. Это простой пример, который можно улучшить, например, с помощью дополнительных нулевых проверок для экземпляра MediaPlayer. Но это должно дать вам небольшую базу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...