This commit is contained in:
Yutousama 2022-10-23 10:34:58 +08:00
parent 578f756635
commit 9f5601da6b
24 changed files with 727 additions and 242 deletions

View File

@ -19,7 +19,7 @@ android {
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 32 targetSdkVersion 32
versionCode 1 versionCode 1
versionName "1.1" versionName "1.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@ -44,12 +44,12 @@ android {
} }
dependencies { dependencies {
implementation 'com.google.android.material:material:1.6.0' implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0' implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
implementation fileTree(dir: "libs", include: ["*.aar"]) implementation fileTree(dir: "libs", include: ["*.aar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:1.6.21"
implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.work:work-runtime:2.7.1' implementation 'androidx.work:work-runtime:2.7.1'
implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.recyclerview:recyclerview:1.2.1'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
@ -62,7 +62,7 @@ dependencies {
implementation 'com.alibaba:fastjson:1.2.78' implementation 'com.alibaba:fastjson:1.2.78'
//noinspection GradleCompatible //noinspection GradleCompatible
implementation 'com.android.support:support-media-compat:28.0.0' implementation "androidx.media:media:1.6.0"
implementation 'androidx.palette:palette-ktx:1.0.0' implementation 'androidx.palette:palette-ktx:1.0.0'
implementation 'com.github.zrunker:ZTextView:v1.0.2' implementation 'com.github.zrunker:ZTextView:v1.0.2'
@ -73,8 +73,8 @@ dependencies {
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
implementation "androidx.room:room-runtime:2.2.6" implementation "androidx.room:room-runtime:2.4.3"
annotationProcessor "androidx.room:room-compiler:2.2.6" annotationProcessor "androidx.room:room-compiler:2.4.3"
implementation("com.squareup.okhttp3:okhttp:4.9.3") implementation("com.squareup.okhttp3:okhttp:4.9.3")

View File

@ -13,6 +13,7 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"> android:usesCleartextTraffic="true">
<activity <activity
android:screenOrientation="fullSensor" android:screenOrientation="fullSensor"
android:name=".views.OpenActivity" android:name=".views.OpenActivity"

View File

@ -17,6 +17,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.yutou.nas_music_player.Datas.MusicData; import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.Interfaces.DefaultNetworkInterface;
import com.yutou.nas_music_player.Interfaces.NetworkInterface; 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;
@ -88,11 +89,15 @@ public class AlbumsRecyclerAdapter extends RecyclerView.Adapter<AlbumsRecyclerAd
holder.icon.setOnClickListener(new View.OnClickListener() { holder.icon.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (data.getImg(AppData.minImageWidth, AppData.minImageHigh) != null) { data.getImg(AppData.minImageWidth,AppData.minImageHigh,new DefaultNetworkInterface(){
Glide.with(context).load(data.getImg(AppData.minImageWidth, AppData.minImageHigh)) @Override
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3))) public void httpGetData(Object data, int state) {
.into(holder.icon); super.httpGetData(data, state);
} Glide.with(context).load(data)
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(holder.icon);
}
});
} }
}); });
} else { } else {

View File

@ -0,0 +1,45 @@
package com.yutou.nas_music_player.Adapters;
import android.animation.ObjectAnimator;
import android.graphics.Canvas;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;
public class MusicItemTouchAdapterCallback extends ItemTouchHelper.Callback {
@Override
public boolean isItemViewSwipeEnabled() {
return true;
}
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
return makeMovementFlags(0,ItemTouchHelper.START);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
// super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
//System.out.println("c = " + c + ", recyclerView = " + recyclerView + ", viewHolder = " + viewHolder + ", dX = " + dX + ", dY = " + dY + ", actionState = " + actionState + ", isCurrentlyActive = " + isCurrentlyActive);
if(isCurrentlyActive){
ObjectAnimator animator=ObjectAnimator.ofFloat(viewHolder.itemView,"translationX",-300).setDuration(300);
animator.start();
ViewGroup.LayoutParams params=viewHolder.itemView.getLayoutParams();
params.width+=300;
viewHolder.itemView.setLayoutParams(params);
// viewHolder.itemView.setX(dX);
}
}
}

View File

@ -22,11 +22,13 @@ import com.alibaba.fastjson.JSONObject;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.yutou.nas_music_player.Datas.MusicData; import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.Interfaces.DefaultNetworkInterface;
import com.yutou.nas_music_player.Interfaces.NetworkInterface; import com.yutou.nas_music_player.Interfaces.NetworkInterface;
import com.yutou.nas_music_player.MyApplication; import com.yutou.nas_music_player.MyApplication;
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.network.HttpManager;
import com.yutou.nas_music_player.tools.AppData; import com.yutou.nas_music_player.tools.AppData;
import com.yutou.nas_music_player.tools.AppTools; import com.yutou.nas_music_player.tools.AppTools;
import com.yutou.nas_music_player.tools.StringUtil; import com.yutou.nas_music_player.tools.StringUtil;
@ -321,24 +323,32 @@ public class MusicLibsAdapter extends RecyclerView.Adapter<MusicLibsAdapter.View
Intent intent = new Intent(itemView.getContext(), AlbumsActivity.class); Intent intent = new Intent(itemView.getContext(), AlbumsActivity.class);
intent.putExtra("model", 2); intent.putExtra("model", 2);
intent.putExtra("fid", data.getId()); intent.putExtra("fid", data.getId());
intent.putExtra("image", data.getImg(AppData.imageWidth, AppData.imageHigh)); intent.putExtra("image", HttpManager.NetworkAPI.HOME+data.getImageUrl());
if (clickAction != null) { if (clickAction != null) {
clickAction.onClick(intent, icon); clickAction.onClick(intent, icon);
} }
} }
protected void clickAlbum(MusicData data) { protected void clickAlbum(MusicData data) {
System.out.println("点击item"); System.out.println("点击item");
if (data == null) if (data == null)
return; return;
Intent intent = new Intent(itemView.getContext(), AlbumsActivity.class); data.getImg(AppData.imageWidth, AppData.imageHigh,new DefaultNetworkInterface(){
intent.putExtra("model", 0); @Override
intent.putExtra("album", data.getAlbum()); public void httpGetData(Object bitmap, int state) {
intent.putExtra("image", data.getImg(AppData.imageWidth, AppData.imageHigh)); super.httpGetData(data, state);
intent.putExtra("color", AppTools.getImageColor(data.getImg(AppData.minImageWidth, AppData.minImageHigh))); Intent intent = new Intent(itemView.getContext(), AlbumsActivity.class);
if (clickAction != null) { intent.putExtra("model", 0);
clickAction.onClick(intent, icon); intent.putExtra("album", data.getAlbum());
} intent.putExtra("image", HttpManager.NetworkAPI.HOME+data.getImageUrl());
intent.putExtra("color", AppTools.getImageColor((Bitmap) bitmap));
if (clickAction != null) {
clickAction.onClick(intent, icon);
}
}
});
} }
@ -390,12 +400,17 @@ public class MusicLibsAdapter extends RecyclerView.Adapter<MusicLibsAdapter.View
icon.setOnClickListener(new View.OnClickListener() { icon.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (data.getImg(AppData.minImageWidth, AppData.minImageHigh) != null) { data.getImg(AppData.minImageWidth, AppData.minImageHigh,new DefaultNetworkInterface(){
Glide.with(MyApplication.application).load(data.getImg(AppData.minImageWidth, AppData.minImageHigh)) @Override
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3))) public void httpGetData(Object bitmap, int state) {
.into(icon); super.httpGetData(data, state);
icon.setTag("img"); Glide.with(MyApplication.application).load(bitmap)
} .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(icon);
icon.setTag("img");
}
});
} }
}); });
} else { } else {

View File

@ -4,8 +4,12 @@ package com.yutou.nas_music_player.Datas;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils; import android.media.ThumbnailUtils;
import android.view.View;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.ImageSize;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
import com.yutou.nas_music_player.Interfaces.DefaultNetworkInterface; import com.yutou.nas_music_player.Interfaces.DefaultNetworkInterface;
import com.yutou.nas_music_player.Interfaces.DownloadInterface; import com.yutou.nas_music_player.Interfaces.DownloadInterface;
import com.yutou.nas_music_player.Interfaces.NetworkInterface; import com.yutou.nas_music_player.Interfaces.NetworkInterface;
@ -77,6 +81,9 @@ public class MusicData {
@ColumnInfo @ColumnInfo
private String md5;//确保是同一个文件 private String md5;//确保是同一个文件
@Ignore
private Bitmap bitmap;
public MusicData() { public MusicData() {
} }
@ -228,75 +235,43 @@ public class MusicData {
public String getImageUrl() { public String getImageUrl() {
return HttpManager.NetworkAPI.MUSIC_IMAGE + "?fileName=" + getFileBase64(); return HttpManager.NetworkAPI.MUSIC_IMAGE + "?fileName=" + getMd5();
} }
public Bitmap getImg(int width, int height) { public Bitmap getImg() {
return getImg(width, height, new DefaultNetworkInterface()); return bitmap;
} }
public Bitmap getImg(int width, int height,@NonNull NetworkInterface networkInterface) { public Bitmap getImg(int width, int height,@NonNull NetworkInterface networkInterface) {
Bitmap img; if(bitmap!=null) {
if (StringUtil.isEmpty(file) && StringUtil.isEmpty(title) && StringUtil.isEmpty(album)) { networkInterface.httpGetData(bitmap,0);
img = BitmapFactory.decodeResource(MyApplication.application.getResources(), R.mipmap.ic_launcher); return bitmap;
networkInterface.httpGetData(img, 0);
return img;
} }
String imageSaveName = (StringUtil.isEmpty(album) ? title : album) + ".png"; if(width==-1||height==-1){
img = AppTools.getSaveBitmap(imageSaveName); AppTools.initImageLoader(MyApplication.application)
if (img != null) { .loadImage(HttpManager.NetworkAPI.HOME+getImageUrl(),new SimpleImageLoadingListener(){
if (width == -1 && height == -1) { @Override
networkInterface.httpGetData(img, 0); public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
return img; super.onLoadingComplete(imageUri, view, loadedImage);
} networkInterface.httpGetData(loadedImage,0);
networkInterface.httpGetData(ThumbnailUtils.extractThumbnail(img, width, height), width + height); bitmap=loadedImage;
return ThumbnailUtils.extractThumbnail(img, width, height); }
});
}else{
System.out.println(HttpManager.NetworkAPI.HOME+getImageUrl());
AppTools.initImageLoader(MyApplication.application)
.loadImage(HttpManager.NetworkAPI.HOME+getImageUrl(),new ImageSize(width,height),new SimpleImageLoadingListener(){
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
super.onLoadingComplete(imageUri, view, loadedImage);
networkInterface.httpGetData(loadedImage,0);
bitmap=loadedImage;
}
});
} }
img = BitmapFactory.decodeResource(MyApplication.application.getResources(), R.mipmap.ic_launcher); return bitmap;
if (isDownloadImg) {
networkInterface.httpGetData(img, 0);
return img;
}
isDownloadImg = true;
JSONObject json = new JSONObject();
if (!StringUtil.isEmpty(getAlbum())) {
json.put("type", "album");
}
if (!StringUtil.isEmpty(getMd5())) {
json.put("fileName", getMd5());
} else {
json.put("fileName", getTitle());
}
System.out.println("下载图片:" + HttpManager.NetworkAPI.MUSIC_IMAGE + "?" + NetworkTool.toGetSplice(json));
HttpManager.getInstance().downloadImage(HttpManager.NetworkAPI.MUSIC_IMAGE, json, imageSaveName, "post", new DownloadInterface() {
@Override
public void onDownloadOver(File oldJar) {
isDownloadImg = false;
AppTools.saveBitmap(oldJar, imageSaveName);
Bitmap img = BitmapFactory.decodeFile(oldJar.getAbsolutePath());
AppData.handler.post(() -> {
if (width == -1 && height == -1) {
networkInterface.httpGetData(img, 0);
} else {
networkInterface.httpGetData(ThumbnailUtils.extractThumbnail(img, width, height), width + height);
}
});
}
@Override
public void onError(Exception e) {
super.onError(e);
isDownloadImg = false;
Bitmap img = BitmapFactory.decodeResource(MyApplication.application.getResources(), R.mipmap.ic_launcher);
AppData.handler.post(() -> networkInterface.httpGetData(img, 0));
}
});
if (width == -1 && height == -1) {
return img;
}
return ThumbnailUtils.extractThumbnail(img, width, height);
} }

View File

@ -11,5 +11,5 @@ public abstract class DownloadInterface {
* @param oldJar * @param oldJar
*/ */
public abstract void onDownloadOver(File oldJar); public abstract void onDownloadOver(File oldJar);
public void onError(Exception e){}; public void onError(Exception e){}
} }

View File

@ -2,16 +2,34 @@ package com.yutou.nas_music_player;
import android.app.Activity; import android.app.Activity;
import android.app.Application; import android.app.Application;
import android.content.res.AssetManager;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.yutou.nas_music_player.views.OpenActivity;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Arrays;
import dalvik.system.BaseDexClassLoader;
import dalvik.system.DexClassLoader;
import dalvik.system.DexFile;
public class MyApplication extends Application { public class MyApplication extends Application {
public static Application application; public static Application application;
private static WeakReference<Activity> activityWeakReference=null; public static DexClassLoader loader;
private static WeakReference<Activity> activityWeakReference = null;
public static Activity getActivity() { public static Activity getActivity() {
return activityWeakReference.get(); return activityWeakReference.get();
@ -24,7 +42,7 @@ public class MyApplication extends Application {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() { registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override @Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
activityWeakReference=new WeakReference<>(activity); activityWeakReference = new WeakReference<>(activity);
} }
@Override @Override
@ -57,5 +75,178 @@ public class MyApplication extends Application {
} }
}); });
// dexLoader();
System.err.println("加载版本111:" + OpenActivity.version);
}
private void dexLoader() {
File path = new File("/data/data/" + getPackageName() + "/plugs");
if (!path.exists()) {
path.mkdirs();
}
File jar = new File("/data/data/" + getPackageName() + "/plugs/classes.jar");
System.err.println("jar = " + jar.getAbsolutePath());
if (!jar.exists()) {
System.out.println("进这里了");
saveAdJar("classes.jar");
return;
}
try {
Object[] t1 = getDexElements(getClassLoader()); //获取系统类加载器的dexElements数组
loader = new DexClassLoader(jar.getAbsolutePath(), "/data/data/" + getPackageName() + "/plugs/", null, getClassLoader());
Object version = loader.loadClass("com.yutou.nas_music_player.views.OpenActivity").getField("version").get(null);
System.out.println("loader version = " + version);
Object[] t2 = getDexElements(loader); //获取jar包类加载器的dexElements数组
saveLibPath(t1, t2); //合并两个数组并将合并后的数组覆盖到系统类加载器
removeLib(loader); //删掉jar包加载器的数组
System.out.println("加载完成");
getDexElements(getClassLoader());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 合并两个Elements数组并覆盖掉系统加载类的dexElements
*
* @param t1 合成的Elements
* @param t2 被合并的Elements
* @throws Exception 未知异常
*/
private void saveLibPath(Object[] t1, Object[] t2) throws Exception {
//遍历BaseDexClassLoader拿到pathList变量 源码参考 46行
//遍历BaseDexClassLoader源码https://android.googlesource.com/platform/libcore/+/refs/heads/master/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
//DexPathList类的源码 https://android.googlesource.com/platform/libcore/+/refs/heads/master/dalvik/src/main/java/dalvik/system/DexPathList.java
Field[] fields = BaseDexClassLoader.class.getDeclaredFields();
Field pathListField = null;
for (Field field : fields) {
System.out.println("field.getName() = " + field.getName());
if (field.getName().equals("pathList")) {
pathListField = field;
}
}
if (pathListField == null)
return;
pathListField.setAccessible(true);
Object pathList = pathListField.get(getClassLoader());
Field dexElements = pathList.getClass().getDeclaredField("dexElements"); //获取到系统类加载器的dexElements
dexElements.setAccessible(true);
//合并两个获取到系统类加载器的dexElements
Object[] obj = Arrays.copyOf(t1, t1.length + t2.length);
int index = 0;
/* for (int i = 0; i < t2.length; i++) {
obj[t1.length+i]=obj[index];
obj[index++]=t2[i];
}*/
/* for (int i=t1.length,j=0;i<t1.length+t2.length;i++,j++){
Array.set(obj,i,t2[j]);
}*/
System.out.println("obj.length = " + obj.length);
System.arraycopy(t2, 0, obj, t1.length, t2.length);
Object tmp = obj[0];
obj[0] = obj[3];
obj[3] = tmp;
//覆盖操作
dexElements.set(pathList, obj);
}
/**
* 移除类加载器的dexElements不然会提示jar包有多个类加载器
*
* @param loader 被移除dexElements的加载器
*/
private void removeLib(ClassLoader loader) {
try {
Field[] fields = BaseDexClassLoader.class.getDeclaredFields();
Field pathListField = null;
for (Field field : fields) {
if (field.getName().equals("pathList"))
pathListField = field;
}
if (pathListField == null)
return;
pathListField.setAccessible(true);
Object pathList = pathListField.get(loader);
Field dexElements = pathList.getClass().getDeclaredField("dexElements");
dexElements.setAccessible(true);
dexElements.set(pathList, null);//设为null后就不要再使用这个加载器了否则会报空指针
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取类加载器的DexElements数组
*
* @param loader 类加载器
* @return dexElements
*/
private Object[] getDexElements(ClassLoader loader) {
System.out.println("===============start============");
try {
Field[] fields = BaseDexClassLoader.class.getDeclaredFields();
Field pathListField = null;
for (Field field : fields) {
System.out.println(field.getName());
if (field.getName().equals("pathList"))
pathListField = field;
}
if (pathListField == null)
return null;
pathListField.setAccessible(true);
Object pathList = pathListField.get(loader);
Field dexElementsField = pathList.getClass().getDeclaredField("dexElements");
dexElementsField.setAccessible(true);
Object[] dexElements = (Object[]) dexElementsField.get(pathList);
//for仅仅只是用于打印Elements类信息的
String pathStr = "path";
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
pathStr = "dir";
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
pathStr = "file";
for (Object lib : dexElements) {
System.out.println("lib = " + lib);
Field uri_F = lib.getClass().getDeclaredField(pathStr);
Field localName_F = lib.getClass().getDeclaredField("dexFile");
uri_F.setAccessible(true);
localName_F.setAccessible(true);
File path = (File) uri_F.get(lib);
DexFile dexFile = (DexFile) localName_F.get(lib);
//System.out.println("uri = " + path.getAbsolutePath()+" localName = "+(dexFile==null));
}
System.out.println("dexElements length = " + dexElements.length);
System.out.println("===============end============");
return dexElements;
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("===============end error============");
return null;
}
/**
* 从assets中释放jar包资源
*
* @param jarName
*/
private void saveAdJar(String jarName) {
AssetManager manager = this.getResources().getAssets();
try {
InputStream inputStream = manager.open(jarName);
FileOutputStream outputStream = new FileOutputStream("/data/data/" + this.getPackageName() + "/plugs/" + jarName);
if (outputStream == null) {
return;
}
int len = 0;
byte[] bytes = new byte[inputStream.available()];
while ((len = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
}
dexLoader();
} catch (IOException e) {
e.printStackTrace();
}
} }
} }

View File

@ -10,21 +10,24 @@ import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat; import android.support.v4.media.session.PlaybackStateCompat;
import com.yutou.nas_music_player.Datas.MusicData; import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.MyApplication;
import com.yutou.nas_music_player.services.MusicService; import com.yutou.nas_music_player.services.MusicService;
import com.yutou.nas_music_player.tools.AppData; import com.yutou.nas_music_player.tools.AppData;
import com.yutou.nas_music_player.views.PlayLibsActivity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class MediaBrowserHelper { public class MediaBrowserHelper {
private static MediaBrowserHelper helper;
private MediaControllerCompat controllerCompat; private MediaControllerCompat controllerCompat;
private MediaBrowserCompat mMediaBrowser; private MediaBrowserCompat mMediaBrowser;
private MediaBrowserConnectionCallback browserConnectionCallback; private final MediaBrowserConnectionCallback browserConnectionCallback;
private MediaControllerCallback controllerCallback; private final MediaControllerCallback controllerCallback;
private MediaBrowserSubscriptionCallback subscriptionCallback; private final MediaBrowserSubscriptionCallback subscriptionCallback;
private Context context; private final Context context;
public MediaBrowserHelper(Context context) { private MediaBrowserHelper(Context context) {
this.context = context; this.context = context;
browserConnectionCallback = new MediaBrowserConnectionCallback(); browserConnectionCallback = new MediaBrowserConnectionCallback();
controllerCallback = new MediaControllerCallback(); controllerCallback = new MediaControllerCallback();
@ -33,6 +36,12 @@ public class MediaBrowserHelper {
mMediaBrowser.connect(); mMediaBrowser.connect();
MusicContainer.getInstance().addBrowserHelper(this); MusicContainer.getInstance().addBrowserHelper(this);
} }
public static MediaBrowserHelper getInstance(){
if(helper==null){
helper=new MediaBrowserHelper(MyApplication.application);
}
return helper;
}
public void onStop() { public void onStop() {
if (controllerCompat != null) { if (controllerCompat != null) {
@ -70,12 +79,16 @@ public class MediaBrowserHelper {
}); });
} }
private List<MediaControllerCompat.Callback> callbacks = new ArrayList<>(); private final List<MediaControllerCompat.Callback> callbacks = new ArrayList<>();
public void regPlayListener(MediaControllerCompat.Callback playListener) { public void regPlayListener(MediaControllerCompat.Callback playListener) {
callbacks.add(playListener); callbacks.add(playListener);
} }
public void unPlayListener(MediaControllerCompat.Callback playListener) {
callbacks.remove(playListener);
}
public void play(MusicData item) { public void play(MusicData item) {
MusicContainer.getInstance().setNowPlayData(item); MusicContainer.getInstance().setNowPlayData(item);
getTransportControls().play(); getTransportControls().play();
@ -85,17 +98,13 @@ public class MediaBrowserHelper {
@Override @Override
public void onConnected() { public void onConnected() {
super.onConnected(); super.onConnected();
try { System.out.println("初始化:onConnected");
System.out.println("初始化:onConnected"); controllerCompat = new MediaControllerCompat(context, mMediaBrowser.getSessionToken());
controllerCompat = new MediaControllerCompat(context, mMediaBrowser.getSessionToken()); controllerCompat.registerCallback(controllerCallback);
controllerCompat.registerCallback(controllerCallback); controllerCallback.onMetadataChanged(controllerCompat.getMetadata());
controllerCallback.onMetadataChanged(controllerCompat.getMetadata()); controllerCallback.onPlaybackStateChanged(controllerCompat.getPlaybackState());
controllerCallback.onPlaybackStateChanged(controllerCompat.getPlaybackState()); mMediaBrowser.subscribe(mMediaBrowser.getRoot(), subscriptionCallback);
mMediaBrowser.subscribe(mMediaBrowser.getRoot(), subscriptionCallback);
} catch (RemoteException e) {
e.printStackTrace();
}
} }
} }

View File

@ -12,12 +12,10 @@ import android.support.v4.media.MediaDescriptionCompat;
import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat; import android.support.v4.media.session.PlaybackStateCompat;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import androidx.core.graphics.drawable.IconCompat;
import androidx.media.session.MediaButtonReceiver; import androidx.media.session.MediaButtonReceiver;
import com.yutou.nas_music_player.MyApplication; import com.yutou.nas_music_player.MyApplication;
@ -29,22 +27,24 @@ public class MediaNotificationManager {
public static MediaNotificationManager manager; public static MediaNotificationManager manager;
public static final int NOTIFICATION_ID = 412; public static final int NOTIFICATION_ID = 412;
private static final String CHANNEL_ID = MyApplication.application.getPackageName() + ".music_channel"; private static final String CHANNEL_ID = MyApplication.application.getPackageName() + ".music_channel";
private MusicService mService; private final MusicService mService;
private NotificationCompat.Action mPlayAction; private final NotificationCompat.Action mPlayAction;
private NotificationCompat.Action mPauseAction; private final NotificationCompat.Action mPauseAction;
private NotificationCompat.Action mNextAction; private final NotificationCompat.Action mNextAction;
private NotificationCompat.Action mPrevAction; private final NotificationCompat.Action mPrevAction;
private NotificationManager mNotificationManager; private final NotificationManager mNotificationManager;
public static MediaNotificationManager getInstance(){ public static MediaNotificationManager getInstance() {
return manager; return manager;
} }
public MusicService getService(){
public MusicService getService() {
return mService; return mService;
} }
public MediaNotificationManager(MusicService musicService) { public MediaNotificationManager(MusicService musicService) {
this.mService = musicService; this.mService = musicService;
manager=this; manager = this;
mNotificationManager = mNotificationManager =
(NotificationManager) mService.getSystemService(Context.NOTIFICATION_SERVICE); (NotificationManager) mService.getSystemService(Context.NOTIFICATION_SERVICE);
@ -85,6 +85,7 @@ public class MediaNotificationManager {
public NotificationManager getManager() { public NotificationManager getManager() {
return mNotificationManager; return mNotificationManager;
} }
public Notification getNotification(MediaMetadataCompat metadata, public Notification getNotification(MediaMetadataCompat metadata,
@NonNull PlaybackStateCompat state, @NonNull PlaybackStateCompat state,
MediaSessionCompat.Token token) { MediaSessionCompat.Token token) {
@ -105,12 +106,12 @@ public class MediaNotificationManager {
NotificationCompat.Builder builder = new NotificationCompat.Builder(mService, CHANNEL_ID); NotificationCompat.Builder builder = new NotificationCompat.Builder(mService, CHANNEL_ID);
builder.setStyle(new androidx.media.app.NotificationCompat.MediaStyle() builder.setStyle(new androidx.media.app.NotificationCompat.MediaStyle()
.setMediaSession(token) .setMediaSession(token)
.setShowActionsInCompactView(0,1,2) .setShowActionsInCompactView(0, 1, 2)
.setShowCancelButton(true) .setShowCancelButton(true)
.setCancelButtonIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(mService,PlaybackStateCompat.ACTION_STOP)) .setCancelButtonIntent(MediaButtonReceiver.buildMediaButtonPendingIntent(mService, PlaybackStateCompat.ACTION_STOP))
); );
builder.setColor(Color.BLUE); builder.setColor(Color.BLUE);
if(metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON)!=null){ if (metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON) != null) {
builder.setLargeIcon(metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON)); builder.setLargeIcon(metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON));
} }
builder.setOngoing(true); builder.setOngoing(true);
@ -153,6 +154,7 @@ public class MediaNotificationManager {
mNotificationManager.createNotificationChannel(mChannel); mNotificationManager.createNotificationChannel(mChannel);
} }
} }
private PendingIntent createContentIntent() { private PendingIntent createContentIntent() {
Intent openUI = new Intent(mService, MainActivity.class); Intent openUI = new Intent(mService, MainActivity.class);
openUI.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); openUI.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

View File

@ -5,6 +5,7 @@ import static android.media.MediaPlayer.SEEK_PREVIOUS_SYNC;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.media.MediaPlayer; import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
@ -48,19 +49,20 @@ public class MusicContainer {
public static final int PLAY_MODEL_ONE_LOOP = 2;//单曲循环 public static final int PLAY_MODEL_ONE_LOOP = 2;//单曲循环
public static final int PLAY_MODEL_LIST_RANDOM = 3;//列表随机 public static final int PLAY_MODEL_LIST_RANDOM = 3;//列表随机
private static MusicContainer container; private static MusicContainer container;
private MusicLibs libs; private final MusicLibs libs;
private MediaPlayer mediaPlayer; private final MediaPlayer mediaPlayer;
private int playIndex = -1; private int playIndex = -1;
private MusicData nowPlayData = null; private MusicData nowPlayData = null;
private MusicLibsInitInterface initInterface; private MusicLibsInitInterface initInterface;
private List<MediaPlayer.OnCompletionListener> completionListener; private List<MediaPlayer.OnCompletionListener> completionListener;
private List<MediaBrowserHelper> browserHelpers; private final List<MediaBrowserHelper> browserHelpers;
private List<MusicData> playList, tmpList; private List<MusicData> playList;
private LinkedHashMap<String, List<MusicData>> albumMapList; private final List<MusicData> tmpList;
private LinkedHashMap<String, List<MusicData>> artistMapList; private final LinkedHashMap<String, List<MusicData>> albumMapList;
private LinkedHashMap<String, List<MusicData>> collectionMapList; private final LinkedHashMap<String, List<MusicData>> artistMapList;
private final LinkedHashMap<String, List<MusicData>> collectionMapList;
private int playModel = PLAY_MODEL_RANDOM; private int playModel = PLAY_MODEL_RANDOM;
private PreviousPlayerList previousPlayerList; private final PreviousPlayerList previousPlayerList;
private MusicContainer(MusicLibsInitInterface initInterface) { private MusicContainer(MusicLibsInitInterface initInterface) {
this.initInterface = initInterface; this.initInterface = initInterface;
@ -245,7 +247,7 @@ public class MusicContainer {
mediaPlayer.stop(); mediaPlayer.stop();
} }
mediaPlayer.reset(); mediaPlayer.reset();
mediaPlayer.setDataSource(url); mediaPlayer.setDataSource(MyApplication.application, Uri.parse(url));
mediaPlayer.prepare(); mediaPlayer.prepare();
mediaPlayer.start(); mediaPlayer.start();
if (playTimer == null) { if (playTimer == null) {
@ -265,7 +267,7 @@ public class MusicContainer {
ConfigTools.getPreferences().edit().putString(ConfigTools.previous_music, JSONObject.toJSONString(tmp)).apply(); ConfigTools.getPreferences().edit().putString(ConfigTools.previous_music, JSONObject.toJSONString(tmp)).apply();
MediaNotificationManager manager = MediaNotificationManager.getInstance(); MediaNotificationManager manager = MediaNotificationManager.getInstance();
if (manager != null) { if (manager != null) {
manager.getService().updateNotification(); // manager.getService().updateNotification();
} }
tmp = null; tmp = null;
} catch (IOException e) { } catch (IOException e) {
@ -326,8 +328,8 @@ public class MusicContainer {
builder.putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, Long.parseLong(data.getTrack())); builder.putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, Long.parseLong(data.getTrack()));
builder.putLong(MediaMetadataCompat.METADATA_KEY_DISC_NUMBER, Long.parseLong(data.getDisc_no())); builder.putLong(MediaMetadataCompat.METADATA_KEY_DISC_NUMBER, Long.parseLong(data.getDisc_no()));
builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, ((int) (data.getDurationAsDouble() * 1000))); builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, ((int) (data.getDurationAsDouble() * 1000)));
if (data.getImg(AppData.minImageWidth, AppData.minImageHigh) != null) { if (data.getImg() != null) {
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, data.getImg(AppData.minImageWidth, AppData.minImageHigh)); builder.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, data.getImg());
} }
builder.putString("md5", data.getMd5()); builder.putString("md5", data.getMd5());
metadataCompat = builder.build(); metadataCompat = builder.build();
@ -344,6 +346,10 @@ public class MusicContainer {
isPause = true; isPause = true;
mediaPlayer.pause(); mediaPlayer.pause();
} }
public void play(){
isPause=false;
mediaPlayer.start();
}
public void receiverPause() { public void receiverPause() {
for (MediaBrowserHelper helper : browserHelpers) { for (MediaBrowserHelper helper : browserHelpers) {
@ -508,6 +514,11 @@ public class MusicContainer {
this.playIndex = i; this.playIndex = i;
} }
public void clearPlayList() {
playList.clear();
tmpList.clear();
}
public class MusicLibs { public class MusicLibs {
private MusicLibs() { private MusicLibs() {
@ -531,7 +542,7 @@ public class MusicContainer {
AlertDialog dialog = new AlertDialog.Builder(context) AlertDialog dialog = new AlertDialog.Builder(context)
.setTitle("添加到收藏夹") .setTitle("添加到收藏夹")
.setItems((CharSequence[]) titles.toArray(new CharSequence[list.size()]), new DialogInterface.OnClickListener() { .setItems(titles.toArray(new CharSequence[list.size()]), new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if (which == 0) {//添加新收藏夹 if (which == 0) {//添加新收藏夹

View File

@ -8,7 +8,6 @@ import androidx.annotation.NonNull;
import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.bumptech.glide.load.HttpException;
import com.yutou.nas_music_player.Interfaces.DownloadInterface; import com.yutou.nas_music_player.Interfaces.DownloadInterface;
import com.yutou.nas_music_player.Interfaces.NetworkInterface; import com.yutou.nas_music_player.Interfaces.NetworkInterface;
import com.yutou.nas_music_player.MyApplication; import com.yutou.nas_music_player.MyApplication;
@ -24,13 +23,8 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.Duration;
import java.time.temporal.TemporalUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -39,7 +33,6 @@ import okhttp3.Call;
import okhttp3.Callback; import okhttp3.Callback;
import okhttp3.FormBody; import okhttp3.FormBody;
import okhttp3.MediaType; import okhttp3.MediaType;
import okhttp3.OkHttp;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.RequestBody; import okhttp3.RequestBody;
@ -50,7 +43,7 @@ public class HttpManager {
public static String downloadPath = AppData.dir + AppData.download_dir + File.separator; public static String downloadPath = AppData.dir + AppData.download_dir + File.separator;
public static class NetworkAPI { public static class NetworkAPI {
public static final String HTTP_KEY = "zIrsh9TUZP2lfRW753PannG49E7VJvor"; public static final String HTTP_KEY = "OHreoKn2CSlDipWV6phEupAqPIX2LJFl";
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_Album = HOME + "/music/getAlbum.do";
@ -250,7 +243,7 @@ public class HttpManager {
}); });
} }
private List<String> downloadImageList = new ArrayList<>(); private final List<String> downloadImageList = new ArrayList<>();
public synchronized void downloadImage(String url, JSONObject body, String saveName, String method, DownloadInterface downloadInterface) { public synchronized void downloadImage(String url, JSONObject body, String saveName, String method, DownloadInterface downloadInterface) {
if(saveName.contains("/")){ if(saveName.contains("/")){
@ -296,7 +289,7 @@ public class HttpManager {
Log.i("donwloadImage", "下载文件:" + url + "?" + body + " 保存文件:" + saveName); Log.i("donwloadImage", "下载文件:" + url + "?" + body + " 保存文件:" + saveName);
Log.i("downloadImageCode", response.code() + ""); Log.i("downloadImageCode", response.code() + "");
if (response.code() != 200) { if (response.code() != 200) {
downloadInterface.onError(new HttpException("http error = " + response.code())); downloadInterface.onError(new Exception("http error = " + response.code()));
return; return;
} }

View File

@ -28,12 +28,13 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class MusicService extends MediaBrowserServiceCompat { public class MusicService extends MediaBrowserServiceCompat {
private final static String TAG="MusicService"; private final static String TAG = "MusicService";
public MediaSessionCompat mediaSession; public MediaSessionCompat mediaSession;
private PlaybackStateCompat.Builder stateBuilder; private PlaybackStateCompat.Builder stateBuilder;
private MediaNotificationManager notificationManager; private MediaNotificationManager notificationManager;
private int mState = PlaybackStateCompat.STATE_PLAYING; private int mState = PlaybackStateCompat.STATE_PLAYING;
private String playMd5=""; private String playMd5 = "";
private MediaBrowserHelper helper;
private static final long MEDIA_SESSION_ACTIONS = PlaybackStateCompat.ACTION_PLAY private static final long MEDIA_SESSION_ACTIONS = PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_PAUSE | PlaybackStateCompat.ACTION_PAUSE
@ -43,6 +44,9 @@ public class MusicService extends MediaBrowserServiceCompat {
| PlaybackStateCompat.ACTION_STOP | PlaybackStateCompat.ACTION_STOP
| PlaybackStateCompat.ACTION_SEEK_TO; | PlaybackStateCompat.ACTION_SEEK_TO;
MusicReceiver receiver = new MusicReceiver();
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
@ -57,25 +61,26 @@ public class MusicService extends MediaBrowserServiceCompat {
mediaSession.setPlaybackState(stateBuilder.build()); mediaSession.setPlaybackState(stateBuilder.build());
mediaSession.setCallback(new MediaSessionCallback()); mediaSession.setCallback(new MediaSessionCallback());
Intent intent = new Intent(this, MainActivity.class); Intent intent = new Intent(this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 233, intent, PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent pi = PendingIntent.getActivity(this, 233, intent, PendingIntent.FLAG_MUTABLE);
mediaSession.setSessionActivity(pi); mediaSession.setSessionActivity(pi);
setSessionToken(mediaSession.getSessionToken()); setSessionToken(mediaSession.getSessionToken());
MusicContainer.getInstance().addCompletionListener(new PlayCompletionListener()); MusicContainer.getInstance().addCompletionListener(new PlayCompletionListener());
MediaBrowserHelper helper = new MediaBrowserHelper(this); helper = MediaBrowserHelper.getInstance();
helper.regPlayListener(new MediaControllerCompat.Callback() { helper.regPlayListener(new MediaControllerCompat.Callback() {
private String compat_md5=""; private String compat_md5 = "";
private MediaMetadataCompat compat; private MediaMetadataCompat compat;
@Override @Override
public void onMetadataChanged(MediaMetadataCompat metadata) { public void onMetadataChanged(MediaMetadataCompat metadata) {
super.onMetadataChanged(metadata); super.onMetadataChanged(metadata);
if(metadata==null){ if (metadata == null) {
return; return;
} }
String md5=metadata.getString("md5"); String md5 = metadata.getString("md5");
if(compat_md5.equals(md5)){ if (compat_md5.equals(md5)) {
return; return;
} }
compat_md5=md5; compat_md5 = md5;
Notification notification = notificationManager.getNotification(metadata, builderState(0).build(), getSessionToken()); Notification notification = notificationManager.getNotification(metadata, builderState(0).build(), getSessionToken());
notificationManager.getManager() notificationManager.getManager()
.notify(MediaNotificationManager.NOTIFICATION_ID, notification); .notify(MediaNotificationManager.NOTIFICATION_ID, notification);
@ -84,10 +89,10 @@ public class MusicService extends MediaBrowserServiceCompat {
@Override @Override
public void onPlaybackStateChanged(PlaybackStateCompat state) { public void onPlaybackStateChanged(PlaybackStateCompat state) {
super.onPlaybackStateChanged(state); super.onPlaybackStateChanged(state);
if(mState==state.getState()){ if (mState == state.getState()) {
return; return;
} }
mState=state.getState(); mState = state.getState();
MusicData data = MusicContainer.getInstance().getNowPlayData(); MusicData data = MusicContainer.getInstance().getNowPlayData();
MediaMetadataCompat metadataCompat = MusicContainer.getInstance().getMetadataCompat(data); MediaMetadataCompat metadataCompat = MusicContainer.getInstance().getMetadataCompat(data);
Notification notification = notificationManager.getNotification(metadataCompat, builderState(state.getPosition()).build(), getSessionToken()); Notification notification = notificationManager.getNotification(metadataCompat, builderState(state.getPosition()).build(), getSessionToken());
@ -95,6 +100,14 @@ public class MusicService extends MediaBrowserServiceCompat {
.notify(MediaNotificationManager.NOTIFICATION_ID, notification); .notify(MediaNotificationManager.NOTIFICATION_ID, notification);
} }
}); });
System.out.println("注册receiver");
registerReceiver(receiver, intentFilter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
} }
@Nullable @Nullable
@ -117,8 +130,8 @@ public class MusicService extends MediaBrowserServiceCompat {
public void seekToNotification(long pos) { public void seekToNotification(long pos) {
MusicData data = MusicContainer.getInstance().getNowPlayData(); MusicData data = MusicContainer.getInstance().getNowPlayData();
if(!playMd5.equals(data.getMd5())){ if (!playMd5.equals(data.getMd5())) {
playMd5=data.getMd5(); playMd5 = data.getMd5();
mediaSession.setMetadata(MusicContainer.getInstance().getNowPlayMetadataCompat()); mediaSession.setMetadata(MusicContainer.getInstance().getNowPlayMetadataCompat());
updateNotification(); updateNotification();
} }
@ -179,15 +192,16 @@ public class MusicService extends MediaBrowserServiceCompat {
} }
public class MediaSessionCallback extends MediaSessionCompat.Callback { public class MediaSessionCallback extends MediaSessionCompat.Callback {
MusicReceiver receiver = new MusicReceiver();
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY); boolean isRegReceiver = false;
@Override @Override
public void onPlay() { public void onPlay() {
super.onPlay(); super.onPlay();
System.out.println("接收到播放指令"); System.out.println("接收到播放指令");
if (!isRegReceiver) {
registerReceiver(receiver, intentFilter); isRegReceiver = true;
}
mState = PlaybackStateCompat.STATE_PLAYING; mState = PlaybackStateCompat.STATE_PLAYING;
MediaMetadataCompat metadataCompat = MusicContainer.getInstance().getNowPlayMetadataCompat(); MediaMetadataCompat metadataCompat = MusicContainer.getInstance().getNowPlayMetadataCompat();
mediaSession.setMetadata(metadataCompat); mediaSession.setMetadata(metadataCompat);
@ -200,9 +214,15 @@ public class MusicService extends MediaBrowserServiceCompat {
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
mState = PlaybackStateCompat.STATE_PAUSED; System.out.println("点击暂停");
MusicContainer.getInstance().pause(); if (helper.isPlayer()) {
mState = PlaybackStateCompat.STATE_PAUSED;
MusicContainer.getInstance().pause();
} else {
mState = PlaybackStateCompat.STATE_PLAYING;
MusicContainer.getInstance().play();
}
updateNotification();
//MusicService.this.onSeekTo(-1); //MusicService.this.onSeekTo(-1);
} }
@ -218,6 +238,7 @@ public class MusicService extends MediaBrowserServiceCompat {
@Override @Override
public void onSkipToNext() { public void onSkipToNext() {
super.onSkipToNext(); super.onSkipToNext();
System.out.println("播放下一曲");
MusicContainer.getInstance().playNext(); MusicContainer.getInstance().playNext();
updateNotification(); updateNotification();
} }
@ -234,7 +255,7 @@ public class MusicService extends MediaBrowserServiceCompat {
super.onStop(); super.onStop();
mState = PlaybackStateCompat.STATE_STOPPED; mState = PlaybackStateCompat.STATE_STOPPED;
MusicContainer.getInstance().getMediaPlayer().stop(); MusicContainer.getInstance().getMediaPlayer().stop();
unregisterReceiver(receiver); isRegReceiver = false;
} }
} }

View File

@ -13,8 +13,8 @@ public class AppData {
public static String dir= MyApplication.application.getFilesDir() + File.separator; public static String dir= MyApplication.application.getFilesDir() + File.separator;
public static boolean isDebug=true; public static boolean isDebug=true;
public static Handler handler=new Handler(Looper.getMainLooper()); public static Handler handler=new Handler(Looper.getMainLooper());
public static int imageWidth=400; public static int imageWidth=200;
public static int imageHigh=400; public static int imageHigh=200;
public static int minImageWidth=200; public static int minImageWidth=80;
public static int minImageHigh=200; public static int minImageHigh=80;
} }

View File

@ -24,6 +24,7 @@ import java.security.MessageDigest;
public class AppTools { public class AppTools {
private static KProgressHUD hud; private static KProgressHUD hud;
private static ImageLoader imageLoader;
public static synchronized void showHud(Context context) { public static synchronized void showHud(Context context) {
hideHud(); hideHud();
@ -88,7 +89,7 @@ public class AppTools {
} }
private static String bytesToHexString(byte[] src) { private static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder(""); StringBuilder stringBuilder = new StringBuilder();
if (src == null || src.length <= 0) { if (src == null || src.length <= 0) {
return null; return null;
} }
@ -113,8 +114,11 @@ public class AppTools {
} }
public static ImageLoader initImageLoader(Context context) { public static ImageLoader initImageLoader(Context context) {
if(imageLoader!=null){
return imageLoader;
}
ImageLoader imageLoader = ImageLoader.getInstance(); imageLoader = ImageLoader.getInstance();
ImageLoaderConfiguration.Builder builder = new ImageLoaderConfiguration.Builder(context); ImageLoaderConfiguration.Builder builder = new ImageLoaderConfiguration.Builder(context);
File cachePath = new File(context.getFilesDir().getAbsolutePath() + "/cache/"); File cachePath = new File(context.getFilesDir().getAbsolutePath() + "/cache/");
if (!cachePath.exists()) { if (!cachePath.exists()) {

View File

@ -12,7 +12,7 @@ import java.io.StringWriter;
*/ */
public class Log { public class Log {
public static boolean isDebug = AppData.isDebug; public static boolean isDebug = AppData.isDebug;
private static boolean LogPrint = false; private static final boolean LogPrint = false;
public static String getErrorLog(Exception e) { public static String getErrorLog(Exception e) {
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
@ -29,7 +29,7 @@ public class Log {
+ "SDK_Version = " + Build.VERSION.SDK_INT + "\n" + "SDK_Version = " + Build.VERSION.SDK_INT + "\n"
+ "files = " + files + "files = " + files
+ "Error = \n"; + "Error = \n";
return str + writer.toString(); return str + writer;
} }
private static void printOrInfo(String string) { private static void printOrInfo(String string) {
@ -68,7 +68,7 @@ public class Log {
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer); PrintWriter printWriter = new PrintWriter(writer);
e.printStackTrace(printWriter); e.printStackTrace(printWriter);
printOrError("[" + title + "]" + writer.toString()); printOrError("[" + title + "]" + writer);
} }
public static void toast(final Context context, final String string) { public static void toast(final Context context, final String string) {

View File

@ -34,7 +34,7 @@ import static com.yutou.nas_music_player.tools.NetworkTool.NetworkAPI.HTTP_KEY;
public class NetworkTool { public class NetworkTool {
public static class NetworkAPI { public static class NetworkAPI {
public static final String HTTP_KEY = "zIrsh9TUZP2lfRW753PannG49E7VJvor"; public static final String HTTP_KEY = "OHreoKn2CSlDipWV6phEupAqPIX2LJFl";
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_Album = HOME + "/music/getAlbum.do";
@ -187,7 +187,7 @@ public class NetworkTool {
} }
private Map<JSONObject, Integer> map = Collections.synchronizedMap(new HashMap<JSONObject, Integer>()); private final Map<JSONObject, Integer> map = Collections.synchronizedMap(new HashMap<JSONObject, Integer>());
public void httpPost(final String url, final JSONObject body, final NetworkInterface networkInterface) { public void httpPost(final String url, final JSONObject body, final NetworkInterface networkInterface) {
if (!url.startsWith("http:") && !StringUtil.isEmpty(HOME)) { if (!url.startsWith("http:") && !StringUtil.isEmpty(HOME)) {
@ -230,7 +230,7 @@ public class NetworkTool {
while ((tmp = reader.readLine()) != null) { while ((tmp = reader.readLine()) != null) {
str.append(tmp); str.append(tmp);
} }
Log.i(TAG, "[域名]" + url + " = [body]" + body.toString() + " -> [接收] " + str); Log.i(TAG, "[域名]" + url + " = [body]" + body + " -> [接收] " + str);
final String finalStr = str.toString(); final String finalStr = str.toString();
// Log.i(TAG + "[" + url + "?" + toGetSplice(body) + "]", "body:" + str + " (" + connection.getResponseCode() + ")"); // Log.i(TAG + "[" + url + "?" + toGetSplice(body) + "]", "body:" + str + " (" + connection.getResponseCode() + ")");
@ -316,7 +316,7 @@ public class NetworkTool {
download(url, new JSONObject(), saveName, "GET", null); download(url, new JSONObject(), saveName, "GET", null);
} }
private List<String> downloadImageList = new ArrayList<>(); private final List<String> downloadImageList = new ArrayList<>();
public synchronized void downloadImage(final String url, final JSONObject body, final String saveName, String method, final DownloadInterface downloadInterface) { public synchronized void downloadImage(final String url, final JSONObject body, final String saveName, String method, final DownloadInterface downloadInterface) {
System.out.println(">>>>>>>>>>" + url); System.out.println(">>>>>>>>>>" + url);
@ -342,7 +342,7 @@ public class NetworkTool {
HttpURLConnection connection = (HttpURLConnection) new URL(url + "?" + toGetSplice(body)).openConnection(); HttpURLConnection connection = (HttpURLConnection) new URL(url + "?" + toGetSplice(body)).openConnection();
// Log.i(TAG,"获取到网络请求:"+connection.getResponseCode()); // Log.i(TAG,"获取到网络请求:"+connection.getResponseCode());
if (method.toLowerCase().equals("post")) { if (method.equalsIgnoreCase("post")) {
connection.setRequestMethod("POST"); connection.setRequestMethod("POST");
connection.setDoOutput(true); connection.setDoOutput(true);
connection.setDoInput(true); connection.setDoInput(true);
@ -414,7 +414,7 @@ public class NetworkTool {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
// Log.i(TAG,"获取到网络请求:"+connection.getResponseCode()); // Log.i(TAG,"获取到网络请求:"+connection.getResponseCode());
if (method.toLowerCase().equals("post")) { if (method.equalsIgnoreCase("post")) {
connection.setRequestMethod("POST"); connection.setRequestMethod("POST");
connection.setDoOutput(true); connection.setDoOutput(true);
connection.setDoInput(true); connection.setDoInput(true);

View File

@ -5,6 +5,7 @@ import android.graphics.BitmapFactory;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.media.session.MediaControllerCompat; import android.support.v4.media.session.MediaControllerCompat;
import android.view.View;
import android.view.Window; import android.view.Window;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
@ -18,6 +19,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.AppBarLayout;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
import com.yutou.nas_music_player.Adapters.AlbumsRecyclerAdapter; import com.yutou.nas_music_player.Adapters.AlbumsRecyclerAdapter;
import com.yutou.nas_music_player.Datas.MusicData; import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.Interfaces.NetworkInterface; import com.yutou.nas_music_player.Interfaces.NetworkInterface;
@ -41,6 +43,7 @@ public class AlbumsActivity extends AppCompatActivity {
private TextView breakApp; private TextView breakApp;
private Button playAll; private Button playAll;
private int model;//0 专辑, 1 歌手, 2 收藏 private int model;//0 专辑, 1 歌手, 2 收藏
private PlayListener playListener;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
@ -59,20 +62,29 @@ public class AlbumsActivity extends AppCompatActivity {
default: default:
finish(); finish();
} }
Bitmap image=getIntent().getParcelableExtra("image"); String imageUrl = getIntent().getStringExtra("image");
if(image!=null){ if (imageUrl != null) {
album_image.setImageBitmap(image); AppTools.initImageLoader(this).displayImage(imageUrl, album_image);
Glide.with(AlbumsActivity.this).load(image) AppTools.initImageLoader(this)
.apply(RequestOptions.bitmapTransform(new BlurTransformation(25, 3))) .loadImage(imageUrl, new SimpleImageLoadingListener() {
.into(image_background); @Override
}else{ public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
super.onLoadingComplete(imageUri, view, loadedImage);
Glide.with(AlbumsActivity.this).load(loadedImage)
.apply(RequestOptions.bitmapTransform(new BlurTransformation(25, 3)))
.into(image_background);
}
});
} else {
album_image.setImageResource(R.mipmap.ic_launcher); album_image.setImageResource(R.mipmap.ic_launcher);
Glide.with(AlbumsActivity.this).load(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher)) Glide.with(AlbumsActivity.this).load(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
.apply(RequestOptions.bitmapTransform(new BlurTransformation(25, 3))) .apply(RequestOptions.bitmapTransform(new BlurTransformation(25, 3)))
.into(image_background); .into(image_background);
} }
browserHelper = new MediaBrowserHelper(this); playListener = new PlayListener();
browserHelper.regPlayListener(new PlayListener()); browserHelper = MediaBrowserHelper.getInstance();
browserHelper.regPlayListener(playListener);
adapter.setPlayListener(browserHelper); adapter.setPlayListener(browserHelper);
listView.setBackgroundColor(getIntent().getIntExtra("color", Color.parseColor("#bbbbbb"))); listView.setBackgroundColor(getIntent().getIntExtra("color", Color.parseColor("#bbbbbb")));
playAll.setBackgroundColor(getIntent().getIntExtra("color", Color.parseColor("#bbbbbb"))); playAll.setBackgroundColor(getIntent().getIntExtra("color", Color.parseColor("#bbbbbb")));
@ -93,7 +105,7 @@ public class AlbumsActivity extends AppCompatActivity {
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
if (list.isEmpty()) if (list.isEmpty())
return; return;
list.get(0).getImg(AppData.imageWidth,AppData.imageHigh, new NetworkInterface() { list.get(0).getImg(AppData.imageWidth, AppData.imageHigh, new NetworkInterface() {
@Override @Override
public void httpGetData(Object data, int state) { public void httpGetData(Object data, int state) {
album_image.setImageBitmap((Bitmap) data); album_image.setImageBitmap((Bitmap) data);
@ -142,7 +154,7 @@ public class AlbumsActivity extends AppCompatActivity {
listView = findViewById(R.id.album_list); listView = findViewById(R.id.album_list);
breakApp = findViewById(R.id.breakApp); breakApp = findViewById(R.id.breakApp);
appBarLayout = findViewById(R.id.appbar); appBarLayout = findViewById(R.id.appbar);
playAll=findViewById(R.id.playAll); playAll = findViewById(R.id.playAll);
listView.setLayoutManager(new LinearLayoutManager(this)); listView.setLayoutManager(new LinearLayoutManager(this));
adapter = new AlbumsRecyclerAdapter(AlbumsActivity.this, new ArrayList<>(), model); adapter = new AlbumsRecyclerAdapter(AlbumsActivity.this, new ArrayList<>(), model);
listView.setAdapter(adapter); listView.setAdapter(adapter);
@ -164,6 +176,6 @@ public class AlbumsActivity extends AppCompatActivity {
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
adapter.onStop(); adapter.onStop();
browserHelper.onStop(); browserHelper.unPlayListener(playListener);
} }
} }

View File

@ -20,6 +20,7 @@ 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;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import com.yutou.nas_music_player.Adapters.MusicLibsAdapter; import com.yutou.nas_music_player.Adapters.MusicLibsAdapter;
import com.yutou.nas_music_player.Datas.MusicData; import com.yutou.nas_music_player.Datas.MusicData;
@ -94,9 +95,15 @@ public class MusicLibsFragment extends Fragment {
getContext().startActivity(intent, bundle); getContext().startActivity(intent, bundle);
}); });
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
if(MusicContainer.getInstance().getNowPlayData()==null){ closeDefaultAnimator();
return; }
} /* * 关闭默认局部刷新动画 this代表recycleview*/
public void closeDefaultAnimator() {
listView.getItemAnimator().setAddDuration(0);
listView.getItemAnimator().setChangeDuration(0);
listView.getItemAnimator().setMoveDuration(0);
listView.getItemAnimator().setRemoveDuration(0);
((SimpleItemAnimator) listView.getItemAnimator()).setSupportsChangeAnimations(false);
} }
public MusicLibsAdapter getAdapter() { public MusicLibsAdapter getAdapter() {
@ -122,7 +129,7 @@ public class MusicLibsFragment extends Fragment {
} }
List<MusicData> list = new ArrayList<>(); List<MusicData> list = new ArrayList<>();
private String musicPath = "root"; private final String musicPath = "root";
public void initData() { public void initData() {
AppTools.showHud(context); AppTools.showHud(context);

View File

@ -15,8 +15,10 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar; import android.widget.SeekBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -33,6 +35,7 @@ import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.yutou.nas_music_player.Adapters.MusicLibsAdapter; import com.yutou.nas_music_player.Adapters.MusicLibsAdapter;
import com.yutou.nas_music_player.Datas.MusicData; import com.yutou.nas_music_player.Datas.MusicData;
import com.yutou.nas_music_player.Interfaces.DefaultNetworkInterface;
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;
@ -58,6 +61,7 @@ public class MainActivity extends AppCompatActivity {
private TextView positionTime, durationTime, bitRate, playIndex; private TextView positionTime, durationTime, bitRate, playIndex;
private SeekBar seekBar; private SeekBar seekBar;
private Handler handler; private Handler handler;
private PlayListener playListener;
private GestureDetectorCompat touch; private GestureDetectorCompat touch;
@ -108,9 +112,9 @@ public class MainActivity extends AppCompatActivity {
} }
setPlayModelButton(model + 1, true); setPlayModelButton(model + 1, true);
}); });
playListener=new PlayListener();
browserHelper = new MediaBrowserHelper(this); browserHelper = MediaBrowserHelper.getInstance();
browserHelper.regPlayListener(new PlayListener()); browserHelper.regPlayListener(playListener);
initData(); initData();
} }
@ -193,14 +197,28 @@ public class MainActivity extends AppCompatActivity {
private void setImage(MusicData data) { private void setImage(MusicData data) {
// setBarColor(data.getImageColor()); // setBarColor(data.getImageColor());
Glide.with(this).load(data.getImg(AppData.imageWidth, AppData.imageHigh)) data.getImg(AppData.imageWidth, AppData.imageHigh,new DefaultNetworkInterface(){
.placeholder(album_image.getDrawable()) @Override
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3))) public void httpGetData(Object bitmap, int state) {
.into(album_image); super.httpGetData(data, state);
Glide.with(this).load(data.getImg(AppData.minImageWidth, AppData.minImageHigh)) Glide.with(MainActivity.this).load(bitmap)
.placeholder(background_image.getDrawable()) .placeholder(album_image.getDrawable())
.apply(RequestOptions.bitmapTransform(new BlurTransformation(25, 3))) .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(background_image); .into(album_image);
Glide.with(MainActivity.this).load(bitmap)
.placeholder(background_image.getDrawable())
.apply(RequestOptions.bitmapTransform(new BlurTransformation(25, 3)))
.into(background_image);
}
});
/* data.getImg(AppData.minImageWidth, AppData.minImageHigh,new DefaultNetworkInterface(){
@Override
public void httpGetData(Object bitmap, int state) {
super.httpGetData(data, state);
}
});*/
} }
private void initView() { private void initView() {
@ -232,6 +250,7 @@ public class MainActivity extends AppCompatActivity {
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
if (browserHelper != null) { if (browserHelper != null) {
browserHelper.unPlayListener(playListener);
browserHelper.onStop(); browserHelper.onStop();
browserHelper = null; browserHelper = null;
} }
@ -266,13 +285,13 @@ public class MainActivity extends AppCompatActivity {
} }
private void toPlayList() { private void toPlayList() {
Pair<View, String> pImage = Pair.create((View) album_image, "main_album_image"); Pair<View, String> pImage = Pair.create(album_image, "main_album_image");
Pair<View, String> pPrevious = Pair.create((View) previous, "previous"); Pair<View, String> pPrevious = Pair.create(previous, "previous");
Pair<View, String> pPlay = Pair.create((View) play, "play"); Pair<View, String> pPlay = Pair.create(play, "play");
Pair<View, String> pNext = Pair.create((View) next, "next"); Pair<View, String> pNext = Pair.create(next, "next");
Pair<View, String> pTitle = Pair.create((View) title, "title"); Pair<View, String> pTitle = Pair.create(title, "title");
Pair<View, String> pArtist = Pair.create((View) artist, "artist"); Pair<View, String> pArtist = Pair.create(artist, "artist");
Pair<View, String> pBar = Pair.create((View) seekBar, "bar"); Pair<View, String> pBar = Pair.create(seekBar, "bar");
Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this, Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this,
pImage, pImage,
pPrevious, pPrevious,
@ -296,6 +315,10 @@ public class MainActivity extends AppCompatActivity {
List<MusicData> playList = MusicContainer.getInstance().getPlayList(); List<MusicData> playList = MusicContainer.getInstance().getPlayList();
POPDialog dialog = new POPDialog(this); POPDialog dialog = new POPDialog(this);
RecyclerView recyclerView = null; RecyclerView recyclerView = null;
Button clear=new Button(this);
LinearLayout layout=new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
clear.setText("清空列表");
dialog.enableExitButton(true); dialog.enableExitButton(true);
if (playList.isEmpty()) { if (playList.isEmpty()) {
dialog.setTitle("播放列表"); dialog.setTitle("播放列表");
@ -312,7 +335,14 @@ public class MainActivity extends AppCompatActivity {
// touchHelper.attachToRecyclerView(recyclerView); // touchHelper.attachToRecyclerView(recyclerView);
adapter.setData(playList); adapter.setData(playList);
adapter.setBrowserHelper(browserHelper); adapter.setBrowserHelper(browserHelper);
dialog.setContentView(recyclerView); clear.setOnClickListener(view -> {
MusicContainer.getInstance().clearPlayList();
AppTools.toast("列表已清空");
dialog.dismiss();
});
layout.addView(clear);
layout.addView(recyclerView);
dialog.setContentView(layout);
} }
dialog.show(); dialog.show();
} }

View File

@ -0,0 +1,128 @@
package com.yutou.nas_music_player.views;
import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
import androidx.core.view.GestureDetectorCompat;
public class MyItemLayout extends LinearLayout {
private GestureDetectorCompat touch;
private int mTotalLength;
public MyItemLayout(Context context) {
super(context);
initTouch(context);
}
public MyItemLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initTouch(context);
}
private void initTouch(Context context) {
touch = new GestureDetectorCompat(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
System.out.println("MyItemLayout.onFling");
return super.onFling(e1, e2, velocityX, velocityY);
}
@Override
public boolean onDown(MotionEvent e) {
System.out.println("MyItemLayout.onDown");
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
System.out.println("MyItemLayout.onScroll");
MyItemLayout.this.setX(MyItemLayout.this.getX()+e2.getX());
return super.onScroll(e1, e2, distanceX, distanceY);
}
/* @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
float y = e2.getY() - e1.getY();
System.out.println("执行动画");
if (Math.abs(y) < 200) {
float x = e2.getX() - e1.getX();
ObjectAnimator animator = new ObjectAnimator();
animator.setTarget(MyItemLayout.this);
animator.setPropertyName("translationX");
animator.setDuration(300);
if (x < 0) {
animator.setFloatValues(-(mTotalLength - getRight()));
} else {
animator.setFloatValues(0);
}
animator.start();
return true;
}
return super.onScroll(e1, e2, distanceX, distanceY);
}*/
});
}
private final boolean down = false;
private final boolean up = false;
private final boolean move = false;
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean tmp = super.onTouchEvent(ev);
/* int action = ev.getAction();
if (action == MotionEvent.ACTION_DOWN) {
down = true;
move = false;
up = false;
} else if (action == MotionEvent.ACTION_UP) {
down = false;
move = false;
up = true;
} else if (action == MotionEvent.ACTION_MOVE) {
down = true;
move = true;
up = false;
}
System.out.println("action = " + action + " down = " + down + " move = " + move + " up = " + up);
if (down && !up && !move) {
return false;
} else if (down && move && !up) {
System.out.println("移动啦");
boolean clickVal = touch.onTouchEvent(ev);
return true;
} else if (down && up && !move) {
return false;
}
AppTools.toast(tmp+"");*/
tmp=true;
if (ev.getAction() == MotionEvent.ACTION_MOVE) {
System.out.println("进触摸");
boolean clickVal = touch.onTouchEvent(ev);
return clickVal;
}
return tmp;
}
@Override
protected void onLayout(boolean changed, int _left, int top, int _right, int bottom) {
//right+=300;
super.onLayout(changed, _left, top, _right, bottom);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
for (int i = 0; i < getChildCount(); i++) {
mTotalLength += getChildAt(i).getWidth();
}
System.out.println("mTotalLength = " + mTotalLength);
}
}

View File

@ -2,6 +2,9 @@ package com.yutou.nas_music_player.views;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -9,22 +12,55 @@ import androidx.appcompat.app.AppCompatActivity;
import com.yutou.nas_music_player.R; import com.yutou.nas_music_player.R;
import com.yutou.nas_music_player.containers.MusicContainer; import com.yutou.nas_music_player.containers.MusicContainer;
import com.yutou.nas_music_player.tools.AppTools;
import cc.ibooker.ztextviewlib.MarqueeTextView;
public class OpenActivity extends AppCompatActivity { public class OpenActivity extends AppCompatActivity {
TextView textView; TextView textView;
public static String version="1.0";
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_open); if (false) {
textView=findViewById(R.id.textView); setContentView(R.layout.layout_music_libs_item);
MusicContainer.getInstance(new MusicContainer.MusicLibsInitInterface() { System.out.println("ok");
@Override ImageButton a,b,c;
public void init() { MarqueeTextView textView=findViewById(R.id.title);
Intent intent=new Intent(OpenActivity.this,MainActivity.class); LinearLayout layout=findViewById(R.id.layout);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); a=findViewById(R.id.dislike);
startActivity(intent); b=findViewById(R.id.collection);
OpenActivity.this.finish(); c=findViewById(R.id.top);
} layout.setTag("layout");
}); a.setTag("a");
b.setTag("b");
c.setTag("c");
textView.setText(version);
a.setOnClickListener(new Click());
b.setOnClickListener(new Click());
c.setOnClickListener(new Click());
layout.setOnClickListener(new Click());
System.out.println("version = " + version);
} else {
setContentView(R.layout.activity_open);
textView = findViewById(R.id.textView);
MusicContainer.getInstance(new MusicContainer.MusicLibsInitInterface() {
@Override
public void init() {
Intent intent = new Intent(OpenActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
OpenActivity.this.finish();
}
});
}
}
private static class Click implements View.OnClickListener{
@Override
public void onClick(View view) {
AppTools.toast("click view = "+view.getTag());
}
} }
} }

View File

@ -50,14 +50,14 @@ public class PlayLibsActivity extends AppCompatActivity {
private TabLayout tabLayout; private TabLayout tabLayout;
private ViewPager2 viewPager; private ViewPager2 viewPager;
private int index = 0; private final int index = 0;
PlayListener playListener = new PlayListener();
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_list); setContentView(R.layout.activity_play_list);
PlayListener playListener = new PlayListener(); browserHelper = MediaBrowserHelper.getInstance();
browserHelper = new MediaBrowserHelper(this);
browserHelper.regPlayListener(playListener); browserHelper.regPlayListener(playListener);
initView(); initView();
bar_pos = getIntent().getIntExtra("bar_pos", 0); bar_pos = getIntent().getIntExtra("bar_pos", 0);
@ -107,6 +107,7 @@ public class PlayLibsActivity extends AppCompatActivity {
} }
List<MusicLibsFragment> fragments; List<MusicLibsFragment> fragments;
private void initView() { private void initView() {
play = findViewById(R.id.collection); play = findViewById(R.id.collection);
next = findViewById(R.id.top); next = findViewById(R.id.top);
@ -117,11 +118,11 @@ public class PlayLibsActivity extends AppCompatActivity {
progressBar = findViewById(R.id.progressBar); progressBar = findViewById(R.id.progressBar);
tabLayout = findViewById(R.id.tabLayout); tabLayout = findViewById(R.id.tabLayout);
viewPager = findViewById(R.id.viewPager); viewPager = findViewById(R.id.viewPager);
fragments=new ArrayList<>(); fragments = new ArrayList<>();
fragments.add(new MusicLibsFragment(this,MusicLibsAdapter.LIBS_MODEL_ALL)); fragments.add(new MusicLibsFragment(this, MusicLibsAdapter.LIBS_MODEL_ALL));
fragments.add(new MusicLibsFragment(this,MusicLibsAdapter.LIBS_MODEL_Album)); fragments.add(new MusicLibsFragment(this, MusicLibsAdapter.LIBS_MODEL_Album));
fragments.add(new MusicLibsFragment(this,MusicLibsAdapter.LIBS_MODEL_PLAY_Collection)); fragments.add(new MusicLibsFragment(this, MusicLibsAdapter.LIBS_MODEL_PLAY_Collection));
fragments.add(new MusicLibsFragment(this,MusicLibsAdapter.LIBS_MODEL_Tmp)); fragments.add(new MusicLibsFragment(this, MusicLibsAdapter.LIBS_MODEL_Tmp));
for (MusicLibsFragment fragment : fragments) { for (MusicLibsFragment fragment : fragments) {
fragment.setPlayContainer(browserHelper); fragment.setPlayContainer(browserHelper);
} }
@ -152,10 +153,10 @@ public class PlayLibsActivity extends AppCompatActivity {
fragments.get(tab.getPosition()).update(); fragments.get(tab.getPosition()).update();
} }
}); });
TabLayoutMediator mediator=new TabLayoutMediator(tabLayout, viewPager, true, new TabLayoutMediator.TabConfigurationStrategy() { TabLayoutMediator mediator = new TabLayoutMediator(tabLayout, viewPager, true, new TabLayoutMediator.TabConfigurationStrategy() {
@Override @Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) { public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
switch (position){ switch (position) {
case 0: case 0:
tab.setText("全部"); tab.setText("全部");
break; break;
@ -191,10 +192,10 @@ public class PlayLibsActivity extends AppCompatActivity {
artist.setText(data.getArtist()); artist.setText(data.getArtist());
progressBar.setMax((int) (data.getDurationAsDouble() * 1000)); progressBar.setMax((int) (data.getDurationAsDouble() * 1000));
progressBar.setProgress(bar_pos); progressBar.setProgress(bar_pos);
data.getImg(AppData.minImageWidth,AppData.minImageHigh, new NetworkInterface() { data.getImg(AppData.minImageWidth, AppData.minImageHigh, new NetworkInterface() {
@Override @Override
public void httpGetData(Object data, int state) { public void httpGetData(Object data, int state) {
setImage((Bitmap) data); setImage((Bitmap) data);
} }
@Override @Override
@ -202,12 +203,12 @@ public class PlayLibsActivity extends AppCompatActivity {
} }
}); });
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
browserHelper.onStop(); browserHelper.unPlayListener(playListener);
browserHelper = null; browserHelper = null;
finish(); finish();
} }

View File

@ -1,6 +1,5 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = "1.4.10"
repositories { repositories {
google() google()