Merge branch 'dev'

pull/1/head
jsyjst 6 years ago
commit 4a4b5beeee

@ -1,29 +1,113 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
<codeStyleSettings language="XML">
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:Android="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.musicplayer">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
@ -14,7 +15,8 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/icon"
android:supportsRtl="true"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".view.WelcomeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -24,14 +26,19 @@
</activity>
<activity android:name=".view.MainActivity"
android:windowSoftInputMode="adjustPan|stateHidden"
></activity>
/>
<service
android:name=".service.PlayerService"
android:enabled="true"
android:exported="true"></service>
android:exported="true"/>
<activity android:name=".view.PlayActivity"></activity>
<service android:name=".service.DownloadService"
android:enabled="true"
android:exported="true"/>
<activity android:name=".view.PlayActivity"/>
</application>
</manifest>

@ -1,15 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<litepal>
<dbname value="SongList"></dbname>
<dbname value="SongList" />
<version value="15"></version>
<version value="27" />
<list>
<mapping class="com.example.musicplayer.entiy.OnlineSong"></mapping>
<mapping class="com.example.musicplayer.entiy.LocalSong"></mapping>
<mapping class="com.example.musicplayer.entiy.SearchHistory"></mapping>
<mapping class="com.example.musicplayer.entiy.Love"></mapping>
<mapping class="com.example.musicplayer.entiy.HistorySong"></mapping>
<mapping class="com.example.musicplayer.entiy.AlbumCollection"></mapping>
<mapping class="com.example.musicplayer.entiy.OnlineSong" />
<mapping class="com.example.musicplayer.entiy.LocalSong" />
<mapping class="com.example.musicplayer.entiy.SearchHistory" />
<mapping class="com.example.musicplayer.entiy.Love" />
<mapping class="com.example.musicplayer.entiy.HistorySong" />
<mapping class="com.example.musicplayer.entiy.AlbumCollection" />
<mapping class="com.example.musicplayer.entiy.DownloadSong" />
<mapping class="com.example.musicplayer.entiy.DownloadInfo"/>
<mapping class="com.example.musicplayer.entiy.Song"/>
</list>
</litepal>

@ -0,0 +1,143 @@
package com.example.musicplayer.adapter;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.andexert.library.RippleView;
import com.example.musicplayer.R;
import com.example.musicplayer.callback.OnItemClickListener;
import com.example.musicplayer.entiy.DownloadSong;
import com.example.musicplayer.util.FileUtil;
import java.util.List;
/**
* <pre>
* author :
* time : 2019/09/18
* desc :
* </pre>
*/
public class DownloadSongAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final String TAG = "LoveSongAdapter";
private int footerViewType = 1;
private int itemViewType = 0;
private List<DownloadSong> mDownloadSongList;
private Context mContext;
private int mLastPosition = -1;
private OnItemClickListener onItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public DownloadSongAdapter(Context context, List<DownloadSong> loveList) {
mContext = context;
mDownloadSongList = loveList;
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView songNameTv;
TextView singerTv;
View playLine;
RippleView item;
public ViewHolder(View itemView) {
super(itemView);
songNameTv = itemView.findViewById(R.id.tv_title);
singerTv = itemView.findViewById(R.id.tv_artist);
playLine = itemView.findViewById(R.id.line_play);
item = itemView.findViewById(R.id.ripple);
}
}
/**
* holder
*/
static class FooterHolder extends RecyclerView.ViewHolder {
TextView numTv;
public FooterHolder(View itemView) {
super(itemView);
numTv = itemView.findViewById(R.id.tv_song_num);
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == itemViewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_song_search_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
} else {
View footerView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.footer_local_songs_item, parent, false);
FooterHolder footerHolder = new FooterHolder(footerView);
return footerHolder;
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
if (viewHolder instanceof ViewHolder) {
ViewHolder holder = (ViewHolder) viewHolder;
final DownloadSong downloadSong = mDownloadSongList.get(position);
holder.songNameTv.setText(downloadSong.getName());
holder.singerTv.setText(downloadSong.getSinger());
//根据点击显示
if (downloadSong.getSongId().equals(FileUtil.getSong().getSongId())) {
holder.playLine.setVisibility(View.VISIBLE);
mLastPosition = position;
holder.songNameTv.setTextColor(mContext.getResources()
.getColor(R.color.yellow));
holder.singerTv.setTextColor(mContext.getResources()
.getColor(R.color.yellow));
} else {
holder.playLine.setVisibility(View.INVISIBLE);
holder.songNameTv.setTextColor(mContext.getResources()
.getColor(R.color.white));
holder.singerTv.setTextColor(mContext.getResources()
.getColor(R.color.white_blue));
}
holder.item.setOnRippleCompleteListener(rippleView -> {
if (onItemClickListener != null) {
onItemClickListener.onClick(position);
}
equalPosition(position);
});
} else {
FooterHolder footerHolder = (FooterHolder) viewHolder;
footerHolder.numTv.setText("共" + mDownloadSongList.size() + "首音乐");
}
}
//判断点击的是否为上一个点击的项目
public void equalPosition(int position) {
if (position != mLastPosition) {
notifyItemChanged(mLastPosition);
mLastPosition = position;
}
notifyItemChanged(position);
}
@Override
public int getItemCount() {
return mDownloadSongList.size() + 1;
}
@Override
public int getItemViewType(int position) {
return position + 1 == getItemCount() ? footerViewType : itemViewType;
}
}

@ -0,0 +1,116 @@
package com.example.musicplayer.adapter;
import android.annotation.SuppressLint;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import com.example.musicplayer.R;
import com.example.musicplayer.app.Constant;
import com.example.musicplayer.callback.OnDeleteClickListener;
import com.example.musicplayer.callback.OnItemClickListener;
import com.example.musicplayer.entiy.DownloadInfo;
import com.example.musicplayer.util.MediaUtil;
import java.util.List;
/**
* <pre>
* author :
* time : 2019/09/17
* desc :
* </pre>
*/
public class DownloadingAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<DownloadInfo> downloadInfoList;
private OnItemClickListener onItemClickListener;
private OnDeleteClickListener onDeleteClickListener;
public void setOnDeleteClickListener(OnDeleteClickListener onDeleteClickListener){
this.onDeleteClickListener = onDeleteClickListener;
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public DownloadingAdapter(List<DownloadInfo> downloadInfoList) {
this.downloadInfoList = downloadInfoList;
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView songTv;
TextView sizeTv;
SeekBar seekBar;
View itemView;
ImageView cancelTv;
public ViewHolder(@NonNull View itemView) {
super(itemView);
this.itemView = itemView;
songTv = itemView.findViewById(R.id.songTv);
sizeTv = itemView.findViewById(R.id.sizeTv);
seekBar = itemView.findViewById(R.id.seekBar);
cancelTv = itemView.findViewById(R.id.cancelIv);
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.recycler_downing_item, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@SuppressLint({"SetTextI18n", "ClickableViewAccessibility"})
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
ViewHolder holder = (ViewHolder) viewHolder;
if (downloadInfoList.size() == 0) return;
DownloadInfo downloadInfo = downloadInfoList.get(i);
holder.songTv.setText(downloadInfo.getSongName());
if(downloadInfo.getStatus() == Constant.DOWNLOAD_READY){//准备开始下载
holder.sizeTv.setText("正在获取歌曲大小");
holder.seekBar.setVisibility(View.GONE);
} else if (downloadInfo.getStatus()==Constant.DOWNLOAD_ING) {//当前歌曲正在下载
holder.sizeTv.setText(
MediaUtil.formatSize(downloadInfo.getCurrentSize()) + "M"
+ " / "
+ MediaUtil.formatSize(downloadInfo.getTotalSize()) + "M");
holder.seekBar.setVisibility(View.VISIBLE);
}else if(downloadInfo.getStatus() == Constant.DOWNLOAD_PAUSED){//暂停
holder.sizeTv.setText("已暂停,点击继续下载");
holder.seekBar.setVisibility(View.GONE);
}else {//当前歌曲并未下载
holder.sizeTv.setText(downloadInfo.getSinger());
holder.seekBar.setVisibility(View.GONE);
}
holder.seekBar.setOnTouchListener((view, motionEvent) -> true); //消费该事件让seekBar不能拖动和点击
holder.seekBar.setProgress(downloadInfo.getProgress());
//点击事件
holder.itemView.setOnClickListener(view -> {
onItemClickListener.onClick(i);
});
//取消
holder.cancelTv.setOnClickListener(view -> onDeleteClickListener.onClick(i));
}
@Override
public int getItemCount() {
return downloadInfoList.size();
}
}

@ -41,6 +41,7 @@ public class LoveSongAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView songNameTv;
TextView singerTv;

@ -10,12 +10,12 @@ import java.util.List;
* Created by on 2018/11/25.
*/
public class SearchAdapter extends FragmentPagerAdapter {
public class TabAdapter extends FragmentPagerAdapter {
private List<Fragment> mFragmentList;//顶部导航栏的内容即fragment
private List<String> mTitle;//顶部导航栏的标题
public SearchAdapter(FragmentManager fragmentManager, List<Fragment>fragments, List<String>title){
public TabAdapter(FragmentManager fragmentManager, List<Fragment>fragments, List<String>title){
super(fragmentManager);
mFragmentList=fragments;
mTitle=title;

@ -1,5 +1,7 @@
package com.example.musicplayer.app;
import android.os.Environment;
/**
* Created by on 2018/10/26.
*/
@ -16,7 +18,7 @@ public class Api {
*/
public static String STORAGE_IMG_FILE= App.getContext().getExternalFilesDir("") + "/yuanmusic/img/";
public static String STORAGE_LRC_FILE= App.getContext().getExternalFilesDir("") + "/yuanmusic/lrc/";
public static String STORAGE_SONG_FILE= App.getContext().getExternalFilesDir("") + "/yuanmusic/song/";
public static String STORAGE_SONG_FILE= Environment.getExternalStorageDirectory() + "/Sxmusic/download/";
//Fiddler抓包qq音乐网站后的地址
public static final String FIDDLER_BASE_QQ_URL ="https://c.y.qq.com/";
@ -28,6 +30,7 @@ public class Api {
public static final String SONG_URL="cgi-bin/musicu.fcg?format=json";
public static final String SONG_URL_DATA_LEFT="%7B%22req_0%22%3A%7B%22module%22%3A%22vkey.GetVkeyServer%22%2C%22method%22%3A%22CgiGetVkey%22%2C%22param%22%3A%7B%22guid%22%3A%22358840384%22%2C%22songmid%22%3A%5B%22";
public static final String SONG_URL_DATA_RIGHT="%22%5D%2C%22songtype%22%3A%5B0%5D%2C%22uin%22%3A%221443481947%22%2C%22loginflag%22%3A1%2C%22platform%22%3A%2220%22%7D%7D%2C%22comm%22%3A%7B%22uin%22%3A%221443481947%22%2C%22format%22%3A%22json%22%2C%22ct%22%3A24%2C%22cv%22%3A0%7D%7D ";
public static final String MP4 =".mp4";
//专辑照片
public static final String ALBUM_PIC="http://y.gtimg.cn/music/photo_new/T002R180x180M000";
public static final String JPG=".jpg";

@ -10,11 +10,14 @@ public class Constant {
public static final int OFFSET = 30;
public static final int TYPE_SONG = 1;
public static final int TYPE_ALBUM = 2;
public static final int TYPE_ALBUM_SONG = 3;
public static final int LIST_TYPE_LOCAL = 0;
public static final int LIST_TYPE_ONLINE = 1;
public static final int LIST_TYPE_LOVE = 2;
public static final int LIST_TYPE_HISTORY = 3;
//播放列表
public static final int LIST_TYPE_LOCAL = 1; //本地列表
public static final int LIST_TYPE_ONLINE = 2; //专辑列表
public static final int LIST_TYPE_LOVE = 3; //我的收藏列表
public static final int LIST_TYPE_HISTORY = 4; //最近播放列表
public static final int LIST_TYPE_DOWNLOAD = 5; //下载列表
public static final int HISTORY_MAX_SIZE = 100;
@ -60,5 +63,20 @@ public class Constant {
//Preferences
public static final String SHARED_PREFERENCES_NAME = "prefs";
public static final String PREFS_PLAY_MODE="play_mode";//播放状态
public static final String PREFS_PLAY_MODE = "play_mode";//播放状态
//download
public final static int TYPE_DOWNLOADING = 0;
public final static int TYPE_DOWNLOAD_PAUSED = 1;
public final static int TYPE_DOWNLOAD_CANCELED = 2;
public final static int TYPE_DOWNLOAD_SUCCESS = 3;
public final static int TYPE_DOWNLOAD_FAILED = 4;
public final static int TYPE_DOWNLOADED = 5;
public final static int TYPE_DOWNLOAD_ADD=6;
//正在下载歌曲列表的状态
public final static int DOWNLOAD_PAUSED = 0;
public final static int DOWNLOAD_WAIT=1;
public final static int DOWNLOAD_ING=2;
public final static int DOWNLOAD_READY=3;
}

@ -4,6 +4,7 @@ import com.example.musicplayer.base.presenter.IPresenter;
import com.example.musicplayer.base.view.BaseView;
import com.example.musicplayer.entiy.Album;
import com.example.musicplayer.entiy.SearchSong;
import com.example.musicplayer.entiy.Song;
import java.util.ArrayList;
import java.util.List;
@ -23,13 +24,13 @@ public interface ISearchContentContract {
void searchAlbumSuccess(List<Album.DataBean.AlbumBean.ListBean> albumList); //获取专辑成功
void searchAlbumMoreSuccess(List<Album.DataBean.AlbumBean.ListBean> songListBeans); //搜索更多内容成功
void searchAlbumError(); //获取专辑失败
void getSongUrlSuccess(String url);//成功获取歌曲url
void getSongUrlSuccess(Song song,String url);//成功获取歌曲url
}
interface Presenter extends IPresenter<View> {
void search(String seek,int offset); //搜索
void searchMore(String seek,int offset); //搜索更多
void searchAlbum(String seek,int offset); //搜索专辑
void searchAlbumMore(String seek,int offset);//搜索更多专辑
void getSongUrl(String songId);//得到歌曲的播放url
void getSongUrl(Song song);//得到歌曲的播放url
}
}

@ -0,0 +1,20 @@
package com.example.musicplayer.download;
import com.example.musicplayer.entiy.DownloadInfo;
/**
* <pre>
* author :
* time : 2019/04/08
* desc :
* </pre>
*/
public interface DownloadListener {
void onProgress(DownloadInfo downloadInfo); //进度
void onSuccess(); //成功
void onDownloaded();//已经下载过的歌曲
void onFailed(); //失败
void onPaused(); //暂停
void onCanceled(); //取消
}

@ -0,0 +1,177 @@
package com.example.musicplayer.download;
import android.os.AsyncTask;
import com.example.musicplayer.app.Api;
import com.example.musicplayer.entiy.DownloadInfo;
import com.example.musicplayer.util.DownloadUtil;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import static com.example.musicplayer.app.Constant.*;
/**
* <pre>
* author :
* time : 2019/04/08
* desc :
* </pre>
*/
public class DownloadTask extends AsyncTask<DownloadInfo, DownloadInfo, Integer> {
private DownloadListener mDownListener;
private boolean isCanceled = false;
private boolean isPaused = false;
private long lastProgress;
public DownloadTask(DownloadListener downloadListener) {
mDownListener = downloadListener;
}
@Override
protected Integer doInBackground(DownloadInfo... downloadInfos) {
InputStream is = null;
RandomAccessFile saveFile = null;
File file = null;
DownloadInfo downloadInfo = downloadInfos[0];
try {
long downloadedLength = 0; //记录已下载的文件长度
String downloadUrl = downloadInfo.getUrl();
File downloadFile = new File(Api.STORAGE_SONG_FILE);
if (!downloadFile.exists()) {
downloadFile.mkdirs();
}
//传过来的下载地址
// http://ws.stream.qqmusic.qq.com/C400001DI2Jj3Jqve9.m4a?guid=358840384&vkey=2B9BF114492F203C3943D8AE38C83DD8FEEA5E628B18F7F4455CA9B5059040266D74EBD43E09627AA4419D379B6A9E1FC1E5D2104AC7BB50&uin=0&fromtag=66
long contentLength = getContentLength(downloadUrl); //实际文件长度
String fileName = DownloadUtil.getSaveSongFile(downloadInfo.getSinger(),downloadInfo.getSongName(),downloadInfo.getDuration(),downloadInfo.getSongId(),contentLength);
file = new File(downloadFile ,fileName);
if (file.exists()) {
downloadedLength = file.length();
}
if (contentLength == 0) {
return TYPE_DOWNLOAD_FAILED;
} else if (contentLength == downloadedLength) { //已下载
return TYPE_DOWNLOADED;
}
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
//断点下载,指定从哪个字节开始下载
.addHeader("RANGE", "bytes=" + downloadedLength + "-")
.url(downloadUrl)
.build();
Response response = client.newCall(request).execute();
if (response != null) {
is = response.body().byteStream();
saveFile = new RandomAccessFile(file, "rw");
saveFile.seek(downloadedLength); //跳过已下载的字节
byte[] b = new byte[1024];
int total = 0;
int len;
while ((len = is.read(b)) != -1) {
if (isCanceled) {
return TYPE_DOWNLOAD_CANCELED;
} else if (isPaused) {
return TYPE_DOWNLOAD_PAUSED;
} else {
total += len;
saveFile.write(b, 0, len);
int progress = (int) ((total + downloadedLength) * 100 / contentLength);
downloadInfo.setProgress(progress);
downloadInfo.setTotalSize(contentLength);
downloadInfo.setCurrentSize(total+downloadedLength);
publishProgress(downloadInfo);
}
}
response.body().close();
return TYPE_DOWNLOAD_SUCCESS;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
if (saveFile != null) {
saveFile.close();
}
if (isCanceled && file != null) {
file.delete();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return TYPE_DOWNLOAD_FAILED;
}
@Override
public void onProgressUpdate(DownloadInfo... downloadInfos) {
DownloadInfo downloadInfo = downloadInfos[0];
int progress = downloadInfo.getProgress();
if (progress > lastProgress) {
mDownListener.onProgress(downloadInfo);
lastProgress = progress;
}
}
@Override
protected void onPostExecute(Integer status) {
switch (status) {
case TYPE_DOWNLOAD_SUCCESS:
mDownListener.onSuccess();
break;
case TYPE_DOWNLOAD_FAILED:
mDownListener.onFailed();
break;
case TYPE_DOWNLOAD_PAUSED:
mDownListener.onPaused();
break;
case TYPE_DOWNLOAD_CANCELED:
mDownListener.onCanceled();
break;
case TYPE_DOWNLOADED:
mDownListener.onDownloaded();
default:
break;
}
}
public void pauseDownload() {
isPaused = true;
}
public void cancelDownload() {
isCanceled = true;
}
private long getContentLength(String downloadUrl) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(downloadUrl)
.build();
Response response = client.newCall(request).execute();
if (response != null && response.isSuccessful()) {
long contentLength = response.body().contentLength();
response.body().close();
return contentLength;
}
return 0;
}
}

@ -0,0 +1,118 @@
package com.example.musicplayer.entiy;
import org.litepal.crud.LitePalSupport;
/**
* <pre>
* author :
* time : 2019/09/17
* desc :
* </pre>
*/
public class DownloadInfo extends LitePalSupport {
private long id;
private String songName;
private String singer;
private String url;
private String songId;
private int progress;
private long currentSize;
private long totalSize;
// private Song song;
private long duration;
private int position;//正在下载歌曲列表中的位置
private int status;//下载歌曲的状态
public String getSongName() {
return songName;
}
public void setSongName(String songName) {
this.songName = songName;
}
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getSongId() {
return songId;
}
public void setSongId(String songId) {
this.songId = songId;
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
this.progress = progress;
}
public long getCurrentSize() {
return currentSize;
}
public void setCurrentSize(long currentSize) {
this.currentSize = currentSize;
}
public long getTotalSize() {
return totalSize;
}
public void setTotalSize(long totalSize) {
this.totalSize = totalSize;
}
// public Song getSong() {
// return song;
// }
//
// public void setSong(Song song) {
// this.song = song;
// }
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public long getId() {
return id;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
}

@ -0,0 +1,87 @@
package com.example.musicplayer.entiy;
import org.litepal.crud.LitePalSupport;
/**
* <pre>
* author :
* time : 2019/09/18
* desc :
* </pre>
*/
public class DownloadSong extends LitePalSupport {
private int id;
private String songId ;
private String mediaId; //下载标识符
private String name;
private String singer;
private String url;
private String pic;
private long duration;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
public void setDuration(long duration) {
this.duration = duration;
}
public long getDuration() {
return duration;
}
public void setSongId(String songId) {
this.songId = songId;
}
public String getSongId() {
return songId;
}
public String getMediaId() {
return mediaId;
}
public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}
}

@ -9,6 +9,7 @@ import org.litepal.crud.LitePalSupport;
public class HistorySong extends LitePalSupport {
private int id;
private String songId;
private String mediaId; //下载标识符
private String qqId;
private String name;
private String singer;
@ -16,6 +17,7 @@ public class HistorySong extends LitePalSupport {
private String pic;
private long duration;
private boolean isOnline;
private boolean isDownload;
@ -91,4 +93,20 @@ public class HistorySong extends LitePalSupport {
public void setQqId(String qqId) {
this.qqId = qqId;
}
public String getMediaId() {
return mediaId;
}
public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}
public void setDownload(boolean download) {
isDownload = download;
}
public boolean isDownload() {
return isDownload;
}
}

@ -9,6 +9,7 @@ import org.litepal.crud.LitePalSupport;
public class Love extends LitePalSupport{
private int id;
private String songId;
private String mediaId; //下载标识符
private String qqId;
private String name;
private String singer;
@ -16,6 +17,7 @@ public class Love extends LitePalSupport{
private String pic;
private long duration;
private boolean isOnline;
private boolean isDownload;
public int getId() {
@ -90,4 +92,20 @@ public class Love extends LitePalSupport{
public String getQqId() {
return qqId;
}
public String getMediaId() {
return mediaId;
}
public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}
public boolean isDownload() {
return isDownload;
}
public void setDownload(boolean download) {
isDownload = download;
}
}

@ -9,6 +9,7 @@ import org.litepal.crud.LitePalSupport;
public class OnlineSong extends LitePalSupport {
private int id;
private String songId;
private String mediaId; //下载标识符
private String qqId;
private String name;
private String singer;
@ -16,6 +17,7 @@ public class OnlineSong extends LitePalSupport {
private String pic;
private String lrc;
private long duration;
private boolean isDownload;
public int getId() {
@ -89,4 +91,20 @@ public class OnlineSong extends LitePalSupport {
public void setQqId(String qqId) {
this.qqId = qqId;
}
public String getMediaId() {
return mediaId;
}
public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}
public void setDownload(boolean download) {
isDownload = download;
}
public boolean isDownload() {
return isDownload;
}
}

@ -1,80 +1,111 @@
package com.example.musicplayer.entiy;
import org.litepal.crud.LitePalSupport;
import java.io.Serializable;
/**
* Created by on 2018/10/19.
*/
public class Song implements Serializable {
public class Song extends LitePalSupport implements Serializable {
private static final long serialVersionUID=1L;
private long id;
private String songId; //歌曲id
private String qqId;//专属本地音乐本地音乐在qq音乐中的songId
private String mediaId;//播放id,下载需要用到
private String singer; //歌手
private long duration; //总时长
private String songName; //歌曲名字
private String url; //歌曲url
private long currentTime; //歌曲播放时长位置
private int current;//在音乐列表的位置
private int position;//在音乐列表的位置
private String imgUrl; //歌曲照片
private boolean isOnline; //是否为网络歌曲
private int listType; //歌曲列表类别
private int listType; //歌曲列表类别,0表示当前没有列表即可能在播放网络歌曲
private boolean isDownload;//是否为下载的歌曲
public String getImgUrl() {
return imgUrl;
public String getSongId() {
return songId;
}
public int getCurrent() {
return current;
public void setSongId(String songId) {
this.songId = songId;
}
public long getDuration() {
return duration;
public String getQqId() {
return qqId;
}
public long getCurrentTime() {
return currentTime;
public void setQqId(String qqId) {
this.qqId = qqId;
}
public String getUrl() {
return url;
public String getMediaId() {
return mediaId;
}
public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public String getSongName() {
return songName;
}
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
public void setSongName(String songName) {
this.songName = songName;
}
public void setCurrent(int current) {
this.current = current;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public long getCurrentTime() {
return currentTime;
}
public void setCurrentTime(long currentTime) {
this.currentTime = currentTime;
}
public void setDuration(long duration) {
this.duration = duration;
public int getPosition() {
return position;
}
public void setUrl(String url) {
this.url = url;
public void setPosition(int position) {
this.position = position;
}
public void setSinger(String singer) {
this.singer = singer;
public String getImgUrl() {
return imgUrl;
}
public void setSongName(String songName) {
this.songName = songName;
public void setImgUrl(String imgUrl) {
this.imgUrl = imgUrl;
}
public boolean isOnline() {
@ -93,25 +124,21 @@ public class Song implements Serializable {
this.listType = listType;
}
public String getSongId() {
return songId;
public boolean isDownload() {
return isDownload;
}
public void setSongId(String songId) {
this.songId = songId;
}
public String getQqId() {
return qqId;
public void setDownload(boolean download) {
isDownload = download;
}
public void setQqId(String qqId) {
this.qqId = qqId;
public long getId() {
return id;
}
public String toString(){
return "songName="+songName+",singer="+singer+",url="+url+",imgUrl="+imgUrl
+",duration="+duration+",currentTime="+currentTime+",current="+current
+",duration="+duration+",currentTime="+currentTime+",position="+ position
+",songId="+songId+",isOnline="+isOnline+",listType="+listType;
}

@ -0,0 +1,48 @@
package com.example.musicplayer.event;
import com.example.musicplayer.entiy.DownloadInfo;
/**
* <pre>
* author :
* time : 2019/09/16
* desc :
* </pre>
*/
public class DownloadEvent {
private int downloadStatus;//下载的状态
private DownloadInfo downloadInfo;
private int position;
public DownloadEvent(int status){
downloadStatus = status;
}
public DownloadEvent(int status, DownloadInfo downloadInfo){
downloadStatus = status;
this.downloadInfo = downloadInfo;
}
public DownloadEvent(int status,int position){
downloadStatus = status;
this.position = position;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public int getDownloadStatus() {
return downloadStatus;
}
public DownloadInfo getDownloadInfo() {
return downloadInfo;
}
}

@ -0,0 +1,12 @@
package com.example.musicplayer.event;
/**
* <pre>
* author :
* time : 2019/09/18
* desc :
* </pre>
*/
public class SongDownloadedEvent {
}

@ -0,0 +1,24 @@
package com.example.musicplayer.event;
/**
* <pre>
* author :
* time : 2019/09/20
* desc :
* </pre>
*/
public class SongListNumEvent {
private int type;
public SongListNumEvent(int type){
this.type = type;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}

@ -13,6 +13,7 @@ import com.example.musicplayer.entiy.Song;
import org.litepal.LitePal;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@ -46,8 +47,8 @@ public class DbHelperImpl implements DbHelper {
@Override
public List<LocalSong> getLocalMp3Info() {
List<LocalSong> mp3InfoList = new ArrayList<>();
getFromDownloadFile(mp3InfoList); //从下载列表中读取歌曲文件
Cursor cursor = App.getContext().getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
@ -119,6 +120,8 @@ public class DbHelperImpl implements DbHelper {
love.setSongId(song.getSongId());
love.setOnline(song.isOnline());
love.setQqId(song.getQqId());
love.setMediaId(song.getMediaId());
love.setDownload(song.isDownload());
return love.save();
}
@ -126,4 +129,30 @@ public class DbHelperImpl implements DbHelper {
public boolean deleteFromLove(String songId) {
return LitePal.deleteAll(Love.class,"songId=?",songId) !=0;
}
//从下载列表中读取文件
private void getFromDownloadFile(List<LocalSong> songList){
File file = new File(Api.STORAGE_SONG_FILE);
if(!file.exists()) {
file.mkdirs();
return;
}
File[] subFile = file.listFiles();
for (File value : subFile) {
String songFileName = value.getName();
String songFile = songFileName.substring(0, songFileName.lastIndexOf("."));
String[] songValue = songFile.split("-");
long size = Long.valueOf(songValue[4]);
//如果文件的大小不等于实际大小,则表示该歌曲还未下载完成,被人为暂停,故跳过该歌曲,不加入到已下载集合
if(size != value.length()) continue;
LocalSong song =new LocalSong();
song.setSinger(songValue[0]);
song.setName(songValue[1]);
song.setDuration(Long.valueOf(songValue[2]));
song.setSongId(songValue[3]);
song.setUrl(Api.STORAGE_SONG_FILE + songFileName);
songList.add(song);
}
}
}

@ -1,9 +1,11 @@
package com.example.musicplayer.presenter;
import com.example.musicplayer.app.Constant;
import com.example.musicplayer.base.presenter.BasePresenter;
import com.example.musicplayer.contract.ILocalContract;
import com.example.musicplayer.entiy.LocalSong;
import com.example.musicplayer.event.SongListNumEvent;
import com.example.musicplayer.event.SongLocalSizeChangeEvent;
import org.greenrobot.eventbus.EventBus;
@ -30,7 +32,7 @@ public class LocalPresenter extends BasePresenter<ILocalContract.View> implement
@Override
public void saveSong(List<LocalSong> localSongs) {
if(mModel.saveSong(localSongs)) {
EventBus.getDefault().post(new SongLocalSizeChangeEvent());
EventBus.getDefault().post(new SongListNumEvent(Constant.LIST_TYPE_LOCAL));
mView.showToast("成功导入本地音乐");
mView.showMusicList(localSongs);
}

@ -7,6 +7,7 @@ import com.example.musicplayer.base.presenter.BasePresenter;
import com.example.musicplayer.contract.ISearchContentContract;
import com.example.musicplayer.entiy.Album;
import com.example.musicplayer.entiy.SearchSong;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.entiy.SongUrl;
import com.example.musicplayer.model.DataModel;
import com.example.musicplayer.model.db.DbHelperImpl;
@ -116,11 +117,11 @@ public class SearchContentPresenter extends BasePresenter<ISearchContentContract
}
@Override
public void getSongUrl(String songId) {
public void getSongUrl(Song song) {
//因为得到播放地址的baseUrl和获取歌曲列表等的baseUrl不同所以要重新赋值
mModel = new DataModel(new NetworkHelperImpl(RetrofitFactory.createRequestOfSongUrl()),new DbHelperImpl(),new PreferencesHelperImpl());
addRxSubscribe(
mModel.getSongUrl(Api.SONG_URL_DATA_LEFT+songId+Api.SONG_URL_DATA_RIGHT)
mModel.getSongUrl(Api.SONG_URL_DATA_LEFT+song.getSongId()+Api.SONG_URL_DATA_RIGHT)
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new BaseObserver<SongUrl>(mView,false,false){
@Override
@ -129,7 +130,12 @@ public class SearchContentPresenter extends BasePresenter<ISearchContentContract
if(songUrl.getCode() == 0){
String sip = songUrl.getReq_0().getData().getSip().get(0);
String purl = songUrl.getReq_0().getData().getMidurlinfo().get(0).getPurl();
mView.getSongUrlSuccess(sip+purl);
if(purl.equals("")){
mView.showToast("该歌曲暂时没有版权,搜搜其它歌曲吧");
}else {
mView.getSongUrlSuccess(song,sip+purl);
}
}else {
mView.showToast(songUrl.getCode()+":获取不到歌曲播放地址");
}

@ -0,0 +1,318 @@
package com.example.musicplayer.service;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;
import com.example.musicplayer.R;
import com.example.musicplayer.app.Api;
import com.example.musicplayer.app.Constant;
import com.example.musicplayer.download.DownloadListener;
import com.example.musicplayer.download.DownloadTask;
import com.example.musicplayer.entiy.DownloadInfo;
import com.example.musicplayer.event.DownloadEvent;
import com.example.musicplayer.event.SongListNumEvent;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.util.DownloadUtil;
import com.example.musicplayer.view.MainActivity;
import org.greenrobot.eventbus.EventBus;
import org.litepal.LitePal;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import static com.example.musicplayer.app.Constant.TYPE_DOWNLOADING;
/**
* <pre>
* author :
* time : 2019/04/08
* desc : DownloadTask
* </pre>
*/
public class DownloadService extends Service {
private static final String TAG = "DownloadService";
private DownloadTask downloadTask;
private String downloadUrl;
private DownloadBinder downloadBinder = new DownloadBinder();
private LinkedList<DownloadInfo> downloadQueue = new LinkedList<>();//等待队列
private int position = 0;//下载歌曲在下载歌曲列表的位置
private DownloadListener listener = new DownloadListener() {
@Override
public void onProgress(DownloadInfo downloadInfo) {
downloadInfo.setStatus(Constant.DOWNLOAD_ING);
EventBus.getDefault().post(new DownloadEvent(TYPE_DOWNLOADING, downloadInfo)); //通知下载模块
if(downloadInfo.getProgress()!=100){
getNotificationManager().notify(1, getNotification("正在下载: "+downloadInfo.getSongName(), downloadInfo.getProgress()));
}else {
if(downloadQueue.isEmpty()) getNotificationManager().notify(1, getNotification("下载成功",-1));
}
}
@Override
public void onSuccess() {
downloadTask = null;
DownloadInfo downloadInfo = downloadQueue.poll();
operateDb(downloadInfo); //操作数据库
start();//下载队列中的其它歌曲
//下载成功通知前台服务通知关闭,并创建一个下载成功的通知
stopForeground(true);
if(downloadQueue.isEmpty()) getNotificationManager().notify(1, getNotification("下载成功",-1));
}
@Override
public void onDownloaded() {
downloadTask = null;
CommonUtil.showToast(DownloadService.this, "已下载");
}
@Override
public void onFailed() {
downloadTask = null;
//下载失败通知前台服务通知关闭,并创建一个下载失败的通知
stopForeground(true);
getNotificationManager().notify(1, getNotification("下载失败",-1));
Toast.makeText(DownloadService.this, "下载失败", Toast.LENGTH_SHORT).show();
}
@Override
public void onPaused() {
downloadTask = null;
DownloadInfo downloadInfo=downloadQueue.poll();//从下载列表中移除该歌曲
updateDbOfPause(downloadInfo.getSongId());
getNotificationManager().notify(1, getNotification("下载已暂停:"+downloadInfo.getSongName(), -1));
start();//下载下载列表中的歌曲
downloadInfo.setStatus(Constant.DOWNLOAD_PAUSED);
EventBus.getDefault().post(new DownloadEvent(Constant.TYPE_DOWNLOAD_PAUSED, downloadInfo)); //下载暂停
Toast.makeText(DownloadService.this, "下载已暂停", Toast.LENGTH_SHORT).show();
}
@Override
public void onCanceled() {
downloadTask = null;
stopForeground(true);
Toast.makeText(DownloadService.this, "下载已取消", Toast.LENGTH_SHORT).show();
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return downloadBinder;
}
public class DownloadBinder extends Binder {
public void startDownload(DownloadInfo song) {
try {
postDownloadEvent(song);//通知正在下载界面
} catch (Exception e) {
e.printStackTrace();
}
if (downloadTask != null) {
CommonUtil.showToast(DownloadService.this, "已经加入下载队列");
} else {
CommonUtil.showToast(DownloadService.this, "开始下载");
start();
}
}
public void pauseDownload(String songId) {
//暂停的歌曲是否为当前下载的歌曲
if (downloadTask != null &&downloadQueue.peek().getSongId().equals(songId)) {
downloadTask.pauseDownload();
}else {//暂停的歌曲是下载队列的歌曲
//将该歌曲从下载队列中移除
for (int i = 0; i < downloadQueue.size(); i++) {
DownloadInfo downloadInfo = downloadQueue.get(i);
if (downloadInfo.getSongId().equals(songId)) {
downloadQueue.remove(i);
updateDbOfPause(downloadInfo.getSongId());
downloadInfo.setStatus(Constant.DOWNLOAD_PAUSED);
EventBus.getDefault().post(new DownloadEvent(Constant.TYPE_DOWNLOAD_PAUSED, downloadInfo)); //下载暂停
}
}
}
}
public void cancelDownload(DownloadInfo song) {
String songId = song.getSongId();
//如果该歌曲正在下载则需要将downloadTask置为null
if (downloadTask != null && downloadQueue.peek().getSongId().equals(songId)) {
downloadTask.cancelDownload();
}
//将该歌曲从下载队列中移除
for (int i = 0; i < downloadQueue.size(); i++) {
DownloadInfo downloadInfo = downloadQueue.get(i);
if (downloadInfo.getSongId().equals(songId)) downloadQueue.remove(i);
}
updateDb(songId);
deleteDb(songId);
//取消下载需要将文件删除并将通知关闭
if (song.getUrl() != null) {
checkoutFile(song,song.getUrl()); //实际文件长度
}
//通知正在下载列表
EventBus.getDefault().post(new DownloadEvent(Constant.TYPE_DOWNLOAD_CANCELED));
}
}
private void start() {
if (downloadTask == null && !downloadQueue.isEmpty()) {
DownloadInfo downloadInfo = downloadQueue.peek();
List<DownloadInfo> songList =
LitePal.where("songId = ?",downloadInfo.getSongId()).find(DownloadInfo.class);
DownloadInfo currentDownloadInfo = songList.get(0);
currentDownloadInfo.setStatus(Constant.DOWNLOAD_READY);
EventBus.getDefault().post(new DownloadEvent(TYPE_DOWNLOADING,currentDownloadInfo));
downloadUrl = currentDownloadInfo.getUrl();
downloadTask = new DownloadTask(listener);
downloadTask.execute(currentDownloadInfo);
getNotificationManager().notify(1, getNotification("正在下载:"+downloadInfo.getSongName(), 0));
}
}
private NotificationManager getNotificationManager() {
return (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}
private Notification getNotification(String title,int progress) {
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String id = "channel_001";
String name = "下载通知";
NotificationChannel mChannel = new NotificationChannel(id, name, NotificationManager.IMPORTANCE_LOW);
getNotificationManager().createNotificationChannel(mChannel);
Notification.Builder builder = new Notification.Builder(this, id);
builder.setSmallIcon(R.mipmap.icon);
builder.setContentIntent(pi);
builder.setContentTitle(title);
if(progress>0){
builder.setContentText(progress +"%");
builder.setProgress(100, progress, false);
}
return builder.build();
} else {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default");
builder.setSmallIcon(R.mipmap.icon);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.icon));
builder.setContentIntent(pi);
builder.setContentTitle(title);
if(progress>0){
builder.setContentText(progress +"%");
builder.setProgress(100, progress, false);
}
return builder.build();
}
}
private void operateDb(DownloadInfo downloadInfo) {
updateDb(downloadInfo.getSongId());
deleteDb(downloadInfo.getSongId());
EventBus.getDefault().post(new DownloadEvent(Constant.TYPE_DOWNLOAD_SUCCESS));//通知已下载列表
EventBus.getDefault().post(new SongListNumEvent(Constant.LIST_TYPE_DOWNLOAD)); //通知主界面的下载个数需要改变
}
//更新数据库中歌曲列表的位置即下载完成歌曲后的位置都要减去1
private void updateDb(String songId) {
long id = LitePal.select("id").where("songId = ?", songId).find(DownloadInfo.class).get(0).getId();
List<DownloadInfo> songIdList = LitePal.where("id > ?", id + "").find(DownloadInfo.class);
for (DownloadInfo song : songIdList) {
song.setPosition(song.getPosition() - 1);
song.save();
}
}
//暂停时更新列表歌曲状态
private void updateDbOfPause(String songId){
List<DownloadInfo> statusList =
LitePal.where("songId = ?",songId).find(DownloadInfo.class,true);
DownloadInfo downloadInfo = statusList.get(0);
downloadInfo.setStatus(Constant.DOWNLOAD_PAUSED);
downloadInfo.save();
}
//下载完成时要删除下载歌曲表中的数据以及关联表中的数据
private void deleteDb(String songId) {
LitePal.deleteAll(DownloadInfo.class, "songId=?", songId);//删除已下载歌曲的相关列
}
private void postDownloadEvent(DownloadInfo downloadInfo) {
//如果需要下载的表中有该条歌曲,则添加到下载队列后跳过
List<DownloadInfo> downloadInfoList =
LitePal.where("songId = ?",downloadInfo.getSongId()).find(DownloadInfo.class,true);
if (downloadInfoList.size() != 0){
DownloadInfo historyDownloadInfo = downloadInfoList.get(0);
historyDownloadInfo.setStatus(Constant.DOWNLOAD_WAIT);
historyDownloadInfo.save();
EventBus.getDefault().post(new DownloadEvent(Constant.DOWNLOAD_PAUSED,historyDownloadInfo));
downloadQueue.offer(historyDownloadInfo);
return;
}
position = LitePal.findAll(DownloadInfo.class).size();
downloadInfo.setPosition(position);
downloadInfo.setStatus(Constant.DOWNLOAD_WAIT); //等待
downloadInfo.save();
downloadQueue.offer(downloadInfo);//将歌曲放到等待队列中
EventBus.getDefault().post(new DownloadEvent(Constant.TYPE_DOWNLOAD_ADD));
}
//获取歌曲实际大小,然后判断是否存在于文件中
public void checkoutFile(DownloadInfo song, String downloadUrl){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(downloadUrl)
.build();
Call call= client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){
long size = response.body().contentLength();
String fileName = DownloadUtil.getSaveSongFile(song.getSinger(),song.getSongName(),song.getDuration(),song.getSongId(),size);
File downloadFile = new File(Api.STORAGE_SONG_FILE);
String directory = String.valueOf(downloadFile);
File file = new File(fileName, directory);
if (file.exists()) {
file.delete();
}
getNotificationManager().cancel(1);
stopForeground(true);
}
}
});
}
}

@ -10,6 +10,7 @@ import android.util.Log;
import com.example.musicplayer.app.Api;
import com.example.musicplayer.app.Constant;
import com.example.musicplayer.entiy.DownloadSong;
import com.example.musicplayer.entiy.HistorySong;
import com.example.musicplayer.entiy.LocalSong;
import com.example.musicplayer.entiy.Love;
@ -20,10 +21,14 @@ import com.example.musicplayer.event.OnlineSongChangeEvent;
import com.example.musicplayer.event.OnlineSongErrorEvent;
import com.example.musicplayer.event.SongAlbumEvent;
import com.example.musicplayer.event.SongCollectionEvent;
import com.example.musicplayer.event.SongDownloadedEvent;
import com.example.musicplayer.event.SongHistoryEvent;
import com.example.musicplayer.event.SongListNumEvent;
import com.example.musicplayer.event.SongLocalEvent;
import com.example.musicplayer.event.SongStatusEvent;
import com.example.musicplayer.model.https.RetrofitFactory;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.util.DownloadUtil;
import com.example.musicplayer.util.FileUtil;
import org.greenrobot.eventbus.EventBus;
@ -52,6 +57,7 @@ public class PlayerService extends Service {
private List<OnlineSong> mSongList;
private List<Love> mLoveList;
private List<HistorySong> mHistoryList;
private List<DownloadSong> mDownloadList;
private int mCurrent;
private int mListType;
private int mPlayMode = Constant.PLAY_ORDER; //播放模式,默认为顺序播放
@ -59,6 +65,7 @@ public class PlayerService extends Service {
@Override
public void onCreate() {
Log.d(TAG, "onCreate: true");
mListType = FileUtil.getSong().getListType();
if (mListType == Constant.LIST_TYPE_ONLINE) {
mSongList = LitePal.findAll(OnlineSong.class);
@ -70,8 +77,10 @@ public class PlayerService extends Service {
mHistoryList = orderHistoryList(LitePal.findAll(HistorySong.class));
//保证最近播放列表一开始总是第一个
Song song = FileUtil.getSong();
song.setCurrent(0);
song.setPosition(0);
FileUtil.saveSong(song);
}else if(mListType == Constant.LIST_TYPE_DOWNLOAD){
mDownloadList = orderDownloadList(DownloadUtil.getSongFromFile(Api.STORAGE_SONG_FILE));
}
}
@ -79,24 +88,28 @@ public class PlayerService extends Service {
public IBinder onBind(Intent arg0) {
mediaPlayer.setOnCompletionListener(mp -> {
EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_PAUSE));//暂停广播
mCurrent = FileUtil.getSong().getCurrent();
mCurrent = FileUtil.getSong().getPosition();
//将歌曲的信息保存起来
if (mListType == Constant.LIST_TYPE_LOCAL) {
mCurrent=getNextCurrent(mCurrent, mPlayMode, mLocalSongList.size()); //根据播放模式来播放下一曲
saveLocalSongInfo(mCurrent);
mPlayStatusBinder.play(Constant.LIST_TYPE_LOCAL);
} else if (mListType == Constant.LIST_TYPE_ONLINE) {
mCurrent=getNextCurrent(mCurrent, mPlayMode, mSongList.size());//根据播放模式来播放下一曲
saveOnlineSongInfo(mCurrent);
mPlayStatusBinder.play(Constant.LIST_TYPE_ONLINE);
} else if (mListType == Constant.LIST_TYPE_LOVE) {
mCurrent=getNextCurrent(mCurrent, mPlayMode, mLoveList.size());//根据播放模式来播放下一曲
saveLoveInfo(mCurrent);
mPlayStatusBinder.play(Constant.LIST_TYPE_LOVE);
} else {
} else if(mListType == Constant.LIST_TYPE_HISTORY){
mCurrent=getNextCurrent(mCurrent, mPlayMode, mHistoryList.size());//根据播放模式来播放下一曲
saveHistoryInfo(mCurrent);
mPlayStatusBinder.play(Constant.LIST_TYPE_HISTORY);
}else if(mListType == Constant.LIST_TYPE_DOWNLOAD){
mCurrent=getNextCurrent(mCurrent, mPlayMode, mDownloadList.size());//根据播放模式来播放下一曲
saveDownloadInfo(mCurrent);
}
if(mListType!=0) {
mPlayStatusBinder.play(mListType);
}else {
mPlayStatusBinder.stop();
}
});
/**
@ -119,7 +132,7 @@ public class PlayerService extends Service {
mHistoryList = orderHistoryList(LitePal.findAll(HistorySong.class));
//保证最近播放列表一开始总是第一个
Song song = FileUtil.getSong();
song.setCurrent(0);
song.setPosition(0);
FileUtil.saveSong(song);
}
@ -143,8 +156,11 @@ public class PlayerService extends Service {
EventBus.getDefault().post(new SongCollectionEvent(true));//发送歌曲改变事件
} else if (mListType == Constant.LIST_TYPE_HISTORY) {
EventBus.getDefault().post(new SongHistoryEvent()); //发送随机歌曲改变事件
}else if(mListType == Constant.LIST_TYPE_DOWNLOAD){
mDownloadList =orderDownloadList(DownloadUtil.getSongFromFile(Api.STORAGE_SONG_FILE));
EventBus.getDefault().post(new SongDownloadedEvent()); //发送下载歌曲改变的消息
}
mCurrent = FileUtil.getSong().getCurrent();
mCurrent = FileUtil.getSong().getPosition();
mediaPlayer.reset();//把各项参数恢复到初始状态
if (mListType == Constant.LIST_TYPE_LOCAL) {
mediaPlayer.setDataSource(mLocalSongList.get(mCurrent).getUrl());
@ -154,9 +170,13 @@ public class PlayerService extends Service {
} else if (mListType == Constant.LIST_TYPE_LOVE) {
mediaPlayer.setDataSource(mLoveList.get(mCurrent).getUrl());
startPlay();
} else {
} else if(mListType == Constant.LIST_TYPE_HISTORY){
mediaPlayer.setDataSource(mHistoryList.get(mCurrent).getUrl());
startPlay();
}else if(mListType == Constant.LIST_TYPE_DOWNLOAD){
Log.d(TAG, "play: "+mDownloadList.get(mCurrent).getUrl());
mediaPlayer.setDataSource(mDownloadList.get(mCurrent).getUrl());
startPlay();
}
} catch (Exception e) {
e.printStackTrace();
@ -207,46 +227,46 @@ public class PlayerService extends Service {
public void next() {
EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_RESUME));
mCurrent = FileUtil.getSong().getCurrent();
mCurrent = FileUtil.getSong().getPosition();
if (mListType == Constant.LIST_TYPE_LOCAL) {
mCurrent=getNextCurrent(mCurrent, mPlayMode, mLocalSongList.size()); //根据播放模式来播放下一曲
saveLocalSongInfo(mCurrent);
mPlayStatusBinder.play(Constant.LIST_TYPE_LOCAL);
} else if (mListType == Constant.LIST_TYPE_ONLINE) {
mCurrent=getNextCurrent(mCurrent, mPlayMode, mSongList.size());//根据播放模式来播放下一曲
saveOnlineSongInfo(mCurrent);
mPlayStatusBinder.play(Constant.LIST_TYPE_ONLINE);
} else if (mListType == Constant.LIST_TYPE_LOVE) {
mCurrent=getNextCurrent(mCurrent, mPlayMode, mLoveList.size());//根据播放模式来播放下一曲
saveLoveInfo(mCurrent);
mPlayStatusBinder.play(Constant.LIST_TYPE_LOVE);
} else {
} else if(mListType == Constant.LIST_TYPE_HISTORY){
mCurrent=getNextCurrent(mCurrent, mPlayMode, mHistoryList.size());//根据播放模式来播放下一曲
saveHistoryInfo(mCurrent);
mPlayStatusBinder.play(Constant.LIST_TYPE_HISTORY);
}else if(mListType == Constant.LIST_TYPE_DOWNLOAD){
mCurrent=getNextCurrent(mCurrent, mPlayMode, mDownloadList.size());//根据播放模式来播放下一曲
saveDownloadInfo(mCurrent);
}
if(mListType!=0) mPlayStatusBinder.play(mListType);
}
public void last() {
EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_RESUME));//暂停广播
mCurrent = FileUtil.getSong().getCurrent();
mCurrent = FileUtil.getSong().getPosition();
if (mListType == Constant.LIST_TYPE_LOCAL) {
mCurrent = getLastCurrent(mCurrent,mPlayMode,mLocalSongList.size());
saveLocalSongInfo(mCurrent);
mPlayStatusBinder.play(mListType);
} else if (mListType == Constant.LIST_TYPE_ONLINE) {
mCurrent = getLastCurrent(mCurrent,mPlayMode,mSongList.size());
saveOnlineSongInfo(mCurrent);
mPlayStatusBinder.play(mListType);
} else if (mListType == Constant.LIST_TYPE_LOVE) {
mCurrent = getLastCurrent(mCurrent,mPlayMode,mLoveList.size());
saveLoveInfo(mCurrent);
mPlayStatusBinder.play(mListType);
} else {
} else if(mListType == Constant.LIST_TYPE_HISTORY){
mCurrent = getLastCurrent(mCurrent,mPlayMode,mHistoryList.size());
saveHistoryInfo(mCurrent);
mPlayStatusBinder.play(mListType);
} else if(mListType == Constant.LIST_TYPE_DOWNLOAD){
mCurrent = getLastCurrent(mCurrent,mPlayMode,mDownloadList.size());
saveDownloadInfo(mCurrent);
}
if(mListType!=0) mPlayStatusBinder.play(mListType);
}
/**
@ -303,7 +323,7 @@ public class PlayerService extends Service {
mLocalSongList = LitePal.findAll(LocalSong.class);
Song song = new Song();
LocalSong localSong = mLocalSongList.get(current);
song.setCurrent(current);
song.setPosition(current);
song.setSongName(localSong.getName());
song.setSinger(localSong.getSinger());
song.setDuration(localSong.getDuration());
@ -320,7 +340,7 @@ public class PlayerService extends Service {
private void saveOnlineSongInfo(int current) {
mSongList = LitePal.findAll(OnlineSong.class);
Song song = new Song();
song.setCurrent(current);
song.setPosition(current);
song.setSongId(mSongList.get(current).getSongId());
song.setSongName(mSongList.get(current).getName());
song.setSinger(mSongList.get(current).getSinger());
@ -329,6 +349,7 @@ public class PlayerService extends Service {
song.setImgUrl(mSongList.get(current).getPic());
song.setOnline(true);
song.setListType(Constant.LIST_TYPE_ONLINE);
song.setMediaId(mSongList.get(current).getMediaId());
FileUtil.saveSong(song);
}
@ -337,7 +358,7 @@ public class PlayerService extends Service {
mLoveList = orderList(LitePal.findAll(Love.class));
Love love = mLoveList.get(current);
Song song = new Song();
song.setCurrent(current);
song.setPosition(current);
song.setSongId(love.getSongId());
song.setQqId(love.getQqId());
song.setSongName(love.getName());
@ -347,6 +368,27 @@ public class PlayerService extends Service {
song.setListType(Constant.LIST_TYPE_LOVE);
song.setOnline(love.isOnline());
song.setDuration(love.getDuration());
song.setMediaId(love.getMediaId());
song.setDownload(love.isDownload());
FileUtil.saveSong(song);
}
//保存下载列表的信息
private void saveDownloadInfo(int current){
DownloadSong downloadSong = mDownloadList.get(current);
Song song = new Song();
song.setPosition(current);
song.setSongId(downloadSong.getSongId());
song.setSongName(downloadSong.getName());
song.setSinger(downloadSong.getSinger());
song.setUrl(downloadSong.getUrl());
song.setImgUrl(downloadSong.getPic());
song.setListType(Constant.LIST_TYPE_DOWNLOAD);
song.setOnline(false);
song.setDuration(downloadSong.getDuration());
song.setMediaId(downloadSong.getMediaId());
song.setDownload(true);
FileUtil.saveSong(song);
}
@ -354,7 +396,7 @@ public class PlayerService extends Service {
private void saveHistoryInfo(int current) {
HistorySong historySong = mHistoryList.get(current);
Song song = new Song();
song.setCurrent(current);
song.setPosition(current);
song.setSongId(historySong.getSongId());
song.setQqId(historySong.getQqId());
song.setSongName(historySong.getName());
@ -364,6 +406,8 @@ public class PlayerService extends Service {
song.setListType(Constant.LIST_TYPE_HISTORY);
song.setOnline(historySong.isOnline());
song.setDuration(historySong.getDuration());
song.setMediaId(historySong.getMediaId());
song.setDownload(historySong.isDownload());
FileUtil.saveSong(song);
}
@ -387,10 +431,14 @@ public class PlayerService extends Service {
history.setPic(song.getImgUrl());
history.setOnline(song.isOnline());
history.setDuration(song.getDuration());
history.setMediaId(song.getMediaId());
history.setDownload(song.isDownload());
history.saveAsync().listen(new SaveCallback() {
@Override
public void onFinish(boolean success) {
if (success) {
//告诉主界面最近播放的数目需要改变
EventBus.getDefault().post(new SongListNumEvent(Constant.LIST_TYPE_HISTORY));
if (LitePal.findAll(HistorySong.class).size() > Constant.HISTORY_MAX_SIZE) {
LitePal.delete(HistorySong.class, LitePal.findFirst(HistorySong.class).getId());
}
@ -404,7 +452,7 @@ public class PlayerService extends Service {
}
//对数据库进行倒叙排序
private List<Love> orderList(List<Love> tempList) {
private List orderList(List<Love> tempList) {
List<Love> loveList = new ArrayList<>();
loveList.clear();
for (int i = tempList.size() - 1; i >= 0; i--) {
@ -413,6 +461,15 @@ public class PlayerService extends Service {
return loveList;
}
private List<DownloadSong> orderDownloadList(List<DownloadSong> tempList) {
List<DownloadSong> downloadSongList = new ArrayList<>();
downloadSongList.clear();
for (int i = tempList.size() - 1; i >= 0; i--) {
downloadSongList.add(tempList.get(i));
}
return downloadSongList;
}
private List<HistorySong> orderHistoryList(List<HistorySong> tempList) {
List<HistorySong> historySongList = new ArrayList<>();
historySongList.clear();
@ -437,6 +494,10 @@ public class PlayerService extends Service {
if (songUrl.getCode() == 0) {
String sip = songUrl.getReq_0().getData().getSip().get(0);
String purl = songUrl.getReq_0().getData().getMidurlinfo().get(0).getPurl();
if(purl.equals("")) {
CommonUtil.showToast(PlayerService.this,"该歌曲暂时没有版权,试试搜索其它歌曲吧");
return;
}
Song song = FileUtil.getSong();
assert song != null;
song.setUrl(sip + purl);
@ -454,7 +515,7 @@ public class PlayerService extends Service {
@Override
public void onError(Throwable throwable) {
Log.d(TAG, "onError: "+throwable.toString());
}
@Override

@ -0,0 +1,81 @@
package com.example.musicplayer.util;
import android.util.Log;
import com.example.musicplayer.app.Api;
import com.example.musicplayer.entiy.DownloadSong;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import static com.example.musicplayer.app.Api.STORAGE_SONG_FILE;
/**
* <pre>
* author :
* time : 2019/09/24
* desc :
* </pre>
*/
public class DownloadUtil {
/**
*
* @param fileName
* @return
*/
public static final List<DownloadSong> getSongFromFile(String fileName){
//将.m4a截取掉得到singer-songName-duration-songId-size
List<DownloadSong> res = new ArrayList<>();
File file=new File(fileName);
if(!file.exists()){
file.mkdirs();
return res;
}
File[] subFile = file.listFiles();
for (File value : subFile) {
String songFileName = value.getName();
String songFile = songFileName.substring(0, songFileName.lastIndexOf("."));
String[] songValue = songFile.split("-");
long size = Long.valueOf(songValue[4]);
//如果文件的大小不等于实际大小,则表示该歌曲还未下载完成,被人为暂停,故跳过该歌曲,不加入到已下载集合
if(size != value.length()) continue;
DownloadSong downloadSong = new DownloadSong();
downloadSong.setSinger(songValue[0]);
downloadSong.setName(songValue[1]);
downloadSong.setDuration(Long.valueOf(songValue[2]));
downloadSong.setSongId(songValue[3]);
downloadSong.setUrl(fileName + songFileName);
res.add(downloadSong);
}
return res;
}
public static final boolean isExistOfDownloadSong(String songId){
//将.m4a截取掉得到singer-songName-duration-songId-size
File file=new File(STORAGE_SONG_FILE);
if(!file.exists()){
file.mkdirs();
return false;
}
File[] subFile = file.listFiles();
for (File value : subFile) {
String songFileName = value.getName();
String songFile = songFileName.substring(0, songFileName.lastIndexOf("."));
String[] songValue = songFile.split("-");
//如果文件的大小不等于实际大小,则表示该歌曲还未下载完成,被人为暂停,故跳过该歌曲,不加入到已下载集合
if(songValue[3].equals(songId)) {
long size = Long.valueOf(songValue[4]);
return size == value.length();
}
}
return false;
}
//组装下载歌曲的文件名
public static final String getSaveSongFile(String singer,String songName,long duration,String songId,long size){
return singer+"-"+songName+"-"+duration+"-"+songId+"-"+size+".m4a";
}
}

@ -1,5 +1,6 @@
package com.example.musicplayer.util;
import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.content.res.Resources;
@ -38,6 +39,12 @@ public class MediaUtil {
return singer.trim();
}
@SuppressLint("DefaultLocale")
public static String formatSize(long size){
double d = (double) size/1024/1024;
return String.format("%.1f",d);
}
}

@ -29,6 +29,7 @@ import com.example.musicplayer.base.activity.BaseActivity;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.event.OnlineSongErrorEvent;
import com.example.musicplayer.event.SongStatusEvent;
import com.example.musicplayer.service.DownloadService;
import com.example.musicplayer.service.PlayerService;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.util.FileUtil;
@ -71,6 +72,8 @@ public class MainActivity extends BaseActivity {
private MediaPlayer mMediaPlayer;
private Thread mSeekBarThread;
private PlayerService.PlayStatusBinder mPlayStatusBinder;
private DownloadService.DownloadBinder mDownloadBinder;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
@ -84,10 +87,23 @@ public class MainActivity extends BaseActivity {
}
};
//绑定下载服务
private ServiceConnection mDownloadConnection =new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mDownloadBinder = (DownloadService.DownloadBinder) iBinder;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
@Override
public void onDestroy() {
super.onDestroy();
unbindService(connection);
unbindService(mDownloadConnection);
EventBus.getDefault().unregister(this);
if (mSeekBarThread != null || mSeekBarThread.isAlive()) mSeekBarThread.interrupt();
Song song = FileUtil.getSong();
@ -109,7 +125,10 @@ public class MainActivity extends BaseActivity {
LitePal.getDatabase();
//启动服务
Intent playIntent = new Intent(MainActivity.this, PlayerService.class);
Intent downIntent = new Intent(MainActivity.this,DownloadService.class);
bindService(playIntent, connection, Context.BIND_AUTO_CREATE);
bindService(downIntent,mDownloadConnection,Context.BIND_AUTO_CREATE);
//设置属性动画
mCircleAnimator = ObjectAnimator.ofFloat(mCoverIv, "rotation", 0.0f, 360.0f);
mCircleAnimator.setDuration(30000);

@ -43,11 +43,15 @@ import com.example.musicplayer.app.Api;
import com.example.musicplayer.app.Constant;
import com.example.musicplayer.base.activity.BaseMvpActivity;
import com.example.musicplayer.contract.IPlayContract;
import com.example.musicplayer.entiy.DownloadInfo;
import com.example.musicplayer.entiy.DownloadSong;
import com.example.musicplayer.entiy.LocalSong;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.event.DownloadEvent;
import com.example.musicplayer.event.SongCollectionEvent;
import com.example.musicplayer.event.SongStatusEvent;
import com.example.musicplayer.presenter.PlayPresenter;
import com.example.musicplayer.service.DownloadService;
import com.example.musicplayer.service.PlayerService;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.util.DisplayUtil;
@ -62,18 +66,11 @@ import com.example.musicplayer.widget.LrcView;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.litepal.LitePal;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.List;
import butterknife.BindView;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
*
@ -142,7 +139,10 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
private List<LocalSong> mLocalSong;//用来判断是否有本地照片
//服务
private PlayerService.PlayStatusBinder mPlayStatusBinder;
private ServiceConnection connection = new ServiceConnection() {
private DownloadService.DownloadBinder mDownloadBinder;
//播放
private ServiceConnection mPlayConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mPlayStatusBinder = (PlayerService.PlayStatusBinder) service;
@ -179,6 +179,19 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
}
};
//绑定下载服务
private ServiceConnection mDownloadConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mDownloadBinder = (DownloadService.DownloadBinder) iBinder;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
@SuppressLint("HandlerLeak")
private Handler mMusicHandler = new Handler() {
@Override
@ -206,9 +219,11 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
//判断播放状态
mPlayStatus = getIntent().getIntExtra(Constant.PLAYER_STATUS, 2);
//绑定服务
//绑定服务,播放和下载的服务
Intent playIntent = new Intent(PlayActivity.this, PlayerService.class);
bindService(playIntent, connection, Context.BIND_AUTO_CREATE);
Intent downIntent = new Intent(PlayActivity.this, DownloadService.class);
bindService(playIntent, mPlayConnection, Context.BIND_AUTO_CREATE);
bindService(downIntent, mDownloadConnection, Context.BIND_AUTO_CREATE);
//界面填充
mSong = FileUtil.getSong();
@ -219,19 +234,31 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
mSeekBar.setMax((int) mSong.getDuration());
mSeekBar.setProgress((int) mSong.getCurrentTime());
mDownLoadIv.setVisibility(mSong.isOnline() ? View.VISIBLE : View.GONE); //下载按钮是否隐藏
mDownLoadIv.setImageDrawable(mSong.isDownload() ? getDrawable(R.drawable.downloaded) : getDrawable(R.drawable.download_song));
mPlayMode = mPresenter.getPlayMode();//得到播放模式
if(mPlayMode == Constant.PLAY_ORDER){
if (mPlayMode == Constant.PLAY_ORDER) {
mPlayModeBtn.setBackground(getDrawable(R.drawable.play_mode_order));
}else if(mPlayMode == Constant.PLAY_RANDOM){
} else if (mPlayMode == Constant.PLAY_RANDOM) {
mPlayModeBtn.setBackground(getDrawable(R.drawable.play_mode_random));
}else {
} else {
mPlayModeBtn.setBackground(getDrawable(R.drawable.play_mode_single));
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDownloadSuccessEvent(DownloadEvent event){
if(event.getDownloadStatus() == Constant.TYPE_DOWNLOAD_SUCCESS){
mDownLoadIv.setImageDrawable(
LitePal.where("songId=?", mSong.getSongId()).find(DownloadSong.class).size() != 0
? getDrawable(R.drawable.downloaded)
: getDrawable(R.drawable.download_song));
}
}
@Override
protected PlayPresenter getPresenter() {
//与Presenter建立关系
@ -321,7 +348,7 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
public void onStopTrackingTouch(SeekBar seekBar) {
if (mPlayStatusBinder.isPlaying()) {
mMediaPlayer = mPlayStatusBinder.getMediaPlayer();
mMediaPlayer.seekTo(seekBar.getProgress()*1000);
mMediaPlayer.seekTo(seekBar.getProgress() * 1000);
startUpdateSeekBarProgress();
} else {
time = seekBar.getProgress();
@ -347,8 +374,8 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
mPlayStatusBinder.resume();
flag = false;
if (isSeek) {
Log.d(TAG, "onClick: "+time);
mMediaPlayer.seekTo(time*1000);
Log.d(TAG, "onClick: " + time);
mMediaPlayer.seekTo(time * 1000);
isSeek = false;
}
mDisc.play();
@ -360,7 +387,7 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
} else {
mPlayStatusBinder.play(mListType);
}
mMediaPlayer.seekTo((int) mSong.getCurrentTime()*1000);
mMediaPlayer.seekTo((int) mSong.getCurrentTime() * 1000);
mDisc.play();
mPlayBtn.setSelected(true);
startUpdateSeekBarProgress();
@ -399,18 +426,18 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
String lrc = FileUtil.getLrcFromNative(mSong.getSongName());
if (null == lrc) {
String qqId = mSong.getQqId();
if(Constant.SONG_ID_UNFIND.equals(qqId)){//匹配不到歌词
if (Constant.SONG_ID_UNFIND.equals(qqId)) {//匹配不到歌词
getLrcError(null);
}else if(null == qqId){//歌曲的id还未匹配
mPresenter.getSongId(mSong.getSongName(),mSong.getDuration());
}else {//歌词还未匹配
mPresenter.getLrc(qqId,Constant.SONG_LOCAL);
} else if (null == qqId) {//歌曲的id还未匹配
mPresenter.getSongId(mSong.getSongName(), mSong.getDuration());
} else {//歌词还未匹配
mPresenter.getLrc(qqId, Constant.SONG_LOCAL);
}
}else {
} else {
showLrc(lrc);
}
} else {
mPresenter.getLrc(mSong.getSongId(),Constant.SONG_ONLINE);
mPresenter.getLrc(mSong.getSongId(), Constant.SONG_ONLINE);
}
}
);
@ -421,8 +448,11 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
});
//歌曲下载
mDownLoadIv.setOnClickListener(v -> {
CommonUtil.showToast(this, "开始下载歌曲");
downLoad(mSong.getUrl(), mSong.getSongName());
if (mSong.isDownload()) {
showToast(getString(R.string.downloded));
} else {
mDownloadBinder.startDownload(getDownloadInfoFromSong(mSong));
}
});
}
@ -628,60 +658,20 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
@Override
public void getSongIdSuccess(String songId) {
Log.d(TAG, "getSongIdSuccess: "+songId);
Log.d(TAG, "getSongIdSuccess: " + songId);
setLocalSongId(songId);//保存音乐信息
mPresenter.getLrc(songId,Constant.SONG_LOCAL);//获取歌词
mPresenter.getLrc(songId, Constant.SONG_LOCAL);//获取歌词
}
@Override
public void saveLrc(String lrc) {
FileUtil.saveLrcToNative(lrc,mSong.getSongName());
}
private void downLoad(String url, String song) {
new Thread(() -> {
File file = new File(Api.STORAGE_SONG_FILE);
if (!file.exists()) {
file.mkdirs();
}
File songFile = new File(file, song + ".mp3");
BufferedOutputStream out = null;
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
out = new BufferedOutputStream(new FileOutputStream(songFile));
byte[] bytes = response.body().bytes();
out.write(bytes, 0, bytes.length);
out.close();
}
showLoadSuccess();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
FileUtil.saveLrcToNative(lrc, mSong.getSongName());
}
private void showLoadSuccess() {
runOnUiThread(() -> {
CommonUtil.showToast(this, "歌曲下载成功");
});
}
//改变播放模式
private void changePlayMode(){
View playModeView = LayoutInflater.from(this).inflate(R.layout.play_mode,null);
private void changePlayMode() {
View playModeView = LayoutInflater.from(this).inflate(R.layout.play_mode, null);
ConstraintLayout orderLayout = playModeView.findViewById(R.id.orderLayout);
ConstraintLayout randomLayout = playModeView.findViewById(R.id.randomLayout);
ConstraintLayout singleLayout = playModeView.findViewById(R.id.singleLayout);
@ -690,7 +680,7 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
TextView singleTv = playModeView.findViewById(R.id.singleTv);
//显示弹窗
PopupWindow popupWindow = new PopupWindow(playModeView, ScreenUtil.dip2px(this,130),ScreenUtil.dip2px(this,150));
PopupWindow popupWindow = new PopupWindow(playModeView, ScreenUtil.dip2px(this, 130), ScreenUtil.dip2px(this, 150));
//设置背景色
popupWindow.setBackgroundDrawable(getDrawable(R.color.transparent));
//设置焦点
@ -699,20 +689,20 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
popupWindow.setOutsideTouchable(true);
popupWindow.update();
//设置弹出的位置
popupWindow.showAsDropDown(mPlayModeBtn,0,-50);
popupWindow.showAsDropDown(mPlayModeBtn, 0, -50);
//显示播放模式
int mode = mPresenter.getPlayMode();
if(mode == Constant.PLAY_ORDER){
if (mode == Constant.PLAY_ORDER) {
orderTv.setSelected(true);
randomTv.setSelected(false);
singleTv.setSelected(false);
}else if(mode == Constant.PLAY_RANDOM){
} else if (mode == Constant.PLAY_RANDOM) {
randomTv.setSelected(true);
orderTv.setSelected(false);
singleTv.setSelected(false);
}else {
} else {
singleTv.setSelected(true);
randomTv.setSelected(false);
orderTv.setSelected(false);
@ -749,7 +739,8 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
@Override
public void onDestroy() {
super.onDestroy();
unbindService(connection);
unbindService(mPlayConnection);
unbindService(mDownloadConnection);
EventBus.getDefault().unregister(this);
stopUpdateSeekBarProgress();
@ -757,4 +748,15 @@ public class PlayActivity extends BaseMvpActivity<PlayPresenter> implements IPla
mMusicHandler.removeCallbacksAndMessages(null);
}
private DownloadInfo getDownloadInfoFromSong(Song song){
DownloadInfo downloadInfo = new DownloadInfo();
downloadInfo.setSinger(song.getSinger());
downloadInfo.setProgress(0);
downloadInfo.setSongId(song.getSongId());
downloadInfo.setUrl(song.getUrl());
downloadInfo.setSongName(song.getSongName());
downloadInfo.setDuration(song.getDuration());
return downloadInfo;
}
}

@ -5,7 +5,6 @@ import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -14,12 +13,19 @@ import android.widget.TextView;
import com.example.musicplayer.R;
import com.example.musicplayer.adapter.ExpandableListViewAdapter;
import com.example.musicplayer.app.Api;
import com.example.musicplayer.app.Constant;
import com.example.musicplayer.entiy.AlbumCollection;
import com.example.musicplayer.entiy.HistorySong;
import com.example.musicplayer.entiy.LocalSong;
import com.example.musicplayer.entiy.Love;
import com.example.musicplayer.event.AlbumCollectionEvent;
import com.example.musicplayer.event.SongLocalSizeChangeEvent;
import com.example.musicplayer.event.SongListNumEvent;
import com.example.musicplayer.util.DownloadUtil;
import com.example.musicplayer.view.main.collection.CollectionFragment;
import com.example.musicplayer.view.main.download.DownloadFragment;
import com.example.musicplayer.view.main.history.HistoryFragment;
import com.example.musicplayer.view.main.local.LocalFragment;
import com.example.musicplayer.view.search.AlbumContentFragment;
import com.example.musicplayer.widget.MyListView;
@ -40,8 +46,8 @@ public class MainFragment extends Fragment {
private MyListView myListView;
private ExpandableListViewAdapter mAdapter;
private LinearLayout mLocalMusicLinear, mCollectionLinear, mHistoryMusicLinear;
private TextView mLocalMusicNum, mLoveMusicNum, mHistoryMusicNum;
private LinearLayout mLocalMusicLinear, mCollectionLinear, mHistoryMusicLinear,mDownloadLinear;
private TextView mLocalMusicNum, mLoveMusicNum, mHistoryMusicNum,mDownloadMusicNum;
private TextView mSeekBtn;
private List<List<AlbumCollection>> mAlbumCollectionList;
@ -66,6 +72,8 @@ public class MainFragment extends Fragment {
mLocalMusicNum = view.findViewById(R.id.tv_local_music_num);
mLoveMusicNum = view.findViewById(R.id.tv_love_num);
mHistoryMusicNum = view.findViewById(R.id.tv_history_num);
mDownloadMusicNum = view.findViewById(R.id.tv_download_num);
mDownloadLinear = view.findViewById(R.id.downloadLinear);
return view;
}
@ -118,23 +126,39 @@ public class MainFragment extends Fragment {
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onLocalSizeEvent(SongLocalSizeChangeEvent event) {
mLocalMusicNum.setText(String.valueOf(LitePal.findAll(LocalSong.class).size()));
public void onSongListEvent(SongListNumEvent event){
int type = event.getType();
if(type == Constant.LIST_TYPE_HISTORY){
mHistoryMusicNum.setText(String.valueOf(LitePal.findAll(HistorySong.class).size()));
}else if(type == Constant.LIST_TYPE_LOCAL){
mLocalMusicNum.setText(String.valueOf(LitePal.findAll(LocalSong.class).size()));
}else if(type == Constant.LIST_TYPE_DOWNLOAD){
mDownloadMusicNum.setText(String.valueOf(DownloadUtil.getSongFromFile(Api.STORAGE_SONG_FILE).size()));
}
}
private void onClick() {
//本地音乐
mLocalMusicLinear.setOnClickListener(v -> replaceFragment(new LocalFragment()));
//搜索
mSeekBtn.setOnClickListener(v -> replaceFragment(new AlbumContentFragment.SearchFragment()));
//我的收藏
mCollectionLinear.setOnClickListener(v -> replaceFragment(new CollectionFragment()));
//下载
mDownloadLinear.setOnClickListener(view -> replaceFragment(new DownloadFragment()));
//最近播放
mHistoryMusicLinear.setOnClickListener(v -> replaceFragment(new HistoryFragment()));
//歌单点击展开
myListView.setOnGroupExpandListener(groupPosition -> {
if (groupPosition == 1) {
twoExpand = true;
}
});
//歌单点击收缩
myListView.setOnGroupCollapseListener(groupPosition -> {
if (groupPosition == 1) {
twoExpand = false;
@ -179,6 +203,7 @@ public class MainFragment extends Fragment {
mLocalMusicNum.setText(String.valueOf(LitePal.findAll(LocalSong.class).size()));
mLoveMusicNum.setText(String.valueOf(LitePal.findAll(Love.class).size()));
mHistoryMusicNum.setText(String.valueOf(LitePal.findAll(HistorySong.class).size()));
mDownloadMusicNum.setText(String.valueOf(DownloadUtil.getSongFromFile(Api.STORAGE_SONG_FILE).size()));
}
//使数据库中的列表逆序排列

@ -1,4 +1,4 @@
package com.example.musicplayer.view.main;
package com.example.musicplayer.view.main.collection;
import android.content.ComponentName;
@ -32,6 +32,7 @@ import org.litepal.LitePal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Created by on 2018/11/30.
@ -62,7 +63,7 @@ public class CollectionFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View mView = inflater.inflate(R.layout.fragment_love_music, container, false);
View mView = inflater.inflate(R.layout.fragment_love, container, false);
EventBus.getDefault().register(this); //注册事件订阅者
mRecycler = mView.findViewById(R.id.recycler_love_songs);
mBackIv = mView.findViewById(R.id.iv_back);
@ -75,7 +76,7 @@ public class CollectionFragment extends Fragment {
super.onActivityCreated(savedInstanceState);
//启动服务
Intent playIntent = new Intent(getActivity(), PlayerService.class);
getActivity().bindService(playIntent, connection, Context.BIND_AUTO_CREATE);
Objects.requireNonNull(getActivity()).bindService(playIntent, connection, Context.BIND_AUTO_CREATE);
showSongList();
onClick();
}
@ -83,7 +84,7 @@ public class CollectionFragment extends Fragment {
public void onDestroy(){
super.onDestroy();
EventBus.getDefault().unregister(this);
getActivity().unbindService(connection);
Objects.requireNonNull(getActivity()).unbindService(connection);
}
@Subscribe(threadMode = ThreadMode.MAIN )
@ -93,7 +94,7 @@ public class CollectionFragment extends Fragment {
mAdapter.notifyDataSetChanged();
if(songCollectionEvent.isLove()){//定位歌曲
if (FileUtil.getSong() != null) {
mManager.scrollToPositionWithOffset(FileUtil.getSong().getCurrent() + 4, mRecycler.getHeight());
mManager.scrollToPositionWithOffset(FileUtil.getSong().getPosition() + 4, mRecycler.getHeight());
}
}
}
@ -117,8 +118,9 @@ public class CollectionFragment extends Fragment {
song.setOnline(love.isOnline());
song.setUrl(love.getUrl());
song.setImgUrl(love.getPic());
song.setCurrent(position);
song.setPosition(position);
song.setDuration(love.getDuration());
song.setMediaId(love.getMediaId());
song.setListType(Constant.LIST_TYPE_LOVE);
FileUtil.saveSong(song);

@ -0,0 +1,77 @@
package com.example.musicplayer.view.main.download;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.example.musicplayer.R;
import com.example.musicplayer.adapter.TabAdapter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
/**
* <pre>
* author :
* time : 2019/09/16
* desc :
* </pre>
*/
public class DownloadFragment extends Fragment {
@BindView(R.id.backIv)
ImageView backIv;
@BindView(R.id.tabLayout)
TabLayout tabLayout;
@BindView(R.id.page)
ViewPager page;
private Unbinder unbinder;
private List<String> mTitleList;
private List<Fragment> mFragments;
private TabAdapter mAdapter;
private String[] mTitles = {"已下载", "正在下载"};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_download, container, false);
unbinder = ButterKnife.bind(this, view);
initTab();
onClick();
return view;
}
private void initTab() {
mTitleList = new ArrayList<>();
mFragments = new ArrayList<>();
mTitleList.addAll(Arrays.asList(mTitles));
mFragments.add(new DownloadMusicFragment());
mFragments.add(new DownloadingFragment());
mAdapter = new TabAdapter(getChildFragmentManager(), mFragments, mTitleList);
page.setAdapter(mAdapter);
tabLayout.setupWithViewPager(page);
}
private void onClick(){
backIv.setOnClickListener(view -> Objects.requireNonNull(getActivity()).getSupportFragmentManager().popBackStack());
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}

@ -0,0 +1,151 @@
package com.example.musicplayer.view.main.download;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.musicplayer.R;
import com.example.musicplayer.adapter.DownloadSongAdapter;
import com.example.musicplayer.app.Constant;
import com.example.musicplayer.entiy.DownloadSong;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.event.DownloadEvent;
import com.example.musicplayer.event.SongDownloadedEvent;
import com.example.musicplayer.service.PlayerService;
import com.example.musicplayer.util.DownloadUtil;
import com.example.musicplayer.util.FileUtil;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import static com.example.musicplayer.app.Api.STORAGE_SONG_FILE;
/**
* <pre>
* author :
* time : 2019/09/16
* desc :
* </pre>
*/
public class DownloadMusicFragment extends Fragment {
private static final String TAG = "DownloadMusicFragment";
@BindView(R.id.songRecycle)
RecyclerView songRecycle;
Unbinder unbinder;
private LinearLayoutManager mManager;
private DownloadSongAdapter mAdapter;
private List<DownloadSong> mDownloadSongList; //已下载歌曲列表
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) {
}
};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_download_music, container, false);
EventBus.getDefault().register(this);
unbinder = ButterKnife.bind(this, view);
mDownloadSongList = new ArrayList<>();
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//启动服务
Intent playIntent = new Intent(getActivity(), PlayerService.class);
Objects.requireNonNull(getActivity()).bindService(playIntent, connection, Context.BIND_AUTO_CREATE);
showSongList();
}
private void showSongList(){
mDownloadSongList = orderList(DownloadUtil.getSongFromFile(STORAGE_SONG_FILE));
mAdapter = new DownloadSongAdapter(getActivity(), mDownloadSongList);
mManager = new LinearLayoutManager(getActivity());
songRecycle.setLayoutManager(mManager);
songRecycle.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(position -> {
DownloadSong downloadSong = mDownloadSongList.get(position);
Song song = new Song();
song.setSongId(downloadSong.getSongId());
song.setSongName(downloadSong.getName());
song.setSinger(downloadSong.getSinger());
song.setOnline(false);
song.setUrl(downloadSong.getUrl());
Log.d(TAG, "showSongList: "+song.getUrl());
song.setImgUrl(downloadSong.getPic());
song.setPosition(position);
song.setDuration(downloadSong.getDuration());
song.setListType(Constant.LIST_TYPE_DOWNLOAD);
song.setMediaId(downloadSong.getMediaId());
song.setDownload(true);
FileUtil.saveSong(song);
mPlayStatusBinder.play(Constant.LIST_TYPE_DOWNLOAD);
});
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDownloadSuccessEvent(DownloadEvent event){
if(event.getDownloadStatus() == Constant.TYPE_DOWNLOAD_SUCCESS){
mDownloadSongList.clear();
mDownloadSongList.addAll(orderList(DownloadUtil.getSongFromFile(STORAGE_SONG_FILE)));
mAdapter.notifyDataSetChanged();
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSongDownloadedEvent(SongDownloadedEvent event){
mAdapter.notifyDataSetChanged();
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
EventBus.getDefault().unregister(this);
}
private List<DownloadSong> orderList(List<DownloadSong> tempList){
List<DownloadSong> loveList=new ArrayList<>();
loveList.clear();
for(int i=tempList.size()-1;i>=0;i--){
loveList.add(tempList.get(i));
}
return loveList;
}
}

@ -0,0 +1,169 @@
package com.example.musicplayer.view.main.download;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.SpeedDialog.dialog.SpeedDialog;
import com.example.SpeedDialog.listener.OnSelectClickListener;
import com.example.musicplayer.R;
import com.example.musicplayer.adapter.DownloadingAdapter;
import com.example.musicplayer.app.Constant;
import com.example.musicplayer.entiy.DownloadInfo;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.event.DownloadEvent;
import com.example.musicplayer.service.DownloadService;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.litepal.LitePal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
/**
* <pre>
* author :
* time : 2019/09/16
* desc :
* </pre>
*/
public class DownloadingFragment extends Fragment {
private static final String TAG = "DownloadingFragment";
@BindView(R.id.songDowningRecycle)
RecyclerView songDowningRecycle;
Unbinder unbinder;
private DownloadingAdapter mAdapter;
private LinearLayoutManager mLinearLayoutManager;
private List<DownloadInfo> mDownloadInfoList; //下载队列
private DownloadService.DownloadBinder mDownloadBinder;
//绑定下载服务
private ServiceConnection mDownloadConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mDownloadBinder = (DownloadService.DownloadBinder) iBinder;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_download_ing, container, false);
EventBus.getDefault().register(this);
unbinder = ButterKnife.bind(this, view);
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
initRecycler();
//绑定服务
Intent downIntent = new Intent(getActivity(), DownloadService.class);
getActivity().bindService(downIntent, mDownloadConnection, Context.BIND_AUTO_CREATE);
super.onActivityCreated(savedInstanceState);
}
private void initRecycler() {
mDownloadInfoList = new LinkedList<>();
mDownloadInfoList.addAll(LitePal.findAll(DownloadInfo.class,true));
songDowningRecycle.setItemAnimator(null); //解决进度刷新闪屏问题
mLinearLayoutManager = new LinearLayoutManager(getActivity());
mAdapter = new DownloadingAdapter(mDownloadInfoList);
songDowningRecycle.setLayoutManager(mLinearLayoutManager);
songDowningRecycle.setAdapter(mAdapter);
//暂停
mAdapter.setOnItemClickListener(position -> {
DownloadInfo downloadInfo = mDownloadInfoList.get(position);
Log.d(TAG, "initRecycler: "+mDownloadInfoList.get(position).getStatus());
//判断是否为正在播放的歌曲
if(downloadInfo.getStatus() == Constant.DOWNLOAD_PAUSED){
mDownloadBinder.startDownload(downloadInfo);
}else {
//传入要暂停的音乐id
mDownloadBinder.pauseDownload(downloadInfo.getSongId());
}
});
//取消下载
mAdapter.setOnDeleteClickListener(position -> {
SpeedDialog speedDialog = new SpeedDialog(getActivity(),SpeedDialog.SELECT_TYPE);
speedDialog.setTitle(getString(R.string.download_cancel))
.setMessage(getString(R.string.download_cancel_message))
.setSureText(getString(R.string.download_sure))
.setSureClickListener(dialog -> {
mDownloadBinder.cancelDownload(mDownloadInfoList.get(position));
})
.show();
});
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDownloadingMessage(DownloadEvent event) {
int status = event.getDownloadStatus();
if (status == Constant.TYPE_DOWNLOADING || status == Constant.TYPE_DOWNLOAD_PAUSED) {//进度条更新
DownloadInfo downloadInfo = event.getDownloadInfo();
mDownloadInfoList.remove(downloadInfo.getPosition());
mDownloadInfoList.add(downloadInfo.getPosition(),downloadInfo);
mAdapter.notifyItemChanged(downloadInfo.getPosition());
}else if(status == Constant.TYPE_DOWNLOAD_SUCCESS){//歌曲下载成功
resetDownloadInfoList();
mAdapter.notifyDataSetChanged();
}else if(status == Constant.TYPE_DOWNLOAD_CANCELED){//下载取消
resetDownloadInfoList();
mAdapter.notifyDataSetChanged();
}else if(status == Constant.TYPE_DOWNLOAD_ADD){//添加了正在下载歌曲
resetDownloadInfoList();
}
}
//重新从数据库中读取需要下载的歌曲
private void resetDownloadInfoList(){
mDownloadInfoList.clear();
List<DownloadInfo> temp = LitePal.findAll(DownloadInfo.class,true);
if(temp.size()!=0){
mDownloadInfoList.addAll(temp);
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
EventBus.getDefault().unregister(this);
unbinder.unbind();
}
}

@ -1,4 +1,4 @@
package com.example.musicplayer.view.main;
package com.example.musicplayer.view.main.history;
import android.content.ComponentName;
import android.content.Context;
@ -67,7 +67,7 @@ public class HistoryFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_love_music, container, false);
View view = inflater.inflate(R.layout.fragment_love, container, false);
EventBus.getDefault().register(this);
mRecycler = view.findViewById(R.id.recycler_love_songs);
mBackIv = view.findViewById(R.id.iv_back);
@ -117,8 +117,9 @@ public class HistoryFragment extends Fragment {
song.setOnline(history.isOnline());
song.setUrl(history.getUrl());
song.setImgUrl(history.getPic());
song.setCurrent(position);
song.setPosition(position);
song.setDuration(history.getDuration());
song.setMediaId(history.getMediaId());
song.setListType(Constant.LIST_TYPE_HISTORY);
FileUtil.saveSong(song);

@ -1,4 +1,4 @@
package com.example.musicplayer.view.main;
package com.example.musicplayer.view.main.local;
import android.content.ComponentName;
import android.content.Context;
@ -97,7 +97,7 @@ public class LocalFragment extends BaseMvpFragment<LocalPresenter> implements IL
public void onMessageEvent(SongLocalEvent event){
songAdapter.notifyDataSetChanged();
if (FileUtil.getSong() != null) {
layoutManager.scrollToPositionWithOffset(FileUtil.getSong().getCurrent() + 4, mRecycler.getHeight());
layoutManager.scrollToPositionWithOffset(FileUtil.getSong().getPosition() + 4, mRecycler.getHeight());
}
}
@ -115,7 +115,7 @@ public class LocalFragment extends BaseMvpFragment<LocalPresenter> implements IL
@Override
protected int getLayoutId() {
return R.layout.fragment_local_music;
return R.layout.fragment_local;
}
@ -137,7 +137,7 @@ public class LocalFragment extends BaseMvpFragment<LocalPresenter> implements IL
song.setSinger(mp3Info.getSinger());
song.setUrl(mp3Info.getUrl());
song.setDuration(mp3Info.getDuration());
song.setCurrent(position);
song.setPosition(position);
song.setOnline(false);
song.setSongId(mp3Info.getSongId());
song.setListType(Constant.LIST_TYPE_LOCAL);
@ -179,7 +179,7 @@ public class LocalFragment extends BaseMvpFragment<LocalPresenter> implements IL
songAdapter = new SongAdapter(mActivity, mLocalSongsList);
mRecycler.setAdapter(songAdapter);
if (FileUtil.getSong() != null) {
layoutManager.scrollToPositionWithOffset(FileUtil.getSong().getCurrent() - 4, mRecycler.getHeight());
layoutManager.scrollToPositionWithOffset(FileUtil.getSong().getPosition() - 4, mRecycler.getHeight());
}
songAdapter.setOnItemClickListener(position -> {
//将点击的序列化到本地
@ -189,7 +189,7 @@ public class LocalFragment extends BaseMvpFragment<LocalPresenter> implements IL
song.setSinger(mp3Info.getSinger());
song.setUrl(mp3Info.getUrl());
song.setDuration(mp3Info.getDuration());
song.setCurrent(position);
song.setPosition(position);
song.setOnline(false);
song.setSongId(mp3Info.getSongId());
song.setListType(Constant.LIST_TYPE_LOCAL);

@ -23,6 +23,7 @@ import com.example.musicplayer.app.Constant;
import com.example.musicplayer.base.fragment.BaseMvpFragment;
import com.example.musicplayer.contract.IAlbumSongContract;
import com.example.musicplayer.entiy.AlbumSong;
import com.example.musicplayer.entiy.DownloadSong;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.event.SongAlbumEvent;
import com.example.musicplayer.presenter.AlbumSongPresenter;
@ -190,12 +191,15 @@ public class AlbumSongFragment extends BaseMvpFragment<AlbumSongPresenter> imple
song.setSongId(dataBean.getSongmid());
song.setSinger(getSinger(dataBean));
song.setSongName(dataBean.getSongname());
song.setCurrent(position);
song.setPosition(position);
song.setDuration(dataBean.getInterval());
song.setOnline(true);
song.setListType(Constant.LIST_TYPE_ONLINE);
song.setImgUrl(Api.ALBUM_PIC+dataBean.getAlbummid()+ Api.JPG);
song.setUrl(null);
song.setMediaId(dataBean.getStrMediaMid());
//判断是否已经下载
song.setDownload(LitePal.where("songId=?", dataBean.getSongmid()).find(DownloadSong.class).size() != 0);
FileUtil.saveSong(song);
mPlayStatusBinder.play(Constant.LIST_TYPE_ONLINE);

@ -9,7 +9,7 @@ import android.view.View;
import android.view.ViewGroup;
import com.example.musicplayer.R;
import com.example.musicplayer.adapter.SearchAdapter;
import com.example.musicplayer.adapter.TabAdapter;
import java.util.ArrayList;
import java.util.List;
@ -23,7 +23,7 @@ public class ContentFragment extends Fragment {
private List<String> mTitleList;
private List<Fragment> mFragments;
private ViewPager mPager;
private SearchAdapter mAdapter;
private TabAdapter mAdapter;
private TabLayout mTabLayout;
private String[] mTitles = {"歌曲", "专辑"};
private String[] mTypes = {"song", "album"};
@ -48,18 +48,12 @@ public class ContentFragment extends Fragment {
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
private void initTab() {
for (int i = 0; i < mTitles.length; i++) {
mTitleList.add(mTitles[i]);
mFragments.add(SearchContentFragment.newInstance(mSeek, mTypes[i]));
}
mAdapter = new SearchAdapter(getChildFragmentManager(), mFragments, mTitleList);
mAdapter = new TabAdapter(getChildFragmentManager(), mFragments, mTitleList);
mPager.setAdapter(mAdapter);
mTabLayout.setupWithViewPager(mPager);

@ -20,6 +20,7 @@ import com.example.musicplayer.app.Constant;
import com.example.musicplayer.base.fragment.BaseLoadingFragment;
import com.example.musicplayer.contract.ISearchContentContract;
import com.example.musicplayer.entiy.Album;
import com.example.musicplayer.entiy.DownloadSong;
import com.example.musicplayer.entiy.SearchSong;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.event.OnlineSongChangeEvent;
@ -27,6 +28,7 @@ import com.example.musicplayer.event.OnlineSongErrorEvent;
import com.example.musicplayer.presenter.SearchContentPresenter;
import com.example.musicplayer.service.PlayerService;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.util.DownloadUtil;
import com.example.musicplayer.util.FileUtil;
import com.github.jdsjlzx.recyclerview.LRecyclerView;
import com.github.jdsjlzx.recyclerview.LRecyclerViewAdapter;
@ -34,6 +36,7 @@ import com.github.jdsjlzx.recyclerview.LRecyclerViewAdapter;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.litepal.LitePal;
import java.util.ArrayList;
import java.util.List;
@ -165,12 +168,12 @@ public class SearchContentFragment extends BaseLoadingFragment<SearchContentPres
song.setSinger(getSinger(dataBean));
song.setSongName(dataBean.getSongname());
song.setImgUrl(Api.ALBUM_PIC+dataBean.getAlbummid()+Api.JPG);
song.setCurrent(position);
song.setDuration(dataBean.getInterval());
song.setOnline(true);
FileUtil.saveSong(song);
song.setMediaId(dataBean.getStrMediaMid());
song.setDownload(DownloadUtil.isExistOfDownloadSong(dataBean.getSongmid()));
//网络获取歌曲地址
mPresenter.getSongUrl(dataBean.getSongmid());
mPresenter.getSongUrl(song);
});
}
@ -238,9 +241,7 @@ public class SearchContentFragment extends BaseLoadingFragment<SearchContentPres
}
@Override
public void getSongUrlSuccess(String url) {
Song song= FileUtil.getSong();
assert song != null;
public void getSongUrlSuccess(Song song,String url) {
song.setUrl(url);
FileUtil.saveSong(song);
mPlayStatusBinder.playOnline();

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

@ -58,7 +58,7 @@
android:layout_below="@+id/iv_icon"
android:textColor="@color/white"
android:textSize="16sp"
android:text="袁健策版权所有@2018"/>
android:text="@string/welcome_text"/>
</LinearLayout>
</RelativeLayout>

@ -0,0 +1,49 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="@color/actionBarColor">
<ImageView
android:id="@+id/backIv"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerVertical="true"
android:layout_marginStart="10dp"
android:src="@drawable/back" />
<TextView
android:id="@+id/titleTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="5dp"
android:layout_toRightOf="@id/backIv"
android:text="@string/download"
android:textColor="@color/white"
android:textSize="16sp" />
</RelativeLayout>
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:background="@color/tab"
android:layout_width="match_parent"
android:layout_height="40dp"
style="@style/MyTabLayoutStyle">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/page"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/translucent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/songDowningRecycle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="65dp"
tools:listitem="@layout/recycler_downing_item">
</android.support.v7.widget.RecyclerView>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="65dp"
android:overScrollMode="never"/>
</LinearLayout>

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/translucent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/songRecycle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="65dp">
</android.support.v7.widget.RecyclerView>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="65dp"
android:overScrollMode="never"/>
</LinearLayout>

@ -38,7 +38,7 @@
android:focusable="true"
android:focusableInTouchMode="true"
android:paddingStart="15dp"
android:hint="周杰伦"
android:hint="@string/search_singer"
android:textColor="@color/white"
android:textSize="16sp" />

@ -116,11 +116,13 @@
android:textColor="@drawable/selector_linear_click"/>
</LinearLayout>
<LinearLayout
android:id="@+id/downloadLinear"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:clickable="true"
android:orientation="vertical">
android:orientation="vertical"
android:focusable="true">
<ImageView
@ -138,10 +140,10 @@
android:text="@string/download"
android:textColor="@drawable/selector_linear_click"/>
<TextView
android:id="@+id/tv_download_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="0"
android:textColor="@drawable/selector_linear_click"/>
</LinearLayout>
<LinearLayout

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<TextView
android:id="@+id/songTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="@color/white"
tools:text="说好不哭"
android:layout_marginStart="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_10"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<TextView
android:id="@+id/sizeTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/short_white"
android:layout_marginTop="@dimen/dp_5"
tools:text="2.7M "
app:layout_constraintLeft_toLeftOf="@+id/songTv"
app:layout_constraintTop_toBottomOf="@+id/songTv"/>
<SeekBar
android:id="@+id/seekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:thumb="@null"
android:progressDrawable="@drawable/seekbar_bg"
android:maxHeight="5dp"
android:max="100"
app:layout_constraintLeft_toRightOf="@+id/sizeTv"
app:layout_constraintTop_toTopOf="@+id/sizeTv"
app:layout_constraintRight_toLeftOf="@id/cancelIv"
app:layout_constraintBottom_toBottomOf="@id/sizeTv"
/>
<ImageView
android:id="@+id/cancelIv"
android:layout_width="@dimen/dp_30"
android:layout_height="@dimen/dp_30"
android:src="@drawable/delete"
android:layout_marginEnd="@dimen/dp_10"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
<View
android:layout_width="match_parent"
android:layout_height="0.1dip"
android:background="@color/gray"
android:layout_marginTop="@dimen/dp_10"
app:layout_constraintTop_toBottomOf="@id/sizeTv"/>
</android.support.constraint.ConstraintLayout>

@ -17,7 +17,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text=""
android:text="@string/me"
android:gravity="center"
android:textColor="@color/musicStyle"
android:textSize="22sp"/>
@ -26,22 +26,14 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text=""
android:text="@string/listen"
android:textSize="20sp"
android:textColor="@color/white_blue"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="看"
android:gravity="center"
android:textSize="20sp"
android:textColor="@color/white_blue"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="唱"
android:text="@string/look"
android:gravity="center"
android:textSize="20sp"
android:textColor="@color/white_blue"/>

@ -49,5 +49,18 @@
<string name="play_mode_order">顺序播放</string>
<string name="play_mode_random">随机播放</string>
<string name="play_mode_single">单曲循环</string>
<string name="bias">&#160;/&#160;</string>
//download
<string name="downloded">该歌曲已下载</string>
<string name="download_cancel">取消下载</string>
<string name="download_cancel_message">确定不再下载吗?</string>
<string name="download_sure">删除</string>
<string name="search_singer">邓紫棋</string>
<string name="look"></string>
<string name="listen"></string>
<string name="me"></string>
<string name="welcome_text">随心所动,开启你的音乐之旅</string>
</resources>

@ -43,6 +43,12 @@
<item name="android:thumb">@drawable/ic_seekbar_thumb</item>
</style>
<style name="download_seek_bar_sytle" parent="Widget.AppCompat.SeekBar">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:thumb">@null</item>
</style>
<style name="text_style">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>

@ -3,13 +3,12 @@ apply from: 'config.gradle'
buildscript {
repositories {
mavenCentral()
google()
jcenter()
jcenter{ url "http://jcenter.bintray.com/"}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.android.tools.build:gradle:3.5.0'
// NOTE: Do not place your application dependencies here; they belong
@ -19,6 +18,8 @@ buildscript {
allprojects {
repositories {
mavenCentral()
maven { url 'https://maven.google.com' }
google()
jcenter()
maven { url "https://jitpack.io" }

@ -5,7 +5,7 @@
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# http://www.gradle.org/docs/position/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
@ -13,6 +13,6 @@ org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# http://www.gradle.org/docs/position/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Loading…
Cancel
Save