This commit is contained in:
yutou 2020-12-02 18:34:06 +08:00
parent b65001f42a
commit a27ef26800
12 changed files with 417 additions and 64 deletions

View File

@ -45,6 +45,7 @@ android {
} }
dependencies { dependencies {
implementation 'com.google.android.material:material:1.2.1'
def room_version = "2.2.5" def room_version = "2.2.5"
implementation fileTree(dir: "libs", include: ["*.jar"]) implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
@ -65,7 +66,7 @@ dependencies {
implementation 'androidx.palette:palette:1.0.0' implementation 'androidx.palette:palette:1.0.0'
implementation 'com.github.zrunker:ZTextView:v1.0.2' implementation 'com.github.zrunker:ZTextView:v1.0.2'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.5' //debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.5'
implementation 'com.kaopiz:kprogresshud:1.2.0' implementation 'com.kaopiz:kprogresshud:1.2.0'
implementation 'com.ogaclejapan.smarttablayout:library:2.0.0@aar' implementation 'com.ogaclejapan.smarttablayout:library:2.0.0@aar'
implementation 'com.ogaclejapan.smarttablayout:utils-v4:2.0.0@aar' implementation 'com.ogaclejapan.smarttablayout:utils-v4:2.0.0@aar'

View File

@ -30,6 +30,10 @@
android:name=".views.PlayLibsActivity" android:name=".views.PlayLibsActivity"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" /> android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" />
<activity
android:name=".views.AlbumsActivity"
android:fitsSystemWindows="true"
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" />
<service <service
android:name=".services.MusicService" android:name=".services.MusicService"

View File

@ -0,0 +1,118 @@
package com.yutou.nas_music_player.Adapters;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView;
import com.alibaba.fastjson.JSONObject;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.kaopiz.kprogresshud.KProgressHUD;
import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.Interfaces.NetworkInterface;
import com.yutou.nas_music_player.R;
import com.yutou.nas_music_player.containers.MusicContainer;
import com.yutou.nas_music_player.tools.AppTools;
import java.util.List;
import cc.ibooker.ztextviewlib.MarqueeTextView;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
public class AlbumsRecyclerAdapter extends RecyclerView.Adapter<AlbumsRecyclerAdapter.AlbumHolder> {
List<MusicData> list;
Context context;
public AlbumsRecyclerAdapter(Context context, List<MusicData> list) {
this.list = list;
this.context = context;
}
@NonNull
@Override
public AlbumHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new AlbumHolder(LayoutInflater.from(context).inflate(R.layout.layout_music_libs_item, parent, false));
}
@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull AlbumHolder holder, int position) {
MusicData data = list.get(position);
holder.title.setText(data.getTitle());
holder.artist.setText(data.getArtist());
holder.icon.setImageResource(R.drawable.ic_dir);
if (!data.isDir()) {
holder.message.setText(data.getBitRate() + "kbps | " + data.getSampleRate() + "hz | " + data.getEncodingType());
holder.message.setVisibility(View.VISIBLE);
holder.artist.setVisibility(View.VISIBLE);
// holder.icon.setImageBitmap(ThumbnailUtils.extractThumbnail(data.getImg(), 64,64));
Glide.with(context).load(data.getImg(-1, -1))
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(holder.icon);
holder.icon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
System.out.println(data.getFile());
System.out.println(data.getImageUrl());
System.out.println(data.getImg(-1, -1));
if (data.getImg(-1, -1) != null) {
Glide.with(context).load(data.getImg(-1, -1))
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(holder.icon);
}
}
});
} else {
holder.message.setText("");
holder.play_mask.setVisibility(View.GONE);
holder.icon.setImageResource(R.drawable.ic_dir);
}
holder.top.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MusicContainer.getInstance().addTmpList(data);
Toast.makeText(context, "已添加到队列中", Toast.LENGTH_LONG).show();
for (MusicData musicData : MusicContainer.getInstance().getTmpPlayList()) {
System.out.println("临时队列:" + musicData.getTitle());
}
}
});
}
@Override
public int getItemCount() {
return list.size();
}
public static class AlbumHolder extends RecyclerView.ViewHolder {
MarqueeTextView title, artist, message;
LinearLayout buttons;
ImageButton collection, top, dislike;
ImageView icon, play_mask;
public AlbumHolder(@NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.title);
artist = itemView.findViewById(R.id.artist);
message = itemView.findViewById(R.id.message);
buttons = itemView.findViewById(R.id.buttons);
collection = itemView.findViewById(R.id.collection);
top = itemView.findViewById(R.id.top);
dislike = itemView.findViewById(R.id.dislike);
icon = itemView.findViewById(R.id.album_image);
play_mask = itemView.findViewById(R.id.play_mask);
}
}
}

View File

@ -75,25 +75,29 @@ public class MusicLibsAdapter extends ArrayAdapter<MusicData> {
Map<String, List<MusicData>> map; Map<String, List<MusicData>> map;
switch (model) { switch (model) {
case LIBS_MODEL_Album: case LIBS_MODEL_Album:
map = MusicContainer.getInstance().getAllAlbumMapList(); new Thread(new Runnable() {
for (String title : map.keySet()) { @Override
MusicData data = new MusicData(); public void run() {
data.setTitle(title); String album=null;
data.setAlbum(map.get(title).get(0).getAlbum()); MusicContainer.getLibs().onAlbumMusicData(album, new NetworkInterface() {
data.setFile(map.get(title).get(0).getFile()); @Override
data.setArtist(""); public void httpGetData(Object data, int state) {
list.add(data); list.clear();
if (data != null && state == 0)
list.addAll((List<MusicData>) data);
notifyDataSetChanged();
} }
@Override
public void httpError(Exception e) {
}
});
}
}).start();
break; break;
case LIBS_MODEL_Artist: case LIBS_MODEL_Artist:
map = MusicContainer.getInstance().getAllArtistMapList();
for (String title : map.keySet()) {
MusicData data = new MusicData();
data.setTitle(title);
data.setFile(map.get(title).get(0).getFile());
data.setArtist(map.get(title).get(0).getArtist());
list.add(data);
}
break; break;
case LIBS_MODEL_Tmp: case LIBS_MODEL_Tmp:
list.addAll(MusicContainer.getInstance().getTmpPlayList()); list.addAll(MusicContainer.getInstance().getTmpPlayList());
@ -122,7 +126,13 @@ public class MusicLibsAdapter extends ArrayAdapter<MusicData> {
list.clear(); list.clear();
if (data != null && state == 0) if (data != null && state == 0)
list.addAll((List<MusicData>) data); list.addAll((List<MusicData>) data);
AppData.handler.post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged(); notifyDataSetChanged();
}
});
} }
@Override @Override
@ -320,7 +330,13 @@ public class MusicLibsAdapter extends ArrayAdapter<MusicData> {
this.musicPath = path; this.musicPath = path;
} }
static class ViewHolder extends RecyclerView.ViewHolder { public int getModel() {
return model;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
MarqueeTextView title, artist, message; MarqueeTextView title, artist, message;
LinearLayout buttons; LinearLayout buttons;
ImageButton collection, top, dislike; ImageButton collection, top, dislike;

View File

@ -53,6 +53,8 @@ public class MusicData {
private boolean isDir = false; private boolean isDir = false;
@Ignore @Ignore
private Bitmap img; private Bitmap img;
@Ignore
private boolean isDownloadImg = false;
@ColumnInfo @ColumnInfo
private int bitRate;//比特率 private int bitRate;//比特率
@ -108,6 +110,14 @@ public class MusicData {
this.comment = comment; this.comment = comment;
} }
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getYear() { public String getYear() {
if (StringUtil.isEmpty(year)) { if (StringUtil.isEmpty(year)) {
year = "8888"; year = "8888";
@ -183,6 +193,8 @@ public class MusicData {
} }
public String getFileBase64() { public String getFileBase64() {
if (StringUtil.isEmpty(file))
return null;
return new String(Base64.encode(file.getBytes(), Base64.DEFAULT)).replace("\n", ""); return new String(Base64.encode(file.getBytes(), Base64.DEFAULT)).replace("\n", "");
} }
@ -191,7 +203,6 @@ public class MusicData {
+ "?random=false&token=" + NetworkTool.NetworkAPI.HTTP_KEY + "&filePath=" + getFileBase64(); + "?random=false&token=" + NetworkTool.NetworkAPI.HTTP_KEY + "&filePath=" + getFileBase64();
} }
private boolean isDownloadImg = false;
public String getImageUrl() { public String getImageUrl() {
return NetworkTool.NetworkAPI.MUSIC_IMAGE + "?fileName=" + getFileBase64(); return NetworkTool.NetworkAPI.MUSIC_IMAGE + "?fileName=" + getFileBase64();
@ -219,6 +230,10 @@ public class MusicData {
if (isDownloadImg) { if (isDownloadImg) {
return null; return null;
} }
if (StringUtil.isEmpty(file)) {
img = BitmapFactory.decodeResource(MyApplication.application.getResources(), R.mipmap.ic_launcher);
return img;
}
img = AppTools.getSaveBitmap(getFileBase64()); img = AppTools.getSaveBitmap(getFileBase64());
if (img != null) { if (img != null) {
if (width == -1 && height == -1) { if (width == -1 && height == -1) {

View File

@ -462,7 +462,10 @@ public class MusicContainer {
} }
private void initData() { private void initData() {
NetworkTool.init().httpGet(NetworkTool.NetworkAPI.MUSIC_ALL, new JSONObject(), new NetworkInterface() { if (initInterface != null)
initInterface.init();
initInterface = null;
/*NetworkTool.init().httpGet(NetworkTool.NetworkAPI.MUSIC_ALL, new JSONObject(), new NetworkInterface() {
@Override @Override
public void httpGetData(Object data, int state) { public void httpGetData(Object data, int state) {
JSONObject json = JSONObject.parseObject(data.toString()); JSONObject json = JSONObject.parseObject(data.toString());
@ -486,6 +489,42 @@ public class MusicContainer {
@Override @Override
public void httpError(Exception e) { public void httpError(Exception e) {
}
});*/
}
public void onAlbumMusicData(String album, NetworkInterface networkInterface) {
JSONObject json = new JSONObject();
if (StringUtil.isEmpty(album)) {
json.put("album", "");
} else {
json.put("album", album);
}
NetworkTool.init().httpGet(NetworkTool.NetworkAPI.MUSIC_Album, json, new NetworkInterface() {
@Override
public void httpGetData(Object data, int state) {
JSONObject json = JSONObject.parseObject((String) data);
if (json.getInteger("code") == 0) {
try {
networkInterface.httpGetData(JSONArray.parseArray(json.getJSONArray("data").toJSONString(), MusicData.class), 0);
} catch (Exception e) {
List<MusicData> list=new ArrayList<>();
for (Object album : json.getJSONArray("data")) {
MusicData musicData=new MusicData();
musicData.setTitle((String) album);
musicData.setAlbum((String) album);
list.add(musicData);
}
networkInterface.httpGetData(list,0);
}
} else {
networkInterface.httpGetData(new ArrayList<>(), 0);
}
}
@Override
public void httpError(Exception e) {
} }
}); });
} }
@ -495,18 +534,12 @@ public class MusicContainer {
@Override @Override
public void httpGetData(Object data, int state) { public void httpGetData(Object data, int state) {
JSONObject json = JSONObject.parseObject((String) data); JSONObject json = JSONObject.parseObject((String) data);
AppData.handler.post(new Runnable() {
@Override
public void run() {
if (json.getInteger("code") == 0) { if (json.getInteger("code") == 0) {
networkInterface.httpGetData(JSONArray.parseArray(json.getString("data"), MusicData.class), 0); networkInterface.httpGetData(JSONArray.parseArray(json.getString("data"), MusicData.class), 0);
} else { } else {
networkInterface.httpGetData(new ArrayList<>(), 0); networkInterface.httpGetData(new ArrayList<>(), 0);
} }
} }
});
}
@Override @Override
public void httpError(Exception e) { public void httpError(Exception e) {

View File

@ -36,6 +36,7 @@ public class NetworkTool {
public static final String HTTP_KEY = "PlVodzYhvxRQbOHKakpKs2dvnoc43Cnk"; public static final String HTTP_KEY = "PlVodzYhvxRQbOHKakpKs2dvnoc43Cnk";
public static String HOME = ""; public static String HOME = "";
public static String MUSIC_LIST = HOME + "/music/list.do"; public static String MUSIC_LIST = HOME + "/music/list.do";
public static String MUSIC_Album = HOME + "/music/getAlbum.do";
public static String MUSIC_ALL = HOME + "/music/all.do"; public static String MUSIC_ALL = HOME + "/music/all.do";
public static String MUSIC_METADATA = HOME + "/music/find/file.do"; public static String MUSIC_METADATA = HOME + "/music/find/file.do";
public static String MUSIC_IMAGE = HOME + "/music/image.do"; public static String MUSIC_IMAGE = HOME + "/music/image.do";
@ -51,6 +52,7 @@ public class NetworkTool {
public static String donwloadPath = AppData.dir + AppData.download_dir + File.separator; public static String donwloadPath = AppData.dir + AppData.download_dir + File.separator;
private NetworkTool() { private NetworkTool() {
HOME = "http://192.168.137.1:8000/nas";
if (StringUtil.isEmpty(HOME)) { if (StringUtil.isEmpty(HOME)) {
httpGet("http://tools.yutou233.cn/nas/music/getlocalhost.do", new JSONObject(), new NetworkInterface() { httpGet("http://tools.yutou233.cn/nas/music/getlocalhost.do", new JSONObject(), new NetworkInterface() {
@Override @Override
@ -112,13 +114,29 @@ public class NetworkTool {
str.append(tmp); str.append(tmp);
} }
reader.close(); reader.close();
if (networkInterface != null) AppData.handler.post(new Runnable() {
@Override
public void run() {
if (networkInterface != null) {
try {
networkInterface.httpGetData(str.toString(), connection.getResponseCode()); networkInterface.httpGetData(str.toString(), connection.getResponseCode());
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
//Log.i(TAG + "[" + url + "]", "body:" + str + " (" + connection.getResponseCode() + ")"); //Log.i(TAG + "[" + url + "]", "body:" + str + " (" + connection.getResponseCode() + ")");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
AppData.handler.post(new Runnable() {
@Override
public void run() {
if (networkInterface != null) if (networkInterface != null)
networkInterface.httpError(e); networkInterface.httpError(e);
}
});
Log.e(TAG, url + " body =" + body.toJSONString()); Log.e(TAG, url + " body =" + body.toJSONString());
} }
} }

View File

@ -9,7 +9,7 @@ import androidx.sqlite.db.SupportSQLiteOpenHelper;
import com.yutou.nas_music_player.Datas.MusicData; import com.yutou.nas_music_player.Datas.MusicData;
@Database(entities = {MusicData.class},version = 1) //@Database(entities = {MusicData.class},version = 1)
public abstract class SQLiteManager extends RoomDatabase { public abstract class SQLiteManager extends RoomDatabase {
@NonNull @NonNull

View File

@ -0,0 +1,70 @@
package com.yutou.nas_music_player.views;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.yutou.nas_music_player.Adapters.AlbumsRecyclerAdapter;
import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.Interfaces.NetworkInterface;
import com.yutou.nas_music_player.R;
import com.yutou.nas_music_player.containers.MusicContainer;
import java.util.ArrayList;
import java.util.List;
public class AlbumsActivity extends AppCompatActivity {
private ImageView album_image;
private RecyclerView listView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_album);
String album=getIntent().getStringExtra("album");
initView();
initData(album);
}
private void initData(String album) {
MusicContainer.getLibs().onAlbumMusicData(album, new NetworkInterface() {
@Override
public void httpGetData(Object data, int state) {
List<MusicData> list= (List<MusicData>) data;
listView.setAdapter(new AlbumsRecyclerAdapter(AlbumsActivity.this,list));
list.get(0).getImg(-1, -1, new NetworkInterface() {
@Override
public void httpGetData(Object data, int state) {
album_image.setImageBitmap((Bitmap) data);
}
@Override
public void httpError(Exception e) {
}
});
}
@Override
public void httpError(Exception e) {
}
});
}
private void initView() {
album_image=findViewById(R.id.album_image);
listView=findViewById(R.id.album_list);
listView.setLayoutManager(new LinearLayoutManager(this));
}
}

View File

@ -1,6 +1,7 @@
package com.yutou.nas_music_player.views.Fragments; package com.yutou.nas_music_player.views.Fragments;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -17,9 +18,13 @@ import com.yutou.nas_music_player.Interfaces.NetworkInterface;
import com.yutou.nas_music_player.R; import com.yutou.nas_music_player.R;
import com.yutou.nas_music_player.containers.MediaBrowserHelper; import com.yutou.nas_music_player.containers.MediaBrowserHelper;
import com.yutou.nas_music_player.containers.MusicContainer; import com.yutou.nas_music_player.containers.MusicContainer;
import com.yutou.nas_music_player.views.AlbumsActivity;
import com.yutou.nas_music_player.views.MainActivity;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.util.Pair;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
@ -107,6 +112,28 @@ public class MusicLibsFragment extends Fragment {
recyclerView.setOnItemClickListener(new AdapterView.OnItemClickListener() { recyclerView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (adapter.getModel()){
case MusicLibsAdapter.LIBS_MODEL_ALL:
clickAllList(position);
break;
case MusicLibsAdapter.LIBS_MODEL_Album:
clickAlbum(position,view);
break;
}
}
private void clickAlbum(int position,View view){
MusicLibsAdapter.ViewHolder holder= (MusicLibsAdapter.ViewHolder) view.getTag();
Pair<View, String> pImage = Pair.create(holder.itemView, "album_image");
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(),pImage).toBundle();
MusicData data=adapter.getItem(position);
if(data==null)
return;
Intent intent=new Intent(getContext(), AlbumsActivity.class);
intent.putExtra("album",data.getAlbum());
startActivity(intent,bundle);
}
private void clickAllList(int position){
MusicData musicData = adapter.getItem(position); MusicData musicData = adapter.getItem(position);
if (musicData != null) { if (musicData != null) {
if (musicData.isDir()) { if (musicData.isDir()) {
@ -118,7 +145,6 @@ public class MusicLibsFragment extends Fragment {
} }
} }
} }
} }
}); });
adapter.setScrollStatus(1); adapter.setScrollStatus(1);

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="192dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="@+id/toolbar">
<ImageView
android:id="@+id/album_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:transitionName="album_image"
app:srcCompat="@drawable/ic_launcher_background" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin">
<TextView
android:id="@+id/breakApp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="返回"
android:textColor="@color/musicArtist" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/album_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -3,7 +3,6 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="15dp"
android:descendantFocusability="blocksDescendants" android:descendantFocusability="blocksDescendants"
android:orientation="vertical"> android:orientation="vertical">