diff --git a/app/src/main/java/com/example/musicplayer/adapter/SongAdapter.java b/app/src/main/java/com/example/musicplayer/adapter/SongAdapter.java index 17ec1de..ca7f450 100644 --- a/app/src/main/java/com/example/musicplayer/adapter/SongAdapter.java +++ b/app/src/main/java/com/example/musicplayer/adapter/SongAdapter.java @@ -113,8 +113,9 @@ public class SongAdapter extends RecyclerView.Adapter { Log.d("jsysjt","------"+song.getArtist()+"/"+song.getTitle()+"/"+song.getDuration()+"/"+song.getSize()); FileHelper.saveSong(song); + onItemClickListener.onSongClick(position); equalPosition(position); - onItemClickListener.onSongClick(); + @@ -147,7 +148,7 @@ public class SongAdapter extends RecyclerView.Adapter { public interface OnItemClickListener{ - void onSongClick(); + void onSongClick(int position); } } diff --git a/app/src/main/java/com/example/musicplayer/entiy/Song.java b/app/src/main/java/com/example/musicplayer/entiy/Song.java index f501b1e..8acbc1e 100644 --- a/app/src/main/java/com/example/musicplayer/entiy/Song.java +++ b/app/src/main/java/com/example/musicplayer/entiy/Song.java @@ -14,6 +14,7 @@ public class Song implements Serializable { private String title; private long size; private String url; + private long currentTime; public long getSize() { return size; @@ -55,9 +56,17 @@ public class Song implements Serializable { this.url = url; } + public long getCurrentTime() { + return currentTime; + } + + public void setCurrentTime(long currentTime) { + this.currentTime = currentTime; + } + public String toString(){ return - "artist="+artist+",title="+title+",url="+url+",duration="+duration+",size"+size; + "artist="+artist+",title="+title+",url="+url+",duration="+duration+",size"+size+",currentTime="+currentTime; } } diff --git a/app/src/main/java/com/example/musicplayer/service/PlayerService.java b/app/src/main/java/com/example/musicplayer/service/PlayerService.java index 8e383b0..e87b933 100644 --- a/app/src/main/java/com/example/musicplayer/service/PlayerService.java +++ b/app/src/main/java/com/example/musicplayer/service/PlayerService.java @@ -11,27 +11,56 @@ import android.os.Message; import android.util.Log; import com.example.musicplayer.constant.PlayerStatus; +import com.example.musicplayer.entiy.Mp3Info; import com.example.musicplayer.entiy.Song; import com.example.musicplayer.util.FileHelper; +import com.example.musicplayer.util.MediaUntil; +import java.util.List; + +import static android.content.ContentValues.TAG; import static com.example.musicplayer.constant.PlayerStatus.PAUSE; import static com.example.musicplayer.constant.PlayerStatus.STOP; @SuppressLint("NewApi") public class PlayerService extends Service { + private static final String TAG="PlayerService"; private PlayStatusBinder mPlayStatusBinder = new PlayStatusBinder(); private MediaPlayer mediaPlayer = new MediaPlayer(); //媒体播放器对象 private boolean isPause; //暂停状态 private Song song; private boolean isPlaying; //是否播放 + private List mMp3InfoList; + private int mCurrent; + @Override + public void onCreate(){ + mMp3InfoList= MediaUntil.getMp3Info(); + } @Override public IBinder onBind(Intent arg0) { + Log.d(TAG, "-------onBind: "); + + mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override + public void onCompletion(MediaPlayer mp) { + mCurrent++; + if(mCurrent<=mMp3InfoList.size()){ + mPlayStatusBinder.play(0); + } + } + }); return mPlayStatusBinder; } + @Override + public void onRebind(Intent intent){ + Log.d(TAG, "-------onRebind: "); + + } + public class PlayStatusBinder extends Binder { /** * 播放音乐 @@ -39,14 +68,16 @@ public class PlayerService extends Service { * @param */ - public void play() { + + public void play(int currentTime) { try { + song = FileHelper.getSong(); mediaPlayer.reset();//把各项参数恢复到初始状态 - mediaPlayer.setDataSource(song.getUrl()); + mediaPlayer.setDataSource(mMp3InfoList.get(mCurrent).getUrl()); mediaPlayer.prepare(); //进行缓冲 isPlaying=true; - mediaPlayer.start(); + mediaPlayer.setOnPreparedListener(new PreparedListener(currentTime)); } catch (Exception e) { e.printStackTrace(); @@ -99,27 +130,15 @@ public class PlayerService extends Service { return isPlaying; } public MediaPlayer getMediaPlayer(){ - return mediaPlayer; - } - } - /*@Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (mediaPlayer.isPlaying()) { - stop(); + return mediaPlayer; } - path = intent.getStringExtra("url"); - int msg = intent.getIntExtra("MSG", 0); - if (msg ==PlayerStatus.PLAY) { - play(0); - } else if (msg == PAUSE) { - pause(); - } else if (msg ==STOP) { - stop(); + public void setCurrent(int current){ + mCurrent=current; } - return super.onStartCommand(intent, flags, startId); } -*/ + + @Override @@ -128,6 +147,12 @@ public class PlayerService extends Service { mediaPlayer.stop(); mediaPlayer.release(); } + Log.d(TAG, "----onDestroy:PlayerService "); + } + @Override + public boolean onUnbind(Intent intent){ + Log.d(TAG, "-----onUnbind: "); + return true; } /** diff --git a/app/src/main/java/com/example/musicplayer/util/MediaUntil.java b/app/src/main/java/com/example/musicplayer/util/MediaUntil.java new file mode 100644 index 0000000..f09e836 --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/util/MediaUntil.java @@ -0,0 +1,57 @@ +package com.example.musicplayer.util; + +import android.database.Cursor; +import android.provider.MediaStore; + +import com.example.musicplayer.constant.MyApplication; +import com.example.musicplayer.entiy.Mp3Info; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by 残渊 on 2018/10/22. + */ + +public class MediaUntil{ + public static List getMp3Info(){ + List mp3InfoList=new ArrayList<>(); + Cursor cursor = MyApplication.getContext().getContentResolver().query( + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, + MediaStore.Audio.Media.DEFAULT_SORT_ORDER); + for (int i = 0; i < cursor.getCount(); i++) { + Mp3Info mp3Info = new Mp3Info(); + cursor.moveToNext(); + String title = cursor.getString((cursor + .getColumnIndex(MediaStore.Audio.Media.TITLE)));//音乐标题 + String artist = cursor.getString(cursor + .getColumnIndex(MediaStore.Audio.Media.ARTIST));//艺术家 + long duration = cursor.getLong(cursor + .getColumnIndex(MediaStore.Audio.Media.DURATION));//时长 + long size = cursor.getLong(cursor + .getColumnIndex(MediaStore.Audio.Media.SIZE)); //文件大小 + String url = cursor.getString(cursor + .getColumnIndex(MediaStore.Audio.Media.DATA)); //文件路径 + int isMusic = cursor.getInt(cursor + .getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));//是否为音乐 + if (isMusic != 0) {//只把音乐添加到集合当中 + if (size > 1000 * 800) { + // 注释部分是切割标题,分离出歌曲名和歌手 (本地媒体库读取的歌曲信息不规范) + if (title.contains("-")) { + String[] str = title.split("-"); + artist = str[0]; + title = str[1]; + } + mp3Info.setTitle(title.trim()); + mp3Info.setArtist(artist); + mp3Info.setDuration(duration); + mp3Info.setSize(size); + mp3Info.setUrl(url); + mp3InfoList.add(mp3Info); + } + } + } + cursor.close(); + return mp3InfoList; + } +} diff --git a/app/src/main/java/com/example/musicplayer/view/LocalMusicFragment.java b/app/src/main/java/com/example/musicplayer/view/LocalMusicFragment.java index 0f62c7a..14fbd03 100644 --- a/app/src/main/java/com/example/musicplayer/view/LocalMusicFragment.java +++ b/app/src/main/java/com/example/musicplayer/view/LocalMusicFragment.java @@ -15,6 +15,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.LinearLayout; import android.widget.SeekBar; import android.widget.TextView; @@ -32,6 +33,8 @@ import java.util.List; public class LocalMusicFragment extends Fragment implements ILocalMusicContract.View { + private static final String TAG = "LocalFragment"; + private MediaPlayer mMediaPlayer; private SeekBar mSeekBar; private boolean isChange; //拖动进度条 @@ -40,6 +43,7 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract. private int time; //记录暂停的时间 private Thread mSeekBarThread; private Button mPlayerBtn; + private LinearLayout mPlayerLinear; private TextView mNextTv; private RecyclerView mRecycler; private List mMp3InfoList; @@ -48,6 +52,7 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract. private TextView mSongNameTv; private TextView mSinger; private Song mSong; + private int current;//记录播放歌曲的位置 private SongAdapter songAdapter; //在onServiceConnected中获取PlayStatusBinder的实例,从而调用服务里面的方法 private PlayerService.PlayStatusBinder mPlayStatusBinder; @@ -74,7 +79,6 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract. Bundle savedInstanceState) { mView = inflater.inflate(R.layout.fragment_local_music, container, false); mRecycler = mView.findViewById(R.id.recycler_song_list); - return mView; } @@ -101,7 +105,6 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract. //启动服务 Intent playIntent = new Intent(getActivity(), PlayerService.class); - getActivity().startService(playIntent); getActivity().bindService(playIntent, connection, Context.BIND_AUTO_CREATE); } @@ -109,24 +112,6 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract. //按钮事件 private void setOnClickListener() { - // - songAdapter.setOnItemClickListener(new SongAdapter.OnItemClickListener() { - @Override - public void onSongClick() { - mSong = FileHelper.getSong(); - Log.d("jsyjsy", "----------------" + mSong.getTitle()); - mSongNameTv.setText(mSong.getTitle()); - mSinger.setText(mSong.getArtist()); - mPlayStatusBinder.play(); - mMediaPlayer = mPlayStatusBinder.getMediaPlayer(); - - mPlayerBtn.setSelected(true); - mSeekBar.setMax((int) mSong.getDuration()); - mSeekBarThread = new Thread(new SeekBarThread()); - mSeekBarThread.start(); - } - }); - //进度条的监听事件 mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override @@ -176,12 +161,31 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract. mSeekBarThread = new Thread(new SeekBarThread()); mSeekBarThread.start(); } else { + mPlayStatusBinder.play((int) mSong.getCurrentTime()); + mPlayerBtn.setSelected(true); mSeekBarThread = new Thread(new SeekBarThread()); mSeekBarThread.start(); } } }); + // + songAdapter.setOnItemClickListener(new SongAdapter.OnItemClickListener() { + @Override + public void onSongClick(int position) { + mSong = FileHelper.getSong(); + Log.d("jsyjsy", "----------------" + mSong.getTitle()); + mSongNameTv.setText(mSong.getTitle()); + mSinger.setText(mSong.getArtist()); + mPlayStatusBinder.setCurrent(position); + mPlayStatusBinder.play(0); + mMediaPlayer = mPlayStatusBinder.getMediaPlayer(); + mPlayerBtn.setSelected(true); + mSeekBar.setMax((int) mSong.getDuration()); + mSeekBarThread = new Thread(new SeekBarThread()); + mSeekBarThread.start(); + } + }); } @@ -207,6 +211,19 @@ public class LocalMusicFragment extends Fragment implements ILocalMusicContract. } + @Override + public void onDetach() { + super.onDetach(); + if (mMediaPlayer != null) { + Song song = FileHelper.getSong(); + song.setCurrentTime(mMediaPlayer.getCurrentPosition()); + Log.d(TAG, "onDetach: " + mMediaPlayer.getCurrentPosition()); + FileHelper.saveSong(song); + } + getActivity().unbindService(connection); + } + + class SeekBarThread implements Runnable { @Override public void run() { diff --git a/app/src/main/java/com/example/musicplayer/view/MainActivity.java b/app/src/main/java/com/example/musicplayer/view/MainActivity.java index 792cfea..8cc58e0 100644 --- a/app/src/main/java/com/example/musicplayer/view/MainActivity.java +++ b/app/src/main/java/com/example/musicplayer/view/MainActivity.java @@ -1,54 +1,180 @@ package com.example.musicplayer.view; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.media.MediaPlayer; +import android.os.IBinder; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; +import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.LinearLayout; +import android.widget.SeekBar; import android.widget.TextView; import com.example.musicplayer.R; import com.example.musicplayer.entiy.Song; +import com.example.musicplayer.service.PlayerService; import com.example.musicplayer.util.FileHelper; public class MainActivity extends AppCompatActivity { - private boolean play=false; - private Button playerBtn; + private static final String TAG="MainActivity"; + + private boolean isChange; //拖动进度条 + private boolean isSeek;//标记是否在暂停的时候拖动进度条 + private boolean flag; //用做暂停的标记 + private int time; //记录暂停的时间 + private Button mPlayerBtn; + private TextView mSongNameTv; private TextView mSingerTv; private Song mSong; private LinearLayout mLinear; + private MediaPlayer mMediaPlayer; + private SeekBar mSeekBar; + private Thread mSeekBarThread; + private PlayerService.PlayStatusBinder mPlayStatusBinder; + private ServiceConnection connection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + mPlayStatusBinder = (PlayerService.PlayStatusBinder) service; + } + + @Override + public void onServiceDisconnected(ComponentName name) { + + } + }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); + onClick(); } private void initView(){ mSong= FileHelper.getSong(); mSongNameTv=findViewById(R.id.tv_song_name); mSingerTv=findViewById(R.id.tv_singer); mLinear=findViewById(R.id.linear_player); - if(mSong!=null){ + mSeekBar = findViewById(R.id.sb_progress); + + + + if(mSong.getTitle()!=null){ + //启动服务 + Intent playIntent = new Intent(MainActivity.this, PlayerService.class); + bindService(playIntent, connection, Context.BIND_AUTO_CREATE); + Log.d(TAG, "------initView:bindService "); + mLinear.setVisibility(View.VISIBLE); mSongNameTv.setText(mSong.getTitle()); mSingerTv.setText(mSong.getArtist()); + mSeekBar.setMax((int)mSong.getDuration()); + mSeekBar.setProgress((int)mSong.getCurrentTime()); + }else { mLinear.setVisibility(View.GONE); } - playerBtn=findViewById(R.id.btn_player); + mPlayerBtn=findViewById(R.id.btn_player); addMainFragment(); } + private void onClick(){ + //进度条的监听事件 + mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + //防止在拖动进度条进行进度设置时与Thread更新播放进度条冲突 + isChange = true; + isSeek = true; + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + if (mMediaPlayer.isPlaying()) { + mMediaPlayer.seekTo(seekBar.getProgress()); + } else { + time = seekBar.getProgress(); + } + isChange = false; + mSeekBarThread = new Thread(new SeekBarThread()); + mSeekBarThread.start(); + } + }); + + // + mPlayerBtn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mPlayStatusBinder.isPlaying()) { + time = mMediaPlayer.getCurrentPosition(); + mPlayStatusBinder.pause(); + flag = true; + mPlayerBtn.setSelected(false); + } else if (flag) { + mPlayStatusBinder.resume(); + flag = false; + if (isSeek) { + mMediaPlayer.seekTo(time); + } else { + isSeek = false; + } + + mPlayerBtn.setSelected(true); + mSeekBarThread = new Thread(new SeekBarThread()); + mSeekBarThread.start(); + } else { + mMediaPlayer=mPlayStatusBinder.getMediaPlayer(); + mPlayStatusBinder.play((int)mSong.getCurrentTime()); + mPlayerBtn.setSelected(true); + mSeekBarThread = new Thread(new SeekBarThread()); + mSeekBarThread.start(); + } + } + }); + } + private void addMainFragment(){ MainFragment mainFragment=new MainFragment(); FragmentManager fragmentManager=getSupportFragmentManager(); FragmentTransaction transaction=fragmentManager.beginTransaction(); + transaction.addToBackStack(null); transaction.add(R.id.fragment_container,mainFragment); transaction.commit(); } + @Override + public void onDestroy(){ + super.onDestroy(); + + unbindService(connection); + Log.d(TAG, "-----onDestroy: "); + } + class SeekBarThread implements Runnable { + @Override + public void run() { + while (!isChange && mPlayStatusBinder.isPlaying()) { + mSeekBar.setProgress(mMediaPlayer.getCurrentPosition()); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + } diff --git a/app/src/main/java/com/example/musicplayer/view/MainFragment.java b/app/src/main/java/com/example/musicplayer/view/MainFragment.java index 904181f..4a8100a 100644 --- a/app/src/main/java/com/example/musicplayer/view/MainFragment.java +++ b/app/src/main/java/com/example/musicplayer/view/MainFragment.java @@ -23,7 +23,7 @@ import com.example.musicplayer.widget.MyListView; * A simple {@link Fragment} subclass. */ public class MainFragment extends Fragment { - + private static final String TAG = "MainFragment"; private LinearLayout mFunctionLinear; private MyListView myListView; @@ -79,17 +79,21 @@ public class MainFragment extends Fragment { FragmentTransaction transaction = fragmentManager.beginTransaction(); if (mLocalMusicFragment == null) { mLocalMusicFragment = new LocalMusicFragment(); - Log.d("jsyjst","-----------------null"); + Log.d(TAG, "replaceFragment: "); } - //将事务提交到返回栈 - transaction.addToBackStack(null); + //进入和退出动画 transaction.setCustomAnimations(R.anim.fragment_in, R.anim.fragment_out, R.anim.slide_in_right, R.anim.slide_out_right); transaction.hide(this); - transaction.add(R.id.fragment_container, mLocalMusicFragment); - + if (!mLocalMusicFragment.isAdded()) { + transaction.add(R.id.fragment_container, mLocalMusicFragment); + }else{ + transaction.show(mLocalMusicFragment); + } + //将事务提交到返回栈 + transaction.addToBackStack(null); transaction.commit();