如何避免MediaPlayer对象的多个实例?

时间:2015-03-01 21:21:11

标签: android android-mediaplayer

我正在开发音乐播放器应用程序,当用户点击PlayListFragment列表视图中的项目(歌曲)时,用户会重定向到mediaPlayerFragment并且选择的旋律开始播放。当用户重复该场景时,我认为创建了一个新的mediaPlayer实例,因为有两个同时播放的melodys。 如何避免这个问题?

(我曾尝试将mediaPlayer.create(..)放在onCreate()中,但可能需要做更多工作才能使其正常工作。我还试图创建一个singletonObject但没有成功)< / p>

MediaPlayerFragment.java

public class MediaPlayerFragment extends  Fragment  {

private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

private MediaPlayer mediaPlayer;
private double endTime = 0;
private double startTime = 0;
private int forwardTime = 5000;
private int backwardTime = 5000;
public static int oneTimeOnly = 0;

private SeekBar seekBar;

private ImageButton btnPlay;
private ImageButton btnPause;
private ImageButton btnStop;
private ImageButton btnForward;
private ImageButton btnRewind;

public TextView songInfo;
public TextView txtEndTime;
public TextView txtStartTime;

private Handler mediaHandler = new Handler();

private boolean isPausePressed = false;
private boolean isPlayPressed = false;
private boolean isStopPressed = true;

private OnFragmentInteractionListener mListener;
private Song currentSong;

public static MediaPlayerFragment newInstance(String param1, String param2) {
    MediaPlayerFragment fragment = new MediaPlayerFragment();
    Bundle args = new Bundle();
    args.putString(ARG_PARAM1, param1);
    args.putString(ARG_PARAM2, param2);
    fragment.setArguments(args);
    return fragment;
}

public MediaPlayerFragment() {
    // Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        mParam1 = getArguments().getString(ARG_PARAM1);
        mParam2 = getArguments().getString(ARG_PARAM2);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.fragment_media_player,    container, false);

    getActivity().setTitle("Media Player");

    songInfo = (TextView)view.findViewById(R.id.txt_currentsong);
    txtEndTime = (TextView)view.findViewById(R.id.txt_time_left);
    txtStartTime = (TextView)view.findViewById(R.id.txt_time_start);
    seekBar = (SeekBar)view.findViewById(R.id.seek_bar_elapsed_time);

    btnPlay = (ImageButton)view.findViewById(R.id.btn_play);
    btnPause = (ImageButton)view.findViewById(R.id.btn_pause);
    btnStop = (ImageButton)view.findViewById(R.id.btn_stop);
    btnRewind = (ImageButton)view.findViewById(R.id.btn_previous);
    btnForward = (ImageButton)view.findViewById(R.id.btn_next);

    songInfo.setText(currentSong.getArtist() + " - " + currentSong.getTitle());

    mediaPlayer = MediaPlayer.create(getActivity(), Uri.parse(currentSong.getUri()));

    seekBar.setClickable(false);
    btnPause.setEnabled(false);
    btnStop.setEnabled(false);
    btnForward.setEnabled(false);
    btnRewind.setEnabled(false);

    //Click events!
    btnPause.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
                pause(view);
                isPausePressed = true;
                isPlayPressed = false;
                isStopPressed = false;
            }
        });

    btnPlay.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            play(view);
            isPausePressed = false;
            isPlayPressed = true;
            isStopPressed = false;
        }
    });

    btnStop.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            stop(view);
            isPausePressed = false;
            isPlayPressed = false;
            isStopPressed = true;
        }
    });

    btnForward.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            forward(view);
            isPausePressed = false;
            isPlayPressed = false;
            isStopPressed = false;
        }
    });

    btnRewind.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            rewind(view);
            isPausePressed = false;
            isPlayPressed = false;
            isStopPressed = false;
        }
    });

    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onStartTrackingTouch(SeekBar s) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar s) {

        }

        @Override
        public void onProgressChanged(SeekBar s, int progress, boolean fromUser) {
            if (mediaPlayer != null && fromUser) {
                mediaPlayer.seekTo(progress);

                // Check if pause, play or stop buttons is pressed
                if(!isPausePressed && !isPlayPressed && !isStopPressed) {
                    play(view);
                }
            }
        }

    });

    return view;
}

public void play(View view) {
    //Check if a track has been choosen from playlist...
    if(currentSong.getId() != null) {
        mediaPlayer.start();
        endTime = mediaPlayer.getDuration();
        startTime = mediaPlayer.getCurrentPosition();
        if (oneTimeOnly == 0) {
            seekBar.setMax((int) endTime);
            oneTimeOnly = 1;
        }

        txtEndTime.setText(String.format("%d min, %d sec",
                        TimeUnit.MILLISECONDS.toMinutes((long) endTime),
                        TimeUnit.MILLISECONDS.toSeconds((long) endTime) -
                                TimeUnit.MILLISECONDS.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) endTime)))
        );

        txtStartTime.setText(String.format("%d min, %d sec",
                        TimeUnit.MILLISECONDS.toMinutes((long) startTime),
                        TimeUnit.MILLISECONDS.toSeconds((long) startTime) -
                                TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) startTime)))
        );

        seekBar.setProgress((int) startTime);
        mediaHandler.postDelayed(UpdateSongTime, 100);

        btnPause.setEnabled(true);
        btnStop.setEnabled(true);
        btnRewind.setEnabled(true);
        btnForward.setEnabled(true);
    }
}

private Runnable UpdateSongTime = new Runnable() {
    public void run() {
        startTime = mediaPlayer.getCurrentPosition();
        txtStartTime.setText(String.format("%d min, %d sec",
                        TimeUnit.MILLISECONDS.toMinutes((long) startTime),
                        TimeUnit.MILLISECONDS.toSeconds((long) startTime),
                        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) startTime)))
        );
        seekBar.setProgress((int) startTime);
        mediaHandler.postDelayed(this, 100);
    }
};

public void stop(View view) {
    btnPause.setEnabled(false);
    btnForward.setEnabled(false);
    btnRewind.setEnabled(false);
    btnStop.setEnabled(false);

    mediaPlayer.pause();
    mediaPlayer.seekTo(0);
}

public void pause(View view) {
    mediaPlayer.pause();
    btnPause.setEnabled(false);
    btnPlay.setEnabled(true);
}

public void forward(View view) {
    int temp = (int)startTime;
    if ((temp + forwardTime)<= endTime) {
        startTime = startTime + forwardTime;
        mediaPlayer.seekTo((int) startTime);
    }
}

public void rewind(View view) {
    int temp = (int) startTime;
    if ((temp-backwardTime)> 0) {
        startTime = startTime - backwardTime;
        mediaPlayer.seekTo((int)startTime);
    }
}

public void setSong(Song song) {
    this.currentSong = song;
}

// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
    if (mListener != null) {
        mListener.onFragmentInteraction(uri);
    }
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnFragmentInteractionListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}

public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    public void onFragmentInteraction(Uri uri);
}

}

PlayListFragment.java

public class PlayListFragment extends Fragment {

private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

private PlayListAdapter playListAdapter;
private ListView lstPlayList;
public static ArrayList<Song> storeSongs = new ArrayList<>();

private OnFragmentInteractionListener mListener;

public static PlayListFragment newInstance(String param1, String param2) {
    PlayListFragment fragment = new PlayListFragment();
    Bundle args = new Bundle();
    args.putString(ARG_PARAM1, param1);
    args.putString(ARG_PARAM2, param2);
    fragment.setArguments(args);
    return fragment;
}

public PlayListFragment() {
    // Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        mParam1 = getArguments().getString(ARG_PARAM1);
        mParam2 = getArguments().getString(ARG_PARAM2);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_play_list, container, false);

    getActivity().setTitle("Play List");

    getSongList();
    sort(storeSongs);
    AddToListView(view);

    lstPlayList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Song song = new Song();

            //Get clicked song from listview.
            song = (Song) parent.getAdapter().getItem(position);


            changeToMediaPlayerFragment(song);

        }
    });

    return view;
}

private void getSongList() {
    ContentResolver musicResolver = getActivity().getContentResolver();
    Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);

    if (musicCursor != null && musicCursor.moveToFirst()) {
        //get columns
        int titleColumns = musicCursor.getColumnIndex( MediaStore.Audio.Media.TITLE);
        int idColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media._ID);
        int artistColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
        int uriColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA);

        //Add songs to container (storeSongs).
        do {
            Long thisId = musicCursor.getLong(idColumn);
            String thisTitle = musicCursor.getString(titleColumns);
            String thisArtist = musicCursor.getString(artistColumn);
            String thisUri = musicCursor.getString(uriColumn);

            storeSongs.add(new Song(thisId, thisTitle, thisArtist, thisUri));

        } while (musicCursor.moveToNext());

    }
}

public void changeToMediaPlayerFragment(Song song) {
    MediaPlayerFragment mediaPlayerFragment = MediaPlayerFragment.newInstance("", "");
    mediaPlayerFragment.setSong(song);
    FragmentManager fM = getFragmentManager();
    FragmentTransaction fT = fM.beginTransaction();
    fT.replace(R.id.container, mediaPlayerFragment, null);
    fT.addToBackStack("go to mediaPlayer fragmement");
    fT.commit();
}

private void AddToListView(View view) {
    if (playListAdapter == null) {
        playListAdapter = new PlayListAdapter(getActivity(), storeSongs);
    }

    this.lstPlayList = (ListView) view.findViewById(R.id.listView_play_list);

    lstPlayList.setAdapter(playListAdapter);
    playListAdapter.notifyDataSetChanged();
}

private void sort(ArrayList<Song> songs) {
    Collections.sort(songs, new Comparator<Song>() {
        @Override
        public int compare(Song lhs, Song rhs) {
            return lhs.getArtist().compareTo(rhs.getArtist());
        }
    });
}

// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
    if (mListener != null) {
        mListener.onFragmentInteraction(uri);
    }
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnFragmentInteractionListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}


public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    public void onFragmentInteraction(Uri uri);
}

}

1 个答案:

答案 0 :(得分:0)

正如Dyrborg所指出的,我现在已经让活动负责持有一个PlayListFragment的引用和一个MediaPlayerFragment的引用。

public void changeToPlayListFragment() {
    if (playListFragment == null) {
        playListFragment = PlayListFragment.newInstance("", "");
    }

    if (getCurrentFragment() == 2) {
        return;
    } else {
        FragmentManager fME = getFragmentManager();
        FragmentTransaction fTE = fME.beginTransaction();
        fTE.replace(R.id.container, playListFragment, null);
        fTE.addToBackStack("go to Playlist fragment");
        fTE.commit();
    }
}

 private int getCurrentFragment() {
    Fragment currentFragment = getFragmentManager().findFragmentById(R.id.container);
    if (currentFragment instanceof MediaPlayerFragment) {
        return 1;
    } else if (currentFragment instanceof  PlayListFragment) {
        return 2;
    } else {
        return 0;
    }
}

链接包含一个简单轻量级媒体播放器的所有 java 代码,具有敲门互动&#34; http://pastebin.com/BHVZYLGv&#34;