diff --git a/app/build.gradle b/app/build.gradle index bf54514..908a59d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -26,10 +26,17 @@ dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.2' + implementation 'androidx.work:work-runtime:2.4.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' - implementation 'jp.wasabeef:glide-transformations:4.x.x' + implementation 'jp.wasabeef:glide-transformations:4.3.0' + implementation 'org.projectlombok:lombok:1.18.12' + implementation 'com.alibaba:fastjson:1.1.72.android' + //noinspection GradleCompatible + implementation 'com.android.support:support-media-compat:28.0.0' + + } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 603a4d2..78504a1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ + @@ -18,6 +20,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/yutou/nas_music_player/Interfaces/DownloadInterface.java b/app/src/main/java/com/yutou/nas_music_player/Interfaces/DownloadInterface.java new file mode 100644 index 0000000..f230835 --- /dev/null +++ b/app/src/main/java/com/yutou/nas_music_player/Interfaces/DownloadInterface.java @@ -0,0 +1,14 @@ +package com.yutou.nas_music_player.Interfaces; + +import java.io.File; + +/** + * 下载接口 + */ +public interface DownloadInterface { + /** + * 下载完成 + * @param oldJar + */ + void DownloadOver(File oldJar); +} diff --git a/app/src/main/java/com/yutou/nas_music_player/Interfaces/NetworkInterface.java b/app/src/main/java/com/yutou/nas_music_player/Interfaces/NetworkInterface.java new file mode 100644 index 0000000..851b423 --- /dev/null +++ b/app/src/main/java/com/yutou/nas_music_player/Interfaces/NetworkInterface.java @@ -0,0 +1,16 @@ +package com.yutou.nas_music_player.Interfaces; + +public interface NetworkInterface { + /** + * 请求成功 + * @param data 请求参数 + * @param state http状态 + */ + void httpGetData(Object data, int state); + + /** + * 请求异常 + * @param e 异常 + */ + void httpError(Exception e); +} diff --git a/app/src/main/java/com/yutou/nas_music_player/MyApplication.java b/app/src/main/java/com/yutou/nas_music_player/MyApplication.java index 71a4823..5dfc187 100644 --- a/app/src/main/java/com/yutou/nas_music_player/MyApplication.java +++ b/app/src/main/java/com/yutou/nas_music_player/MyApplication.java @@ -1,11 +1,14 @@ package com.yutou.nas_music_player; import android.app.Application; +import android.content.Context; + +public class MyApplication extends Application { + public static Application application; -public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); - + MyApplication.application = this; } } diff --git a/app/src/main/java/com/yutou/nas_music_player/containers/MusicContainer.java b/app/src/main/java/com/yutou/nas_music_player/containers/MusicContainer.java new file mode 100644 index 0000000..d908553 --- /dev/null +++ b/app/src/main/java/com/yutou/nas_music_player/containers/MusicContainer.java @@ -0,0 +1,59 @@ +package com.yutou.nas_music_player.containers; + +import android.media.MediaPlayer; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.yutou.nas_music_player.Interfaces.NetworkInterface; +import com.yutou.nas_music_player.tools.NetworkTool; + +import java.util.List; + + +public class MusicContainer { + private static MusicContainer container; + private MusicLibs musicLibs; + private MediaPlayer mediaPlayer; + + private MusicContainer() { + mediaPlayer=new MediaPlayer(); + musicLibs=new MusicLibs(); + } + + public static MusicContainer getInstance() { + if (container == null) { + container = new MusicContainer(); + } + return container; + } + public static MusicLibs getLibs(){ + return getInstance().musicLibs; + } + public static class MusicLibs{ + private MusicLibs(){ + initData(); + } + + private void initData() { + NetworkTool.init().httpGet(NetworkTool.NetworkAPI.MUSIC_LIST, new JSONObject(), new NetworkInterface() { + @Override + public void httpGetData(Object data, int state) { + JSONObject json=JSONObject.parseObject(data.toString()); + if(json.getInteger("code")==0){ + List list= JSONArray.parseArray(json.getJSONArray("data").toJSONString(),MusicData.class); + System.out.println(list.size()); + for (MusicData musicData : list) { + System.out.println(musicData.getTitle()); + } + } + } + + @Override + public void httpError(Exception e) { + + } + }); + } + + } +} diff --git a/app/src/main/java/com/yutou/nas_music_player/containers/MusicData.java b/app/src/main/java/com/yutou/nas_music_player/containers/MusicData.java new file mode 100644 index 0000000..480a998 --- /dev/null +++ b/app/src/main/java/com/yutou/nas_music_player/containers/MusicData.java @@ -0,0 +1,114 @@ +package com.yutou.nas_music_player.containers; + + + + + +import java.io.*; + + +public class MusicData { + private String artist;//艺术家 + private String album;//专辑 + private String title;//标题 + private String comment;//评论 + private String year;//年份 + private String track;//音轨号 + private String disc_no;//碟片编号 + private String composer;//作曲 + private String artist_sort;//分类 + private String lastDir;//上一个文件夹 + private boolean isDir = false; + + public MusicData() { + } + + public String getArtist() { + return artist; + } + + public void setArtist(String artist) { + this.artist = artist; + } + + public String getAlbum() { + return album; + } + + public void setAlbum(String album) { + this.album = album; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String getYear() { + return year; + } + + public void setYear(String year) { + this.year = year; + } + + public String getTrack() { + return track; + } + + public void setTrack(String track) { + this.track = track; + } + + public String getDisc_no() { + return disc_no; + } + + public void setDisc_no(String disc_no) { + this.disc_no = disc_no; + } + + public String getComposer() { + return composer; + } + + public void setComposer(String composer) { + this.composer = composer; + } + + public String getArtist_sort() { + return artist_sort; + } + + public void setArtist_sort(String artist_sort) { + this.artist_sort = artist_sort; + } + + + public String getLastDir() { + return lastDir; + } + + public void setLastDir(String lastDir) { + this.lastDir = lastDir; + } + + public boolean isDir() { + return isDir; + } + + public void setDir(boolean dir) { + isDir = dir; + } +} diff --git a/app/src/main/java/com/yutou/nas_music_player/services/MusicService.java b/app/src/main/java/com/yutou/nas_music_player/services/MusicService.java new file mode 100644 index 0000000..ee46127 --- /dev/null +++ b/app/src/main/java/com/yutou/nas_music_player/services/MusicService.java @@ -0,0 +1,27 @@ +package com.yutou.nas_music_player.services; + +import android.app.Service; +import android.content.Intent; +import android.os.Bundle; +import android.os.IBinder; +import android.support.v4.media.MediaBrowserCompat; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.media.MediaBrowserServiceCompat; + +import java.util.List; + +public class MusicService extends MediaBrowserServiceCompat { + + @Nullable + @Override + public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, @Nullable Bundle rootHints) { + return new BrowserRoot("media_root_id",null); + } + + @Override + public void onLoadChildren(@NonNull String parentId, @NonNull Result> result) { + + } +} diff --git a/app/src/main/java/com/yutou/nas_music_player/tools/AppData.java b/app/src/main/java/com/yutou/nas_music_player/tools/AppData.java new file mode 100644 index 0000000..ef9444c --- /dev/null +++ b/app/src/main/java/com/yutou/nas_music_player/tools/AppData.java @@ -0,0 +1,11 @@ +package com.yutou.nas_music_player.tools; + +import android.os.Handler; +import android.os.Looper; + +public class AppData { + + public static String download_dir="downloads"; + public static boolean isDebug=true; + public static Handler handler=new Handler(Looper.getMainLooper()); +} diff --git a/app/src/main/java/com/yutou/nas_music_player/tools/Log.java b/app/src/main/java/com/yutou/nas_music_player/tools/Log.java new file mode 100644 index 0000000..08c921a --- /dev/null +++ b/app/src/main/java/com/yutou/nas_music_player/tools/Log.java @@ -0,0 +1,83 @@ +package com.yutou.nas_music_player.tools; + +import android.content.Context; +import android.os.Build; + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * 日志工具 + */ +public class Log { + public static boolean isDebug = AppData.isDebug; + private static boolean LogPrint = false; + + public static String getErrorLog(Exception e) { + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + e.printStackTrace(printWriter); + File path = new File(NetworkTool.donwloadPath); + StringBuilder files = new StringBuilder(); + if (path.exists()) { + for (File file : path.listFiles()) { + files.append(file.getName()).append("\n"); + } + } + String str = "phoneType = " + Build.MODEL + "\n" + + "SDK_Version = " + Build.VERSION.SDK_INT + "\n" + + "files = " + files + + "Error = \n"; + return str + writer.toString(); + } + + private static void printOrInfo(String string) { + if (LogPrint || isDebug) { + System.out.println("[KUKUSDK_L]" + string); + } + // LogW.i(string); + } + + private static void printOrError(String string) { + if (LogPrint || isDebug) { + System.err.println("[KUKUSDK_E]" + string); + } + // LogW.i(string); + + } + + public static void i(Object title, String text) { + if (title instanceof String) { + printOrInfo("[" + title + "]" + text); + } else { + printOrInfo("[" + title.getClass().getName() + "]" + text); + } + } + + public static void e(Object title, String text) { + if (title instanceof String) { + printOrError("[" + title + "]" + text); + } else { + printOrError("[" + title.getClass().getName() + "]" + text); + } + } + + public static void e(Object title, Exception e) { + // e.printStackTrace(); + StringWriter writer = new StringWriter(); + PrintWriter printWriter = new PrintWriter(writer); + e.printStackTrace(printWriter); + printOrError("[" + title + "]" + writer.toString()); + } + + public static void toast(final Context context, final String string) { + AppData.handler.post(new Runnable() { + @Override + public void run() { + // Toast.makeText(Utils.getTopActivity(), string, Toast.LENGTH_SHORT).show(); + i("Toast", string); + } + }); + } +} diff --git a/app/src/main/java/com/yutou/nas_music_player/tools/NetworkTool.java b/app/src/main/java/com/yutou/nas_music_player/tools/NetworkTool.java new file mode 100644 index 0000000..7b6a38b --- /dev/null +++ b/app/src/main/java/com/yutou/nas_music_player/tools/NetworkTool.java @@ -0,0 +1,287 @@ +package com.yutou.nas_music_player.tools; + + +import com.alibaba.fastjson.JSONException; +import com.alibaba.fastjson.JSONObject; +import com.yutou.nas_music_player.Interfaces.DownloadInterface; +import com.yutou.nas_music_player.Interfaces.NetworkInterface; +import com.yutou.nas_music_player.MyApplication; + + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.ConnectException; +import java.net.HttpURLConnection; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import static com.yutou.nas_music_player.tools.NetworkTool.NetworkAPI.HOME; + + +public class NetworkTool { + + public static class NetworkAPI { + private static final String HTTP_KEY = "PlVodzYhvxRQbOHKakpKs2dvnoc43Cnk"; + public static String HOME = ""; + public static String MUSIC_LIST = HOME + "/music/list.do"; + public static String MUSIC_METADATA = HOME + "/find/file.do"; + public static String MUSIC_IMAGE = HOME + "/image.do"; + public static String MUSIC_PLAY = HOME + "/play.do"; + + + } + + private static final String TAG = NetworkTool.class.getName(); + private static NetworkTool network; + public boolean isNet = true; + public static String donwloadPath = MyApplication.application.getFilesDir() + File.separator + AppData.download_dir + File.separator; + + private NetworkTool() { + if (StringUtil.isEmpty(HOME)) { + httpGet("http://tools.yutou233.cn/nas/music/getlocalhost.do" , new JSONObject(), new NetworkInterface() { + @Override + public void httpGetData(Object data, int state) { + try { + JSONObject json = JSONObject.parseObject(data.toString()); + if (json.getInteger("code") == 0) { + HOME = json.getString("data") + ":8000/nas"; + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + @Override + public void httpError(Exception e) { + + } + }); + } + } + + public static NetworkTool init() { + if (network == null) { + network = new NetworkTool(); + } + return network; + } + + public void httpGet(final String url, final JSONObject body, final NetworkInterface networkInterface) { + if(!url.startsWith("http:")&&!StringUtil.isEmpty(HOME)){ + httpGet(HOME+url,body,networkInterface); + return; + } + if(StringUtil.isEmpty(HOME)&&!url.contains("getlocalhost.do")){ + AppData.handler.postDelayed(new Runnable() { + @Override + public void run() { + NetworkTool.init().httpGet(url, body, networkInterface); + } + },300); + return; + } + new Thread(new Runnable() { + @Override + public void run() { + try { + System.out.println(url + "?" + toGetSplice(body)); + HttpURLConnection connection = (HttpURLConnection) new URL(url + "?" + toGetSplice(body)).openConnection(); + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + connection.connect(); + String tmp; + StringBuilder str = new StringBuilder(); + while ((tmp = reader.readLine()) != null) { + str.append(tmp); + } + reader.close(); + if (networkInterface != null) + networkInterface.httpGetData(str.toString(), connection.getResponseCode()); + //Log.i(TAG + "[" + url + "]", "body:" + str + " (" + connection.getResponseCode() + ")"); + } catch (Exception e) { + e.printStackTrace(); + if (networkInterface != null) + networkInterface.httpError(e); + Log.e(TAG, url + "\n" + e); + } + } + }).start(); + + } + + private Map map = Collections.synchronizedMap(new HashMap()); + + public void httpPost(final String url, final JSONObject body, final NetworkInterface networkInterface) { + new Thread(new Runnable() { + + @Override + public void run() { + String tmp; + StringBuilder str = new StringBuilder(); + try { + HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); + connection.setRequestMethod("POST"); + connection.setDoOutput(true); + connection.setDoInput(true); + connection.setConnectTimeout(5 * 1000); + connection.setReadTimeout(10 * 1000); + connection.addRequestProperty("Connection", "keep-alive"); + connection.addRequestProperty("User-Agent", getExtUa()); + OutputStream outputStream = connection.getOutputStream(); + + String bytes = body.toString(); + outputStream.write(bytes.getBytes()); + outputStream.flush(); + outputStream.close(); + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + while ((tmp = reader.readLine()) != null) { + str.append(tmp); + } + Log.i(TAG, "[域名]" + url + " = [body]" + body.toString() + " -> [接收] " + str); + final String finalStr = str.toString(); + + // Log.i(TAG + "[" + url + "?" + toGetSplice(body) + "]", "body:" + str + " (" + connection.getResponseCode() + ")"); + if (map.containsKey(body)) { + map.remove(body); + } + if (networkInterface != null) + networkInterface.httpGetData(str.toString(), connection.getResponseCode()); + connection.disconnect(); + } catch (SocketTimeoutException e) { + Log.e(TAG, url + "\n传参:" + body.toString() + "\n密文:" + str + "\n" + e); + + synchronized (NetworkTool.this) { + + if (!map.containsKey(body)) { + map.put(body, 0); + } + if (map.get(body) != null && map.get(body) == 0) { + map.put(body, 1); + httpPost(url, body, networkInterface); + return; + } + if (networkInterface != null) + networkInterface.httpError(e); + } + + } catch (ConnectException e) { + e.printStackTrace(); + } catch (IOException e) { + if (networkInterface != null) + networkInterface.httpError(e); + } catch (Exception e) { + e.printStackTrace(); + networkInterface.httpError(e); + } + } + }).start(); + + } + + private String getExtUa() { + return "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36"; + } + + public String toGetSplice(JSONObject json) { + try { + json.put("token",NetworkAPI.HTTP_KEY); + } catch (JSONException e) { + e.printStackTrace(); + } + StringBuilder string = new StringBuilder(); + Set keys = json.keySet(); + for (String key : keys) { + try { + string.append("&").append(key).append("=").append(json.getString(key)); + } catch (JSONException e) { + e.printStackTrace(); + try { + string.append("&").append(URLEncoder.encode(key, "UTF-8")).append("="); + // string += "&" + key + "="; + } catch (Exception e1) { + string.append("&").append(key).append("="); + } + } + } + + string = new StringBuilder(string.substring(1, string.length()).replaceAll(" ", "")); + return string.toString(); + } + + public synchronized static void download(final String url, final String saveName) { + download(url, saveName, null); + } + + private static int reindex = 0; + + static Set downloadCache = Collections.synchronizedSet(new HashSet()); + + public synchronized static void download(final String url, final String saveName, final DownloadInterface downloadInterface) { + if (downloadCache.contains(url)) return; + downloadCache.add(url); + new Thread(new Runnable() { + @Override + public void run() { + File jar = null; + try { + File savePath = new File(NetworkTool.donwloadPath); + if (!savePath.exists()) { + savePath.mkdirs(); + } + Log.i(TAG, "下载文件:" + url + " 保存文件:" + saveName); + HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); + + // Log.i(TAG,"获取到网络请求:"+connection.getResponseCode()); + + + InputStream inputStream = connection.getInputStream(); + jar = new File(donwloadPath + saveName + "_tmp.tmp"); + jar.createNewFile(); + Log.i(NetworkTool.class, "临时保存文件:" + jar.getAbsolutePath()); + OutputStream outputStream = new FileOutputStream(jar); + byte[] bytes = new byte[1024]; + int len; + while ((len = inputStream.read(bytes)) > 0) { + outputStream.write(bytes, 0, len); + } + outputStream.close(); + inputStream.close(); + File oldJar = new File(donwloadPath + saveName); + if (oldJar.exists()) { + oldJar.delete(); + } + jar.renameTo(oldJar); + Log.i(NetworkTool.class, "实际保存:" + oldJar.getAbsolutePath() + " " + oldJar.getName()); + Log.toast(MyApplication.application, "下载完成,重启生效"); + + if (downloadInterface != null) { + downloadInterface.DownloadOver(oldJar); + } + + } catch (Exception e) { + e.printStackTrace(); + if (jar != null) { + jar.delete(); + } + if (reindex < 3) { + reindex++; + download(url, saveName, downloadInterface); + } + } finally { + downloadCache.remove(url); + } + } + }).start(); + } +} diff --git a/app/src/main/java/com/yutou/nas_music_player/tools/StringUtil.java b/app/src/main/java/com/yutou/nas_music_player/tools/StringUtil.java new file mode 100644 index 0000000..9757a38 --- /dev/null +++ b/app/src/main/java/com/yutou/nas_music_player/tools/StringUtil.java @@ -0,0 +1,7 @@ +package com.yutou.nas_music_player.tools; + +public class StringUtil { + public static boolean isEmpty(String string){ + return string == null || string.trim().length() == 0; + } +} diff --git a/app/src/main/java/com/yutou/nas_music_player/views/MainActivity.java b/app/src/main/java/com/yutou/nas_music_player/views/MainActivity.java index b6583d8..91385fa 100644 --- a/app/src/main/java/com/yutou/nas_music_player/views/MainActivity.java +++ b/app/src/main/java/com/yutou/nas_music_player/views/MainActivity.java @@ -5,6 +5,7 @@ import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import com.yutou.nas_music_player.R; +import com.yutou.nas_music_player.containers.MusicContainer; public class MainActivity extends AppCompatActivity { @@ -12,5 +13,6 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + MusicContainer.getInstance(); } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index d6ec7e9..2f6a2fb 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -7,6 +7,7 @@ tools:context=".views.MainActivity"> + + + + + + + + + + \ No newline at end of file