From 357aa17ccd0e2671eb4aabe08568b54e8797dfe5 Mon Sep 17 00:00:00 2001 From: jsyjst Date: Tue, 17 Sep 2019 22:58:04 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E6=AD=8C=E6=9B=B2=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E5=AE=9E=E7=8E=B0=E4=B8=8B=E8=BD=BD=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E7=9A=84=E4=B8=8B=E8=BD=BD=E4=B8=AD=E7=9A=84=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/codeStyles/Project.xml | 134 ++++++++++--- app/src/main/AndroidManifest.xml | 15 +- .../adapter/DownloadingAdapter.java | 104 ++++++++++ .../{SearchAdapter.java => TabAdapter.java} | 4 +- .../java/com/example/musicplayer/app/Api.java | 4 +- .../com/example/musicplayer/app/Constant.java | 7 + .../download/DownloadListener.java | 19 ++ .../musicplayer/download/DownloadTask.java | 179 ++++++++++++++++++ .../musicplayer/entiy/DownloadInfo.java | 58 ++++++ .../musicplayer/event/DownloadEvent.java | 29 +++ .../musicplayer/service/DownloadService.java | 162 ++++++++++++++++ .../example/musicplayer/util/MediaUtil.java | 7 + .../musicplayer/view/MainActivity.java | 19 ++ .../musicplayer/view/PlayActivity.java | 37 +++- .../musicplayer/view/main/MainFragment.java | 21 +- .../{ => collection}/CollectionFragment.java | 4 +- .../view/main/download/DownloadFragment.java | 77 ++++++++ .../main/download/DownloadMusicFragment.java | 28 +++ .../main/download/DownloadingFragment.java | 87 +++++++++ .../main/{ => history}/HistoryFragment.java | 4 +- .../view/main/{ => local}/LocalFragment.java | 4 +- .../view/search/ContentFragment.java | 12 +- app/src/main/res/layout/fragment_download.xml | 49 +++++ .../main/res/layout/fragment_download_ing.xml | 23 +++ .../res/layout/fragment_download_music.xml | 21 ++ ...ent_local_music.xml => fragment_local.xml} | 0 ...gment_love_music.xml => fragment_love.xml} | 0 app/src/main/res/layout/function.xml | 4 +- .../main/res/layout/recycler_downing_item.xml | 80 ++++++++ app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/styles.xml | 6 + build.gradle | 7 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 33 files changed, 1145 insertions(+), 63 deletions(-) create mode 100644 app/src/main/java/com/example/musicplayer/adapter/DownloadingAdapter.java rename app/src/main/java/com/example/musicplayer/adapter/{SearchAdapter.java => TabAdapter.java} (83%) create mode 100644 app/src/main/java/com/example/musicplayer/download/DownloadListener.java create mode 100644 app/src/main/java/com/example/musicplayer/download/DownloadTask.java create mode 100644 app/src/main/java/com/example/musicplayer/entiy/DownloadInfo.java create mode 100644 app/src/main/java/com/example/musicplayer/event/DownloadEvent.java create mode 100644 app/src/main/java/com/example/musicplayer/service/DownloadService.java rename app/src/main/java/com/example/musicplayer/view/main/{ => collection}/CollectionFragment.java (97%) create mode 100644 app/src/main/java/com/example/musicplayer/view/main/download/DownloadFragment.java create mode 100644 app/src/main/java/com/example/musicplayer/view/main/download/DownloadMusicFragment.java create mode 100644 app/src/main/java/com/example/musicplayer/view/main/download/DownloadingFragment.java rename app/src/main/java/com/example/musicplayer/view/main/{ => history}/HistoryFragment.java (97%) rename app/src/main/java/com/example/musicplayer/view/main/{ => local}/LocalFragment.java (98%) create mode 100644 app/src/main/res/layout/fragment_download.xml create mode 100644 app/src/main/res/layout/fragment_download_ing.xml create mode 100644 app/src/main/res/layout/fragment_download_music.xml rename app/src/main/res/layout/{fragment_local_music.xml => fragment_local.xml} (100%) rename app/src/main/res/layout/{fragment_love_music.xml => fragment_love.xml} (100%) create mode 100644 app/src/main/res/layout/recycler_downing_item.xml diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 30aa626..ae78c11 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,29 +1,113 @@ - - - - - - - - - - + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
\ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3d009b6..3b93537 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ @@ -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"> @@ -24,14 +26,19 @@ + /> + android:exported="true"/> - + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/musicplayer/adapter/DownloadingAdapter.java b/app/src/main/java/com/example/musicplayer/adapter/DownloadingAdapter.java new file mode 100644 index 0000000..74ff9b2 --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/adapter/DownloadingAdapter.java @@ -0,0 +1,104 @@ +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.SeekBar; +import android.widget.TextView; + +import com.example.musicplayer.R; +import com.example.musicplayer.entiy.DownloadInfo; +import com.example.musicplayer.util.MediaUtil; + +import java.util.List; + +/** + *
+ *     author : 残渊
+ *     time   : 2019/09/17
+ *     desc   :
+ * 
+ */ + +public class DownloadingAdapter extends RecyclerView.Adapter { + private List downloadInfoList; + private int footerViewType = 1; + private int itemViewType = 0; + + public DownloadingAdapter(List downloadInfoList) { + this.downloadInfoList = downloadInfoList; + } + + class ViewHolder extends RecyclerView.ViewHolder { + TextView songTv; + TextView currentSizeTv; + TextView totalSizeTv; + SeekBar seekBar; + View itemView; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + this.itemView = itemView; + songTv = itemView.findViewById(R.id.songTv); + currentSizeTv = itemView.findViewById(R.id.currentSizeTv); + totalSizeTv = itemView.findViewById(R.id.totalSizeTv); + seekBar = itemView.findViewById(R.id.seekBar); + } + } + + /** + * 底部holder + */ + static class FooterHolder extends RecyclerView.ViewHolder { + + TextView numTv; + + FooterHolder(View itemView) { + super(itemView); + numTv = itemView.findViewById(R.id.tv_song_num); + } + } + + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + if (i == itemViewType) { + View view = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.recycler_downing_item, viewGroup, false); + ViewHolder viewHolder = new ViewHolder(view); + return viewHolder; + } else { + View footerView = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.footer_local_songs_item, viewGroup, false); + FooterHolder footerHolder = new FooterHolder(footerView); + return footerHolder; + } + } + + @SuppressLint("SetTextI18n") + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { + ViewHolder holder = (ViewHolder) viewHolder; + DownloadInfo downloadInfo = downloadInfoList.get(i); + holder.itemView.setVisibility(downloadInfo.getProgress() == 100 ? View.GONE : View.VISIBLE); + holder.songTv.setText(downloadInfo.getSongName()); + holder.currentSizeTv.setText(MediaUtil.formatSize(downloadInfo.getCurrentSize()) + "M"); + holder.totalSizeTv.setText(MediaUtil.formatSize(downloadInfo.getTotalSize()) + "M"); + holder.seekBar.setProgress(downloadInfo.getProgress()); + + } + + @Override + public int getItemCount() { + return downloadInfoList.size() + 1; + } + + @Override + public int getItemViewType(int position) { + return position + 1 == getItemCount() ? footerViewType : itemViewType; + } +} diff --git a/app/src/main/java/com/example/musicplayer/adapter/SearchAdapter.java b/app/src/main/java/com/example/musicplayer/adapter/TabAdapter.java similarity index 83% rename from app/src/main/java/com/example/musicplayer/adapter/SearchAdapter.java rename to app/src/main/java/com/example/musicplayer/adapter/TabAdapter.java index c9c93b9..2bc27d9 100644 --- a/app/src/main/java/com/example/musicplayer/adapter/SearchAdapter.java +++ b/app/src/main/java/com/example/musicplayer/adapter/TabAdapter.java @@ -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 mFragmentList;//顶部导航栏的内容即fragment private List mTitle;//顶部导航栏的标题 - public SearchAdapter(FragmentManager fragmentManager, Listfragments, Listtitle){ + public TabAdapter(FragmentManager fragmentManager, Listfragments, Listtitle){ super(fragmentManager); mFragmentList=fragments; mTitle=title; diff --git a/app/src/main/java/com/example/musicplayer/app/Api.java b/app/src/main/java/com/example/musicplayer/app/Api.java index a36a6e2..2a6fa24 100644 --- a/app/src/main/java/com/example/musicplayer/app/Api.java +++ b/app/src/main/java/com/example/musicplayer/app/Api.java @@ -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/"; diff --git a/app/src/main/java/com/example/musicplayer/app/Constant.java b/app/src/main/java/com/example/musicplayer/app/Constant.java index 89763da..3d4f299 100644 --- a/app/src/main/java/com/example/musicplayer/app/Constant.java +++ b/app/src/main/java/com/example/musicplayer/app/Constant.java @@ -61,4 +61,11 @@ public class Constant { //Preferences public static final String SHARED_PREFERENCES_NAME = "prefs"; public static final String PREFS_PLAY_MODE="play_mode";//播放状态 + + //download + public final static int TYPE_DOWNLOADING=0; + public final static int TYPE_PAUSED = 1; + public final static int TYPE_CANCELED = 2; + public final static int TYPE_SUCCESS = 3; + public final static int TYPE_FAILED = 4; } diff --git a/app/src/main/java/com/example/musicplayer/download/DownloadListener.java b/app/src/main/java/com/example/musicplayer/download/DownloadListener.java new file mode 100644 index 0000000..d1514c6 --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/download/DownloadListener.java @@ -0,0 +1,19 @@ +package com.example.musicplayer.download; + +import com.example.musicplayer.entiy.DownloadInfo; + +/** + *
+ *     author : 残渊
+ *     time   : 2019/04/08
+ *     desc   : 监听下载过程中的各种状态
+ * 
+ */ + +public interface DownloadListener { + void onProgress(DownloadInfo downloadInfo); //进度 + void onSuccess(); //成功 + void onFailed(); //失败 + void onPaused(); //暂停 + void onCanceled(); //取消 +} diff --git a/app/src/main/java/com/example/musicplayer/download/DownloadTask.java b/app/src/main/java/com/example/musicplayer/download/DownloadTask.java new file mode 100644 index 0000000..4e7d525 --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/download/DownloadTask.java @@ -0,0 +1,179 @@ +package com.example.musicplayer.download; + +import android.os.AsyncTask; +import android.os.Environment; +import android.util.Log; + + +import com.example.musicplayer.app.Api; +import com.example.musicplayer.entiy.DownloadInfo; + +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.*; + + +/** + *
+ *     author : 残渊
+ *     time   : 2019/04/08
+ *     desc   :
+ * 
+ */ + +public class DownloadTask extends AsyncTask { + + 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(); + + //传过来的下载地址 + // http://ws.stream.qqmusic.qq.com/C400001DI2Jj3Jqve9.m4a?guid=358840384&vkey=2B9BF114492F203C3943D8AE38C83DD8FEEA5E628B18F7F4455CA9B5059040266D74EBD43E09627AA4419D379B6A9E1FC1E5D2104AC7BB50&uin=0&fromtag=66 + File downloadFile = new File(Api.STORAGE_SONG_FILE); + if (!downloadFile.exists()) { + downloadFile.mkdirs(); + } + + String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1, downloadUrl.indexOf("?")); + Log.d(TAG, "doInBackground: fileName=" + fileName); + String directory = String.valueOf(downloadFile); + file = new File(directory + fileName); + if (file.exists()) { + downloadedLength = file.length(); + } + long contentLength = getContentLength(downloadUrl); //实际文件长度 + if (contentLength == 0) { + return TYPE_FAILED; + } else if (contentLength == downloadedLength) { + return TYPE_SUCCESS; + } + + + 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_CANCELED; + } else if (isPaused) { + return TYPE_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_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_FAILED; + } + + @Override + public void onProgressUpdate(DownloadInfo... downloadInfos) { + DownloadInfo downloadInfo = downloadInfos[0]; + int progress = downloadInfo.getProgress(); + Log.d(TAG, "onProgressUpdate: " + progress); + if (progress > lastProgress) { + mDownListener.onProgress(downloadInfo); + lastProgress = progress; + } + } + + @Override + protected void onPostExecute(Integer status) { + switch (status) { + case TYPE_SUCCESS: + mDownListener.onSuccess(); + break; + case TYPE_FAILED: + mDownListener.onFailed(); + break; + case TYPE_PAUSED: + mDownListener.onPaused(); + break; + case TYPE_CANCELED: + mDownListener.onCanceled(); + break; + 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; + } +} diff --git a/app/src/main/java/com/example/musicplayer/entiy/DownloadInfo.java b/app/src/main/java/com/example/musicplayer/entiy/DownloadInfo.java new file mode 100644 index 0000000..54da91c --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/entiy/DownloadInfo.java @@ -0,0 +1,58 @@ +package com.example.musicplayer.entiy; + +/** + *
+ *     author : 残渊
+ *     time   : 2019/09/17
+ *     desc   : 下载的信息
+ * 
+ */ + +public class DownloadInfo { + private String songName; + private String url; + private int progress; + private long currentSize; + private long totalSize; + + public int getProgress() { + return progress; + } + + public long getCurrentSize() { + return currentSize; + } + + public long getTotalSize() { + return totalSize; + } + + public String getSongName() { + return songName; + } + + + public void setCurrentSize(long currentSize) { + this.currentSize = currentSize; + } + + public void setProgress(int progress) { + this.progress = progress; + } + + public void setSongName(String songName) { + this.songName = songName; + } + + public void setTotalSize(long totalSize) { + this.totalSize = totalSize; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/app/src/main/java/com/example/musicplayer/event/DownloadEvent.java b/app/src/main/java/com/example/musicplayer/event/DownloadEvent.java new file mode 100644 index 0000000..5277afc --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/event/DownloadEvent.java @@ -0,0 +1,29 @@ +package com.example.musicplayer.event; + +import com.example.musicplayer.entiy.DownloadInfo; + +/** + *
+ *     author : 残渊
+ *     time   : 2019/09/16
+ *     desc   :
+ * 
+ */ + +public class DownloadEvent { + private int downloadStatus;//下载的状态 + private DownloadInfo downloadInfo; + + public DownloadEvent(int status, DownloadInfo downloadInfo){ + downloadStatus = status; + this.downloadInfo = downloadInfo; + } + + public int getDownloadStatus() { + return downloadStatus; + } + + public DownloadInfo getDownloadInfo() { + return downloadInfo; + } +} diff --git a/app/src/main/java/com/example/musicplayer/service/DownloadService.java b/app/src/main/java/com/example/musicplayer/service/DownloadService.java new file mode 100644 index 0000000..3b33ddf --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/service/DownloadService.java @@ -0,0 +1,162 @@ +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.Environment; +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.download.DownloadTask; +import com.example.musicplayer.entiy.DownloadInfo; +import com.example.musicplayer.event.DownloadEvent; +import com.example.musicplayer.download.DownloadListener; +import com.example.musicplayer.view.MainActivity; + +import org.greenrobot.eventbus.EventBus; + +import java.io.File; + +import static com.example.musicplayer.app.Constant.TYPE_DOWNLOADING; + +/** + *
+ *     author : 残渊
+ *     time   : 2019/04/08
+ *     desc   : 下载服务,保证DownloadTask在后台运行
+ * 
+ */ + +public class DownloadService extends Service { + + private DownloadTask downloadTask; + private String downloadUrl; + private DownloadBinder downloadBinder = new DownloadBinder(); + private DownloadListener listener = new DownloadListener() { + @Override + public void onProgress(DownloadInfo downloadInfo) { + EventBus.getDefault().postSticky(new DownloadEvent(TYPE_DOWNLOADING,downloadInfo)); + getNotificationManager().notify(1, getNotification("下载中......", downloadInfo.getProgress())); + } + + @Override + public void onSuccess() { + downloadTask = null; + //下载成功通知前台服务通知关闭,并创建一个下载成功的通知 + stopForeground(true); + getNotificationManager().notify(1, getNotification("下载成功", -1)); + Toast.makeText(DownloadService.this, "下载成功", Toast.LENGTH_SHORT).show(); + } + + @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; + 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 downloadInfo) { + if (downloadTask == null) { + downloadUrl = downloadInfo.getUrl(); + downloadTask = new DownloadTask(listener); + downloadTask.execute(downloadInfo); + startForeground(1, getNotification("下载中......", 0)); + Toast.makeText(DownloadService.this, "下载中......", Toast.LENGTH_SHORT).show(); + } + } + + public void pauseDownload() { + if (downloadTask != null) { + downloadTask.pauseDownload(); + } + } + + public void cancelDownload() { + if (downloadTask != null) { + downloadTask.cancelDownload(); + } else { + if (downloadUrl != null) { + //取消下载需要将文件删除并将通知关闭 + String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/")); + String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath(); + File file = new File(fileName + directory); + if (file.exists()) { + file.delete(); + } + getNotificationManager().cancel(1); + stopForeground(true); + Toast.makeText(DownloadService.this, "下载已取消", Toast.LENGTH_SHORT).show(); + } + } + } + } + + + 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(); + } + } +} diff --git a/app/src/main/java/com/example/musicplayer/util/MediaUtil.java b/app/src/main/java/com/example/musicplayer/util/MediaUtil.java index 12bc83b..70c1fd5 100644 --- a/app/src/main/java/com/example/musicplayer/util/MediaUtil.java +++ b/app/src/main/java/com/example/musicplayer/util/MediaUtil.java @@ -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); + } + } diff --git a/app/src/main/java/com/example/musicplayer/view/MainActivity.java b/app/src/main/java/com/example/musicplayer/view/MainActivity.java index fd9ae3e..51714a8 100644 --- a/app/src/main/java/com/example/musicplayer/view/MainActivity.java +++ b/app/src/main/java/com/example/musicplayer/view/MainActivity.java @@ -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); diff --git a/app/src/main/java/com/example/musicplayer/view/PlayActivity.java b/app/src/main/java/com/example/musicplayer/view/PlayActivity.java index fdd0e9d..d43be4a 100644 --- a/app/src/main/java/com/example/musicplayer/view/PlayActivity.java +++ b/app/src/main/java/com/example/musicplayer/view/PlayActivity.java @@ -43,11 +43,13 @@ 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.LocalSong; import com.example.musicplayer.entiy.Song; 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; @@ -67,10 +69,10 @@ 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.Connection; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; @@ -142,7 +144,10 @@ public class PlayActivity extends BaseMvpActivity implements IPla private List 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 +184,19 @@ public class PlayActivity extends BaseMvpActivity 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 +224,11 @@ public class PlayActivity extends BaseMvpActivity 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(); @@ -422,7 +442,11 @@ public class PlayActivity extends BaseMvpActivity implements IPla //歌曲下载 mDownLoadIv.setOnClickListener(v -> { CommonUtil.showToast(this, "开始下载歌曲"); - downLoad(mSong.getUrl(), mSong.getSongName()); + DownloadInfo downloadInfo = new DownloadInfo(); + downloadInfo.setUrl(mSong.getUrl()); + downloadInfo.setSongName(mSong.getSongName()); + mDownloadBinder.startDownload(downloadInfo); + //downLoad(mSong.getUrl(), mSong.getSongName()); }); } @@ -749,7 +773,8 @@ public class PlayActivity extends BaseMvpActivity implements IPla @Override public void onDestroy() { super.onDestroy(); - unbindService(connection); + unbindService(mPlayConnection); + unbindService(mDownloadConnection); EventBus.getDefault().unregister(this); stopUpdateSeekBarProgress(); diff --git a/app/src/main/java/com/example/musicplayer/view/main/MainFragment.java b/app/src/main/java/com/example/musicplayer/view/main/MainFragment.java index cd0b8ab..2e325e3 100644 --- a/app/src/main/java/com/example/musicplayer/view/main/MainFragment.java +++ b/app/src/main/java/com/example/musicplayer/view/main/MainFragment.java @@ -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; @@ -20,6 +19,10 @@ 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.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,7 +43,7 @@ public class MainFragment extends Fragment { private MyListView myListView; private ExpandableListViewAdapter mAdapter; - private LinearLayout mLocalMusicLinear, mCollectionLinear, mHistoryMusicLinear; + private LinearLayout mLocalMusicLinear, mCollectionLinear, mHistoryMusicLinear,mDownloadLinear; private TextView mLocalMusicNum, mLoveMusicNum, mHistoryMusicNum; private TextView mSeekBtn; @@ -66,6 +69,7 @@ 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); + mDownloadLinear = view.findViewById(R.id.downloadLinear); return view; } @@ -123,18 +127,25 @@ public class MainFragment extends Fragment { } 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; diff --git a/app/src/main/java/com/example/musicplayer/view/main/CollectionFragment.java b/app/src/main/java/com/example/musicplayer/view/main/collection/CollectionFragment.java similarity index 97% rename from app/src/main/java/com/example/musicplayer/view/main/CollectionFragment.java rename to app/src/main/java/com/example/musicplayer/view/main/collection/CollectionFragment.java index f08eb03..71b0d4c 100644 --- a/app/src/main/java/com/example/musicplayer/view/main/CollectionFragment.java +++ b/app/src/main/java/com/example/musicplayer/view/main/collection/CollectionFragment.java @@ -1,4 +1,4 @@ -package com.example.musicplayer.view.main; +package com.example.musicplayer.view.main.collection; import android.content.ComponentName; @@ -62,7 +62,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); diff --git a/app/src/main/java/com/example/musicplayer/view/main/download/DownloadFragment.java b/app/src/main/java/com/example/musicplayer/view/main/download/DownloadFragment.java new file mode 100644 index 0000000..8abbe67 --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/view/main/download/DownloadFragment.java @@ -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; + +/** + *
+ *     author : 残渊
+ *     time   : 2019/09/16
+ *     desc   : 下载模块
+ * 
+ */ + +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 mTitleList; + private List 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(); + } +} diff --git a/app/src/main/java/com/example/musicplayer/view/main/download/DownloadMusicFragment.java b/app/src/main/java/com/example/musicplayer/view/main/download/DownloadMusicFragment.java new file mode 100644 index 0000000..c7561ed --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/view/main/download/DownloadMusicFragment.java @@ -0,0 +1,28 @@ +package com.example.musicplayer.view.main.download; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.example.musicplayer.R; + +/** + *
+ *     author : 残渊
+ *     time   : 2019/09/16
+ *     desc   : 下载歌曲列表
+ * 
+ */ + +public class DownloadMusicFragment extends Fragment { + @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); + return view; + } +} diff --git a/app/src/main/java/com/example/musicplayer/view/main/download/DownloadingFragment.java b/app/src/main/java/com/example/musicplayer/view/main/download/DownloadingFragment.java new file mode 100644 index 0000000..6762766 --- /dev/null +++ b/app/src/main/java/com/example/musicplayer/view/main/download/DownloadingFragment.java @@ -0,0 +1,87 @@ +package com.example.musicplayer.view.main.download; + +import android.os.Bundle; +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.DownloadingAdapter; +import com.example.musicplayer.entiy.DownloadInfo; +import com.example.musicplayer.event.DownloadEvent; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; +import org.greenrobot.eventbus.ThreadMode; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.Unbinder; + +/** + *
+ *     author : 残渊
+ *     time   : 2019/09/16
+ *     desc   : 正在下载歌曲列表
+ * 
+ */ + +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 mDownloadInfoList; + + @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(); + super.onActivityCreated(savedInstanceState); + } + + private void initRecycler(){ + mDownloadInfoList = new ArrayList<>(); + mLinearLayoutManager = new LinearLayoutManager(getActivity()); + mAdapter = new DownloadingAdapter(mDownloadInfoList); + songDowningRecycle.setLayoutManager(mLinearLayoutManager); + songDowningRecycle.setAdapter(mAdapter); + } + + @Subscribe(threadMode = ThreadMode.MAIN, sticky = true) + public void onDownloadingMessage(DownloadEvent event) { + mDownloadInfoList.clear(); + mDownloadInfoList.add(event.getDownloadInfo()); + mAdapter.notifyDataSetChanged(); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + EventBus.getDefault().unregister(this); + unbinder.unbind(); + } +} diff --git a/app/src/main/java/com/example/musicplayer/view/main/HistoryFragment.java b/app/src/main/java/com/example/musicplayer/view/main/history/HistoryFragment.java similarity index 97% rename from app/src/main/java/com/example/musicplayer/view/main/HistoryFragment.java rename to app/src/main/java/com/example/musicplayer/view/main/history/HistoryFragment.java index 73be7b6..53b08b7 100644 --- a/app/src/main/java/com/example/musicplayer/view/main/HistoryFragment.java +++ b/app/src/main/java/com/example/musicplayer/view/main/history/HistoryFragment.java @@ -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); diff --git a/app/src/main/java/com/example/musicplayer/view/main/LocalFragment.java b/app/src/main/java/com/example/musicplayer/view/main/local/LocalFragment.java similarity index 98% rename from app/src/main/java/com/example/musicplayer/view/main/LocalFragment.java rename to app/src/main/java/com/example/musicplayer/view/main/local/LocalFragment.java index a77b925..9ecba4e 100644 --- a/app/src/main/java/com/example/musicplayer/view/main/LocalFragment.java +++ b/app/src/main/java/com/example/musicplayer/view/main/local/LocalFragment.java @@ -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; @@ -115,7 +115,7 @@ public class LocalFragment extends BaseMvpFragment implements IL @Override protected int getLayoutId() { - return R.layout.fragment_local_music; + return R.layout.fragment_local; } diff --git a/app/src/main/java/com/example/musicplayer/view/search/ContentFragment.java b/app/src/main/java/com/example/musicplayer/view/search/ContentFragment.java index 285a8b8..89bb73f 100644 --- a/app/src/main/java/com/example/musicplayer/view/search/ContentFragment.java +++ b/app/src/main/java/com/example/musicplayer/view/search/ContentFragment.java @@ -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 mTitleList; private List 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); diff --git a/app/src/main/res/layout/fragment_download.xml b/app/src/main/res/layout/fragment_download.xml new file mode 100644 index 0000000..42aa180 --- /dev/null +++ b/app/src/main/res/layout/fragment_download.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_download_ing.xml b/app/src/main/res/layout/fragment_download_ing.xml new file mode 100644 index 0000000..46d5bb0 --- /dev/null +++ b/app/src/main/res/layout/fragment_download_ing.xml @@ -0,0 +1,23 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_download_music.xml b/app/src/main/res/layout/fragment_download_music.xml new file mode 100644 index 0000000..e80efc1 --- /dev/null +++ b/app/src/main/res/layout/fragment_download_music.xml @@ -0,0 +1,21 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_local_music.xml b/app/src/main/res/layout/fragment_local.xml similarity index 100% rename from app/src/main/res/layout/fragment_local_music.xml rename to app/src/main/res/layout/fragment_local.xml diff --git a/app/src/main/res/layout/fragment_love_music.xml b/app/src/main/res/layout/fragment_love.xml similarity index 100% rename from app/src/main/res/layout/fragment_love_music.xml rename to app/src/main/res/layout/fragment_love.xml diff --git a/app/src/main/res/layout/function.xml b/app/src/main/res/layout/function.xml index b3593a4..4e250b0 100644 --- a/app/src/main/res/layout/function.xml +++ b/app/src/main/res/layout/function.xml @@ -116,11 +116,13 @@ android:textColor="@drawable/selector_linear_click"/> + android:orientation="vertical" + android:focusable="true"> + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5f797b5..b75ea8e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -49,5 +49,6 @@ 顺序播放 随机播放 单曲循环 +  /  diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 978f837..da21481 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -43,6 +43,12 @@ @drawable/ic_seekbar_thumb + +