删掉B面代码
This commit is contained in:
parent
f58d8d8bf3
commit
8b8a79f39b
@ -70,7 +70,7 @@ dependencies {
|
|||||||
implementation("io.reactivex.rxjava2:rxandroid:2.1.1")
|
implementation("io.reactivex.rxjava2:rxandroid:2.1.1")
|
||||||
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")
|
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")
|
||||||
|
|
||||||
implementation("androidx.paging:paging-runtime-ktx:3.3.2")
|
// implementation("androidx.paging:paging-runtime-ktx:3.3.2")
|
||||||
|
|
||||||
implementation("com.github.bumptech.glide:glide:4.16.0")
|
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||||
// kapt("com.github.bumptech.glide:compiler:4.16.0")
|
// kapt("com.github.bumptech.glide:compiler:4.16.0")
|
||||||
@ -79,17 +79,17 @@ dependencies {
|
|||||||
|
|
||||||
|
|
||||||
//提取图片主色
|
//提取图片主色
|
||||||
implementation ("androidx.palette:palette:1.0.0")
|
// implementation ("androidx.palette:palette:1.0.0")
|
||||||
|
|
||||||
//动画
|
//动画
|
||||||
implementation ("com.airbnb.android:lottie:6.5.0")
|
// implementation ("com.airbnb.android:lottie:6.5.0")
|
||||||
|
|
||||||
//----------media3
|
//----------media3
|
||||||
implementation("androidx.media3:media3-exoplayer:1.4.1")
|
// implementation("androidx.media3:media3-exoplayer:1.4.1")
|
||||||
implementation("androidx.media3:media3-exoplayer-dash:1.4.1")
|
// implementation("androidx.media3:media3-exoplayer-dash:1.4.1")
|
||||||
implementation("androidx.media3:media3-session:1.4.1")
|
// implementation("androidx.media3:media3-session:1.4.1")
|
||||||
implementation("androidx.media3:media3-ui:1.4.1")
|
// implementation("androidx.media3:media3-ui:1.4.1")
|
||||||
implementation ("androidx.media3:media3-database:1.4.1")
|
// implementation ("androidx.media3:media3-database:1.4.1")
|
||||||
//----------media3
|
//----------media3
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -23,18 +23,7 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.MusicApp"
|
android:theme="@style/Theme.MusicApp"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
<activity
|
|
||||||
android:name=".ui.activity.LikeSongActivity"
|
|
||||||
android:screenOrientation="portrait"
|
|
||||||
android:exported="false" />
|
|
||||||
<activity
|
|
||||||
android:name=".ui.activity.ResultListActivity"
|
|
||||||
android:screenOrientation="portrait"
|
|
||||||
android:exported="false" />
|
|
||||||
<activity
|
|
||||||
android:name=".ui.activity.CategoryListActivity"
|
|
||||||
android:screenOrientation="portrait"
|
|
||||||
android:exported="false" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.A_PlayActivity"
|
android:name=".ui.activity.A_PlayActivity"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
@ -43,20 +32,12 @@
|
|||||||
android:name=".ui.activity.A_SettingActivity"
|
android:name=".ui.activity.A_SettingActivity"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<activity
|
|
||||||
android:name=".ui.activity.PlayActivity"
|
|
||||||
android:exported="false"
|
|
||||||
android:screenOrientation="portrait" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.A_HomeActivity"
|
android:name=".ui.activity.A_HomeActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
|
||||||
android:name=".ui.activity.HomeActivity"
|
|
||||||
android:screenOrientation="portrait"
|
|
||||||
android:exported="false">
|
|
||||||
|
|
||||||
</activity>
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.A_SplashActivity"
|
android:name=".ui.activity.A_SplashActivity"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
@ -68,25 +49,25 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<service
|
<!-- <service-->
|
||||||
android:name=".media3.PlaybackService"
|
<!-- android:name=".media3.PlaybackService"-->
|
||||||
android:exported="true"
|
<!-- android:exported="true"-->
|
||||||
android:foregroundServiceType="mediaPlayback">
|
<!-- android:foregroundServiceType="mediaPlayback">-->
|
||||||
<intent-filter>
|
<!-- <intent-filter>-->
|
||||||
<action android:name="androidx.media3.session.MediaSessionService" />
|
<!-- <action android:name="androidx.media3.session.MediaSessionService" />-->
|
||||||
</intent-filter>
|
<!-- </intent-filter>-->
|
||||||
</service>
|
<!-- </service>-->
|
||||||
|
|
||||||
<service
|
<!-- <service-->
|
||||||
android:name=".media3.MyDownloadService"
|
<!-- android:name=".media3.MyDownloadService"-->
|
||||||
android:exported="false"
|
<!-- android:exported="false"-->
|
||||||
android:foregroundServiceType="dataSync"
|
<!-- android:foregroundServiceType="dataSync"-->
|
||||||
tools:ignore="ForegroundServicePermission">
|
<!-- tools:ignore="ForegroundServicePermission">-->
|
||||||
<intent-filter>
|
<!-- <intent-filter>-->
|
||||||
<action android:name="androidx.media3.exoplayer.downloadService.action.RESTART" />
|
<!-- <action android:name="androidx.media3.exoplayer.downloadService.action.RESTART" />-->
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<!-- <category android:name="android.intent.category.DEFAULT" />-->
|
||||||
</intent-filter>
|
<!-- </intent-filter>-->
|
||||||
</service>
|
<!-- </service>-->
|
||||||
<service
|
<service
|
||||||
android:name=".service.MusicPlayerForegroundService"
|
android:name=".service.MusicPlayerForegroundService"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
|
|||||||
@ -3,16 +3,6 @@ package com.hi.music.player;
|
|||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
|
|
||||||
import com.hi.music.player.api.MediaControllerStatusListener;
|
|
||||||
import com.hi.music.player.firebase.RemoteConfigJava;
|
|
||||||
import com.hi.music.player.firebase.Sp;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.media3.MyMediaControllerManager;
|
|
||||||
import com.hi.music.player.objectbox.ObjectBoxManager;
|
|
||||||
|
|
||||||
public class MusicApplication extends Application {
|
public class MusicApplication extends Application {
|
||||||
|
|
||||||
public static Context myApplication;
|
public static Context myApplication;
|
||||||
@ -30,20 +20,20 @@ public class MusicApplication extends Application {
|
|||||||
return visitorData;
|
return visitorData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
myApplication = this;
|
myApplication = this;
|
||||||
Sp.init(this);
|
// Sp.init(this);
|
||||||
RemoteConfigJava.getInstance().init(this);
|
// RemoteConfigJava.getInstance().init(this);
|
||||||
ObjectBoxManager.init(this);
|
// ObjectBoxManager.init(this);
|
||||||
MyMediaControllerManager.getInstance().init(new MediaControllerStatusListener() {
|
// MyMediaControllerManager.getInstance().init(new MediaControllerStatusListener() {
|
||||||
@Override
|
// @Override
|
||||||
public void onMediaControllerComplete(boolean isOk) {
|
// public void onMediaControllerComplete(boolean isOk) {
|
||||||
CommonUtils.LogMsg("=-----mediaController+" + isOk);
|
// CommonUtils.LogMsg("=-----mediaController+" + isOk);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -101,7 +101,7 @@ public class A_ImportFragmentAdapter extends RecyclerView.Adapter<A_ImportFragme
|
|||||||
time = itemView.findViewById(R.id.time);
|
time = itemView.findViewById(R.id.time);
|
||||||
|
|
||||||
option.setOnClickListener(v -> {
|
option.setOnClickListener(v -> {
|
||||||
int position = getBindingAdapterPosition();
|
int position = getAdapterPosition();
|
||||||
if (position != RecyclerView.NO_POSITION && onOptionClickListener != null) {
|
if (position != RecyclerView.NO_POSITION && onOptionClickListener != null) {
|
||||||
onOptionClickListener.onOptionClick(position, audioItem.getFile(), option);
|
onOptionClickListener.onOptionClick(position, audioItem.getFile(), option);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,78 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.databinding.ItemCategoryBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseCategory;
|
|
||||||
|
|
||||||
public class AdapterCategory extends BaseAdapter<ResponseCategory, ItemCategoryBinding>{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemCategoryBinding getViewBinding(ViewGroup parent) {
|
|
||||||
return ItemCategoryBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
|
|
||||||
int itemViewType = getItemViewType(position);
|
|
||||||
if (itemViewType == TYPE_ITEM) {
|
|
||||||
VHolder<ItemCategoryBinding> itemHolder = (VHolder<ItemCategoryBinding>) holder;
|
|
||||||
ItemCategoryBinding vb = itemHolder.getVb();
|
|
||||||
ResponseCategory responseCategory = data.get(position);
|
|
||||||
String pageType = responseCategory.getPageType();
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
.load(responseCategory.getCovert())
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.into(vb.header);
|
|
||||||
vb.tvTitle.setText(responseCategory.getTwoTitle());
|
|
||||||
vb.tvSubtitle.setText(responseCategory.getTwoSubtitle());
|
|
||||||
CommonUtils.LogMsg("title="+responseCategory.getTwoTitle()+"----------pageType="+pageType
|
|
||||||
+"---browserId="+responseCategory.getBrowseId()+"---videoId="+responseCategory.getVideoId()+"---playListId="+responseCategory.getPlayListId());
|
|
||||||
if(pageType == null){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// if(pageType.equals(MyValue.PAGE_TYPE_MV)||pageType.equals(MyValue.PAGE_TYPE_MV_LIST)){
|
|
||||||
// ViewGroup.LayoutParams layoutParams = vb.header.getLayoutParams();
|
|
||||||
// layoutParams.width = CommonUtils.dpToPx(280);
|
|
||||||
// vb.header.setLayoutParams(layoutParams);
|
|
||||||
// vb.header.setBackgroundResource(R.drawable.bg_black_13);
|
|
||||||
//
|
|
||||||
// }else {
|
|
||||||
// ViewGroup.LayoutParams layoutParams = vb.header.getLayoutParams();
|
|
||||||
// layoutParams.width = CommonUtils.dpToPx(170);
|
|
||||||
// vb.header.setLayoutParams(layoutParams);
|
|
||||||
// vb.header.setBackground(null);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
vb.header.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (homeItemClickListener != null) {
|
|
||||||
homeItemClickListener.onClickItemCategory(responseCategory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.api.onImageColorListener;
|
|
||||||
import com.hi.music.player.databinding.ItemCategoryListBinding;
|
|
||||||
import com.hi.music.player.databinding.ItemSingerBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseCategoryListChild;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
|
|
||||||
public class AdapterCategoryList extends BaseAdapter<ResponsePlayListInfo, ItemCategoryListBinding> {
|
|
||||||
|
|
||||||
|
|
||||||
private String mPageType;
|
|
||||||
|
|
||||||
public void setPageType(String mPageType) {
|
|
||||||
this.mPageType = mPageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemCategoryListBinding getViewBinding(ViewGroup parent) {
|
|
||||||
return ItemCategoryListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
VHolder<ItemCategoryListBinding> itemHolder = (VHolder<ItemCategoryListBinding>) holder;
|
|
||||||
ResponsePlayListInfo child = data.get(position);
|
|
||||||
|
|
||||||
ItemCategoryListBinding vb = itemHolder.getVb();
|
|
||||||
vb.tvSongName.setText(child.getSongTitle());
|
|
||||||
vb.tvDuration.setText(child.getDuration());
|
|
||||||
String singerName = child.getSingerName();
|
|
||||||
String describe = child.getDescribe();
|
|
||||||
|
|
||||||
switch (mPageType){
|
|
||||||
case MyValue.PAGE_TYPE_ALBUM:
|
|
||||||
vb.tvSingerName.setText(describe);
|
|
||||||
vb.imCard.setVisibility(View.GONE);
|
|
||||||
vb.tvPosition.setVisibility(View.VISIBLE);
|
|
||||||
vb.tvPosition.setText(String.valueOf(position+1));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
vb.tvSingerName.setText(singerName);
|
|
||||||
|
|
||||||
vb.imCard.setVisibility(View.VISIBLE);
|
|
||||||
vb.tvPosition.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
.load(child.getSmallCovert())
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
CommonUtils.LogMsg(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(vb.image);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
vb.getRoot().setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
homeItemClickListener.onClickItemCategoryList(child, itemHolder.getAbsoluteAdapterPosition());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if(position == data.size() - 1){
|
|
||||||
vb.place.setVisibility(View.VISIBLE);
|
|
||||||
}else {
|
|
||||||
vb.place.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.media3.exoplayer.offline.Download;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.databinding.ItemLikeSongBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.BoxDownloadSong;
|
|
||||||
import com.hi.music.player.javabean.BoxLikeSong;
|
|
||||||
|
|
||||||
public class AdapterDownloadSong extends BaseAdapter<Download, ItemLikeSongBinding> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemLikeSongBinding getViewBinding(ViewGroup parent) {
|
|
||||||
return ItemLikeSongBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
VHolder<ItemLikeSongBinding> itemHolder = (VHolder<ItemLikeSongBinding>) holder;
|
|
||||||
ItemLikeSongBinding vb = itemHolder.getVb();
|
|
||||||
Download download = data.get(position);
|
|
||||||
BoxDownloadSong boxDownloadSong = CommonUtils.downloadToBean(download);
|
|
||||||
|
|
||||||
if (position == data.size()-1){
|
|
||||||
vb.place.setVisibility(View.VISIBLE);
|
|
||||||
}else {
|
|
||||||
vb.place.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
vb.layoutDownload.setVisibility(View.GONE);
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
.load(boxDownloadSong.getCovert())
|
|
||||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(4))))
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
CommonUtils.LogMsg(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(vb.imCovert);
|
|
||||||
vb.tvTitle.setText(boxDownloadSong.getSongName());
|
|
||||||
vb.tvSingerName.setText(boxDownloadSong.getSingerName());
|
|
||||||
|
|
||||||
vb.getRoot().setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if(homeItemClickListener!= null){
|
|
||||||
int absoluteAdapterPosition = itemHolder.getAbsoluteAdapterPosition();
|
|
||||||
homeItemClickListener.onClickDownloadSong(download,absoluteAdapterPosition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.GridLayoutManager;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.databinding.ItemFooterLoadingBinding;
|
|
||||||
import com.hi.music.player.databinding.ItemHomeBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseCategory;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseHomeChild;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class AdapterHome extends BaseAdapter<ResponseHomeChild, ItemHomeBinding> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemHomeBinding getViewBinding(ViewGroup parent) {
|
|
||||||
|
|
||||||
return ItemHomeBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
int itemViewType = getItemViewType(position);
|
|
||||||
if (itemViewType == TYPE_ITEM) {
|
|
||||||
VHolder<ItemHomeBinding> itemHolder = (VHolder<ItemHomeBinding>) holder;
|
|
||||||
ItemHomeBinding vb = itemHolder.getVb();
|
|
||||||
ResponseHomeChild responseHomeChild = data.get(position);
|
|
||||||
vb.headTitle.setText(responseHomeChild.getHeaderTitle());
|
|
||||||
CommonUtils.LogMsg("position="+position+"-----------headTitle-=" + responseHomeChild.getHeaderTitle());
|
|
||||||
List<ResponseSingle> singleList = responseHomeChild.getSingleList();
|
|
||||||
List<ResponseCategory> categoryList = responseHomeChild.getCategoryList();
|
|
||||||
|
|
||||||
if (singleList != null && singleList.size() > 0) {
|
|
||||||
vb.recyclerSinger.setVisibility(View.VISIBLE);
|
|
||||||
AdapterSinger adapterSinger = new AdapterSinger();
|
|
||||||
adapterSinger.setHomeItemClickListener(homeItemClickListener);
|
|
||||||
adapterSinger.addData(singleList);
|
|
||||||
vb.recyclerSinger.setLayoutManager(new GridLayoutManager(MusicApplication.myApplication, 4, RecyclerView.HORIZONTAL, false));
|
|
||||||
vb.recyclerSinger.setAdapter(adapterSinger);
|
|
||||||
} else {
|
|
||||||
vb.recyclerSinger.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (categoryList != null && categoryList.size() > 0) {
|
|
||||||
vb.recyclerCategory.setVisibility(View.VISIBLE);
|
|
||||||
AdapterCategory adapterCategory = new AdapterCategory();
|
|
||||||
adapterCategory.setHomeItemClickListener(homeItemClickListener);
|
|
||||||
adapterCategory.addData(categoryList);
|
|
||||||
vb.recyclerCategory.setLayoutManager(new LinearLayoutManager(MusicApplication.myApplication, RecyclerView.HORIZONTAL, false));
|
|
||||||
vb.recyclerCategory.setAdapter(adapterCategory);
|
|
||||||
} else {
|
|
||||||
vb.recyclerCategory.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(position == data.size() - 1){
|
|
||||||
vb.place.setVisibility(View.VISIBLE);
|
|
||||||
}else {
|
|
||||||
vb.place.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
VHolder<ItemFooterLoadingBinding> footerHolder = (VHolder<ItemFooterLoadingBinding>) holder;
|
|
||||||
FrameLayout root = footerHolder.getVb().getRoot();
|
|
||||||
if (isLoadingAdded) {
|
|
||||||
root.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
root.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,215 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.util.Pair;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.lifecycle.Observer;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.exoplayer.offline.Download;
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadRequest;
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadService;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.api.onCheckDownload;
|
|
||||||
import com.hi.music.player.databinding.ItemLikeSongBinding;
|
|
||||||
import com.hi.music.player.databinding.ItemSingerBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.BoxDownloadSong;
|
|
||||||
import com.hi.music.player.javabean.BoxLikeSong;
|
|
||||||
import com.hi.music.player.javabean.CustomerDownload;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
import com.hi.music.player.media3.MyDownloadService;
|
|
||||||
import com.hi.music.player.media3.MyMediaControllerManager;
|
|
||||||
import com.hi.music.player.network.JsonHelper;
|
|
||||||
import com.hi.music.player.network.RetrofitManager;
|
|
||||||
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
public class AdapterLikeSong extends BaseAdapter<BoxLikeSong, ItemLikeSongBinding> {
|
|
||||||
|
|
||||||
private VMApplication vmApplication;
|
|
||||||
|
|
||||||
private List<Pair<Boolean, String>> status = new ArrayList<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemLikeSongBinding getViewBinding(ViewGroup parent) {
|
|
||||||
return ItemLikeSongBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public AdapterLikeSong(Context mContext, VMApplication vm) {
|
|
||||||
super(mContext);
|
|
||||||
vmApplication = vm;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateDownloadStatus(boolean isSuccess, int position, String videoId) {
|
|
||||||
status.add(new Pair<>(isSuccess, videoId));
|
|
||||||
notifyItemChanged(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
VHolder<ItemLikeSongBinding> itemHolder = (VHolder<ItemLikeSongBinding>) holder;
|
|
||||||
ItemLikeSongBinding vb = itemHolder.getVb();
|
|
||||||
BoxLikeSong boxLikeSong = data.get(position);
|
|
||||||
String videoId = boxLikeSong.getVideoId();
|
|
||||||
|
|
||||||
if (position == data.size()-1){
|
|
||||||
vb.place.setVisibility(View.VISIBLE);
|
|
||||||
}else {
|
|
||||||
vb.place.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for(Pair<Boolean,String> pair:status){
|
|
||||||
if(pair.second.equals(videoId)){
|
|
||||||
vb.imDownload.setSelected(pair.first);
|
|
||||||
vb.imDownload.setVisibility(View.VISIBLE);
|
|
||||||
vb.downloadPb.setVisibility(View.GONE);
|
|
||||||
CommonUtils.LogMsg("--------------------状态更新");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MyDownloadService.queryIsDownload(videoId, new onCheckDownload() {
|
|
||||||
@Override
|
|
||||||
public void onHasDownload(CustomerDownload customerDownload) {
|
|
||||||
boolean download = customerDownload.isDownload();
|
|
||||||
if (download) {
|
|
||||||
vb.imDownload.setSelected(true);
|
|
||||||
} else {
|
|
||||||
vb.imDownload.setSelected(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
vb.layoutDownload.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (vb.imDownload.isSelected()) {
|
|
||||||
//已经下载
|
|
||||||
Toast.makeText(mContext,mContext.getText(R.string.text_has_downloaded),Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vb.imDownload.setVisibility(View.GONE);
|
|
||||||
vb.downloadPb.setVisibility(View.VISIBLE);
|
|
||||||
RetrofitManager.getInstance().getPlayUrl(videoId, new com.hi.music.player.api.RequestListener<ResponseBody>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFail(String errorMsg) {
|
|
||||||
CommonUtils.LogMsg("-------------onFail");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess(JSONObject data) {
|
|
||||||
// JSONObject jsonObject = CommonUtils.toJsonObject(data);
|
|
||||||
if (data != null) {
|
|
||||||
ResponsePlayUrl responsePlayUrl = JsonHelper.ResolvePlayUrlJson(data);
|
|
||||||
if (responsePlayUrl == null) {
|
|
||||||
// TODO: 2024/9/27
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String videoUrlMedium = responsePlayUrl.getVideoUrlMedium();
|
|
||||||
|
|
||||||
BoxDownloadSong downloadSong = new BoxDownloadSong();
|
|
||||||
downloadSong.setVideoId(videoId);
|
|
||||||
downloadSong.setCovert(String.valueOf(boxLikeSong.getCovert()));
|
|
||||||
downloadSong.setSongName((String) boxLikeSong.getSongName());
|
|
||||||
downloadSong.setSingerName((String) boxLikeSong.getSingerName());
|
|
||||||
downloadSong.setDuration((String) boxLikeSong.getDuration());
|
|
||||||
downloadSong.setDurationMs(boxLikeSong.getDurationMs());
|
|
||||||
downloadSong.setVideoUrl(videoUrlMedium);
|
|
||||||
Gson gson = new Gson();
|
|
||||||
String info = gson.toJson(downloadSong);
|
|
||||||
byte[] bytes = info.getBytes(StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
DownloadRequest downloadRequest = new DownloadRequest.Builder(videoId, Uri.parse(videoUrlMedium))
|
|
||||||
.setMimeType("video/mp4")
|
|
||||||
.setData(bytes)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
|
|
||||||
DownloadService.sendAddDownload(
|
|
||||||
mContext,
|
|
||||||
MyDownloadService.class, // 上面定义的下载服务类
|
|
||||||
downloadRequest,
|
|
||||||
true // 是否在前台运行
|
|
||||||
);
|
|
||||||
if (homeItemClickListener != null) {
|
|
||||||
homeItemClickListener.onDownloadSong(videoId, itemHolder.getAbsoluteAdapterPosition());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
.load(boxLikeSong.getCovert())
|
|
||||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(4))))
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
CommonUtils.LogMsg(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(vb.imCovert);
|
|
||||||
vb.tvTitle.setText(boxLikeSong.getSongName());
|
|
||||||
vb.tvSingerName.setText(boxLikeSong.getSingerName());
|
|
||||||
|
|
||||||
vb.getRoot().setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (homeItemClickListener != null) {
|
|
||||||
int absoluteAdapterPosition = itemHolder.getAbsoluteAdapterPosition();
|
|
||||||
homeItemClickListener.onClickLikeSong(boxLikeSong, absoluteAdapterPosition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,118 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import static androidx.media3.session.legacy.MediaControllerCompat.getMediaController;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.media3.common.MediaItem;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.api.MediaControllerListener;
|
|
||||||
import com.hi.music.player.databinding.ItemPlayListBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
|
||||||
import com.hi.music.player.media3.MyMediaControllerManager;
|
|
||||||
|
|
||||||
public class AdapterPlayList extends BaseAdapter<ResponsePlayListInfo, ItemPlayListBinding> {
|
|
||||||
|
|
||||||
private String mCurVideId;
|
|
||||||
|
|
||||||
private String lastVideId;
|
|
||||||
|
|
||||||
// private int curMusicPos = 0;
|
|
||||||
private MyMediaControllerManager instance = MyMediaControllerManager.getInstance();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemPlayListBinding getViewBinding(ViewGroup parent) {
|
|
||||||
return ItemPlayListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCurVideId(String curVideId) {
|
|
||||||
lastVideId = mCurVideId;
|
|
||||||
this.mCurVideId = curVideId;
|
|
||||||
for (int i = 0; i < data.size(); i++) {
|
|
||||||
ResponsePlayListInfo listInfo = data.get(i);
|
|
||||||
if (listInfo.getVideoId().equals(curVideId)) {
|
|
||||||
notifyItemChanged(i);
|
|
||||||
}
|
|
||||||
if (listInfo.getVideoId().equals(lastVideId)) {
|
|
||||||
notifyItemChanged(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void updateCurMusicAnimation() {
|
|
||||||
int curIndex = instance.getCurIndex();
|
|
||||||
CommonUtils.LogMsg("--curIndex=" + curIndex);
|
|
||||||
notifyItemChanged(curIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
ResponsePlayListInfo listInfo = data.get(position);
|
|
||||||
VHolder<ItemPlayListBinding> itemHolder = (VHolder<ItemPlayListBinding>) holder;
|
|
||||||
ItemPlayListBinding vb = itemHolder.getVb();
|
|
||||||
|
|
||||||
vb.songName.setText(listInfo.getSongTitle());
|
|
||||||
String singerName = listInfo.getSingerName();
|
|
||||||
String describe = listInfo.getDescribe();
|
|
||||||
if (singerName != null && !singerName.isEmpty()) {
|
|
||||||
vb.artistName.setText(singerName);
|
|
||||||
} else if (describe != null && !describe.isEmpty()) {
|
|
||||||
vb.artistName.setText(describe);
|
|
||||||
}
|
|
||||||
|
|
||||||
String covert;
|
|
||||||
String small = listInfo.getSmallCovert();
|
|
||||||
String covert1 = listInfo.getCovert();
|
|
||||||
if (small == null || small.isEmpty()) {
|
|
||||||
covert = covert1;
|
|
||||||
} else {
|
|
||||||
covert = small;
|
|
||||||
}
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
// .apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(10))))
|
|
||||||
.load(covert)
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.into(vb.imCovert);
|
|
||||||
|
|
||||||
MediaItem currentMediaItem = instance.getCurMediaItem();
|
|
||||||
if (currentMediaItem != null && currentMediaItem.mediaId.equals(listInfo.getVideoId())) {
|
|
||||||
vb.viewPlaying.setVisibility(View.VISIBLE);
|
|
||||||
vb.itemLayout.setBackgroundColor(CommonUtils.getMyColor(R.color.cur_play_music));
|
|
||||||
if (instance.getIsPlaying()) {
|
|
||||||
vb.viewPlaying.startAnimating();
|
|
||||||
lastVideId = listInfo.getVideoId();
|
|
||||||
CommonUtils.LogMsg("-------playAnimation " + itemHolder.getAbsoluteAdapterPosition());
|
|
||||||
} else {
|
|
||||||
vb.viewPlaying.pauseAnimating();
|
|
||||||
CommonUtils.LogMsg("-------pauseAnimation " + itemHolder.getAbsoluteAdapterPosition());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
vb.viewPlaying.setVisibility(View.GONE);
|
|
||||||
vb.itemLayout.setBackgroundColor(CommonUtils.getMyColor(R.color.color_transparent));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
vb.itemLayout.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
CommonUtils.LogMsg("-------onClick curMusicPos=" + itemHolder.getAbsoluteAdapterPosition());
|
|
||||||
setCurVideId(listInfo.getVideoId());
|
|
||||||
instance.playPositionMusic(itemHolder.getAbsoluteAdapterPosition());
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,72 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.databinding.ItemResultBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.ItemDecoration;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseResultList;
|
|
||||||
import com.hi.music.player.ui.activity.PlayActivity;
|
|
||||||
|
|
||||||
public class AdapterResult extends BaseAdapter<ResponseResultList, ItemResultBinding>{
|
|
||||||
public AdapterResult(Context mContext) {
|
|
||||||
super(mContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemResultBinding getViewBinding(ViewGroup parent) {
|
|
||||||
return ItemResultBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
ResponseResultList resultList = data.get(position);
|
|
||||||
|
|
||||||
VHolder<ItemResultBinding> itemHolder = (VHolder<ItemResultBinding>) holder;
|
|
||||||
ItemResultBinding vb = itemHolder.getVb();
|
|
||||||
String headerTitle = resultList.getHeaderTitle();
|
|
||||||
vb.tvHeaderTitle.setText(headerTitle);
|
|
||||||
|
|
||||||
CommonUtils.LogMsg("---------headerTitle="+headerTitle);
|
|
||||||
|
|
||||||
ItemDecoration itemDecoration ;
|
|
||||||
|
|
||||||
if(position == 0){
|
|
||||||
itemDecoration = new ItemDecoration(10,0,0);
|
|
||||||
AdapterResultListSong adapterResultListSong = new AdapterResultListSong();
|
|
||||||
adapterResultListSong.setData(resultList.getChildList());
|
|
||||||
vb.listChild.setAdapter(adapterResultListSong);
|
|
||||||
vb.listChild.setLayoutManager(new LinearLayoutManager(mContext));
|
|
||||||
if(homeItemClickListener!= null)
|
|
||||||
adapterResultListSong.setHomeItemClickListener(homeItemClickListener);
|
|
||||||
}else {
|
|
||||||
itemDecoration = new ItemDecoration(0,10,0);
|
|
||||||
AdapterResultListAlbum adapterResultListAlbum = new AdapterResultListAlbum();
|
|
||||||
adapterResultListAlbum.setData(resultList.getChildList());
|
|
||||||
vb.listChild.setAdapter(adapterResultListAlbum);
|
|
||||||
vb.listChild.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL,false));
|
|
||||||
if(homeItemClickListener!= null)
|
|
||||||
adapterResultListAlbum.setHomeItemClickListener(homeItemClickListener);
|
|
||||||
}
|
|
||||||
// vb.listChild.addItemDecoration(itemDecoration);
|
|
||||||
|
|
||||||
if(position == data.size() - 1){
|
|
||||||
vb.place.setVisibility(View.VISIBLE);
|
|
||||||
}else {
|
|
||||||
vb.place.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.databinding.ItemResultListAlbumBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseResultListChild;
|
|
||||||
|
|
||||||
public class AdapterResultListAlbum extends BaseAdapter<ResponseResultListChild, ItemResultListAlbumBinding>{
|
|
||||||
@Override
|
|
||||||
protected ItemResultListAlbumBinding getViewBinding(ViewGroup parent) {
|
|
||||||
return ItemResultListAlbumBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
ResponseResultListChild listChild = data.get(position);
|
|
||||||
|
|
||||||
|
|
||||||
VHolder<ItemResultListAlbumBinding> itemHolder = (VHolder<ItemResultListAlbumBinding>) holder;
|
|
||||||
ItemResultListAlbumBinding vb = itemHolder.getVb();
|
|
||||||
if(position == data.size()-1){
|
|
||||||
vb.view.setVisibility(View.VISIBLE);
|
|
||||||
}else {
|
|
||||||
vb.view.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
.load(listChild.getThumbnail())
|
|
||||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(4))))
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
CommonUtils.LogMsg(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(vb.header);
|
|
||||||
vb.tvTitle.setText(listChild.getSongName());
|
|
||||||
vb.tvSubtitle.setText(listChild.getSubTitle());
|
|
||||||
vb.header.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if(homeItemClickListener != null){
|
|
||||||
int absoluteAdapterPosition = itemHolder.getAbsoluteAdapterPosition();
|
|
||||||
String videoId = listChild.getVideoId();
|
|
||||||
String browserId = listChild.getBrowserId();
|
|
||||||
homeItemClickListener.onClickResultSong(listChild,absoluteAdapterPosition);
|
|
||||||
// if(videoId == null||videoId.isEmpty()){
|
|
||||||
// homeItemClickListener.onClickResultAlbum(listChild,absoluteAdapterPosition);
|
|
||||||
// }else if(browserId!= null&&!browserId.isEmpty()){
|
|
||||||
// homeItemClickListener.onClickResultSong(listChild,absoluteAdapterPosition);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
CommonUtils.LogMsg("-------Album getBrowserId="+listChild.getBrowserId()+"---getPlayListId= "+listChild.getPlayListId()+"---getVideoId="+listChild.getVideoId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.databinding.ItemResultListSongBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseResultListChild;
|
|
||||||
|
|
||||||
public class AdapterResultListSong extends BaseAdapter<ResponseResultListChild, ItemResultListSongBinding> {
|
|
||||||
@Override
|
|
||||||
protected ItemResultListSongBinding getViewBinding(ViewGroup parent) {
|
|
||||||
return ItemResultListSongBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
ResponseResultListChild listChild = data.get(position);
|
|
||||||
|
|
||||||
VHolder<ItemResultListSongBinding> itemHolder = (VHolder<ItemResultListSongBinding>) holder;
|
|
||||||
ItemResultListSongBinding vb = itemHolder.getVb();
|
|
||||||
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
.load(listChild.getThumbnail())
|
|
||||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(4))))
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
CommonUtils.LogMsg(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(vb.imCovert);
|
|
||||||
vb.tvSongName.setText(listChild.getSongName());
|
|
||||||
String playCount = listChild.getPlayCount();
|
|
||||||
String subTitle = listChild.getSubTitle();
|
|
||||||
if (playCount == null){
|
|
||||||
vb.tvSubtitle.setText(subTitle);
|
|
||||||
}else {
|
|
||||||
String s = subTitle + " • " + playCount;
|
|
||||||
vb.tvSubtitle.setText(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vb.getRoot().setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (homeItemClickListener != null) {
|
|
||||||
int absoluteAdapterPosition = itemHolder.getAbsoluteAdapterPosition();
|
|
||||||
String videoId = listChild.getVideoId();
|
|
||||||
String browserId = listChild.getBrowserId();
|
|
||||||
homeItemClickListener.onClickResultSong(listChild, absoluteAdapterPosition);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
CommonUtils.LogMsg("-------Song getBrowserId=" + listChild.getBrowserId() + "---getPlayListId= " + listChild.getPlayListId() + "---getVideoId=" + listChild.getVideoId());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.databinding.ItemSearchBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseSearch;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSearchChild;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class AdapterSearch extends BaseAdapter<ResponseSearch, ItemSearchBinding> {
|
|
||||||
@Override
|
|
||||||
protected ItemSearchBinding getViewBinding(ViewGroup parent) {
|
|
||||||
return ItemSearchBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
ResponseSearch responseSearch = data.get(position);
|
|
||||||
|
|
||||||
VHolder<ItemSearchBinding> itemHolder = (VHolder<ItemSearchBinding>) holder;
|
|
||||||
ItemSearchBinding vb = itemHolder.getVb();
|
|
||||||
|
|
||||||
vb.tvHeaderTitle.setText(responseSearch.getHeaderTitle());
|
|
||||||
|
|
||||||
String beastSongTCovert = responseSearch.getBeastSongTCovert();
|
|
||||||
if (beastSongTCovert != null && !beastSongTCovert.isEmpty()) {
|
|
||||||
vb.layoutBest.setVisibility(View.VISIBLE);
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.load(beastSongTCovert)
|
|
||||||
.transform(new CircleCrop())
|
|
||||||
.into(vb.imBestCovert);
|
|
||||||
vb.tvBestTitle.setText(responseSearch.getBeastSongTitle());
|
|
||||||
vb.tvBestSubtitle.setText(responseSearch.getBeastSongDescribe());
|
|
||||||
vb.layout.setBackground(ContextCompat.getDrawable(MusicApplication.myApplication, R.drawable.bg_best_bg));
|
|
||||||
vb.layout.setPadding(CommonUtils.dpToPx(6), CommonUtils.dpToPx(10), 0, 0);
|
|
||||||
vb.tvPlay.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (homeItemClickListener != null) {
|
|
||||||
homeItemClickListener.onClickSearchResultBest(responseSearch);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
vb.layoutBest.setVisibility(View.GONE);
|
|
||||||
vb.layout.setBackground(null);
|
|
||||||
vb.layout.setPadding(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<ResponseSearchChild> list = responseSearch.getList();
|
|
||||||
|
|
||||||
if(list!= null&&list.size()>0){
|
|
||||||
AdapterSearchChild adapterSearchChild = new AdapterSearchChild();
|
|
||||||
adapterSearchChild.setData(list);
|
|
||||||
vb.list.setAdapter(adapterSearchChild);
|
|
||||||
if (homeItemClickListener != null)
|
|
||||||
adapterSearchChild.setHomeItemClickListener(homeItemClickListener);
|
|
||||||
vb.list.setLayoutManager(new LinearLayoutManager(MusicApplication.myApplication));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(position == data.size() - 1){
|
|
||||||
vb.place.setVisibility(View.VISIBLE);
|
|
||||||
}else {
|
|
||||||
vb.place.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.databinding.ItemSearchBinding;
|
|
||||||
import com.hi.music.player.databinding.ItemSearchChildBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseSearch;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSearchChild;
|
|
||||||
|
|
||||||
public class AdapterSearchChild extends BaseAdapter<ResponseSearchChild, ItemSearchChildBinding> {
|
|
||||||
@Override
|
|
||||||
protected ItemSearchChildBinding getViewBinding(ViewGroup parent) {
|
|
||||||
return ItemSearchChildBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
ResponseSearchChild responseSearchChild = data.get(position);
|
|
||||||
VHolder<ItemSearchChildBinding> itemHolder = (VHolder<ItemSearchChildBinding>) holder;
|
|
||||||
ItemSearchChildBinding vb = itemHolder.getVb();
|
|
||||||
|
|
||||||
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(13))))
|
|
||||||
.load(responseSearchChild.getSongCovert())
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
CommonUtils.LogMsg(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(vb.imCovert);
|
|
||||||
|
|
||||||
vb.tvTitle.setText(responseSearchChild.getSongTitle());
|
|
||||||
vb.tvSubtitle.setText(responseSearchChild.getSongDescribe());
|
|
||||||
vb.getRoot().setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (homeItemClickListener != null) {
|
|
||||||
homeItemClickListener.onClickSearchResult(responseSearchChild);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,77 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.databinding.ItemSingerBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
|
|
||||||
public class AdapterSinger extends BaseAdapter<ResponseSingle, ItemSingerBinding> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemSingerBinding getViewBinding(ViewGroup parent) {
|
|
||||||
return ItemSingerBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
int itemViewType = getItemViewType(position);
|
|
||||||
if (itemViewType == TYPE_ITEM) {
|
|
||||||
VHolder<ItemSingerBinding> itemHolder = (VHolder<ItemSingerBinding>) holder;
|
|
||||||
ItemSingerBinding vb = itemHolder.getVb();
|
|
||||||
ResponseSingle responseSingle = data.get(position);
|
|
||||||
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
.load(responseSingle.getSingerHead())
|
|
||||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(4))))
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
CommonUtils.LogMsg(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(vb.header);
|
|
||||||
vb.tvSingerName.setText(responseSingle.getSingerName());
|
|
||||||
vb.tvSongName.setText(responseSingle.getSongTitle());
|
|
||||||
// vb.tvDescribe.setText(responseSingle.getDescription());
|
|
||||||
vb.getRoot().setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (homeItemClickListener != null) {
|
|
||||||
homeItemClickListener.onClickItemSinger(responseSingle);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.hi.music.player.databinding.ItemSuggestionBinding;
|
|
||||||
|
|
||||||
public class AdapterSuggestion extends BaseAdapter<String, ItemSuggestionBinding> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ItemSuggestionBinding getViewBinding(ViewGroup parent) {
|
|
||||||
return ItemSuggestionBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
|
|
||||||
VHolder<ItemSuggestionBinding> itemHolder = (VHolder<ItemSuggestionBinding>) holder;
|
|
||||||
ItemSuggestionBinding vb = itemHolder.getVb();
|
|
||||||
String text = data.get(position);
|
|
||||||
vb.tvSuggestion.setText(text);
|
|
||||||
vb.relayout.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if(homeItemClickListener!= null){
|
|
||||||
homeItemClickListener.onClickItemSuggestion(true,text);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
vb.imFillIn.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if(homeItemClickListener!= null){
|
|
||||||
homeItemClickListener.onClickItemSuggestion(false,text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,127 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import androidx.viewbinding.ViewBinding;
|
|
||||||
|
|
||||||
import com.hi.music.player.api.HomeItemClickListener;
|
|
||||||
import com.hi.music.player.databinding.ItemFooterLoadingBinding;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseCategory;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
abstract public class BaseAdapter<K, T extends ViewBinding> extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
|
||||||
|
|
||||||
protected List<K> data = new ArrayList<>();
|
|
||||||
|
|
||||||
protected Context mContext;
|
|
||||||
|
|
||||||
protected static final int TYPE_ITEM = 0;
|
|
||||||
protected static final int TYPE_FOOTER = 1;
|
|
||||||
protected boolean isLoadingAdded = false;
|
|
||||||
|
|
||||||
public BaseAdapter() {
|
|
||||||
|
|
||||||
}
|
|
||||||
public BaseAdapter(Context mContext) {
|
|
||||||
this.mContext = mContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HomeItemClickListener homeItemClickListener;
|
|
||||||
|
|
||||||
|
|
||||||
public void setHomeItemClickListener(HomeItemClickListener homeItemClickListener) {
|
|
||||||
this.homeItemClickListener = homeItemClickListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isLoadingAdded() {
|
|
||||||
return isLoadingAdded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addData(List<K> data) {
|
|
||||||
this.data.addAll(data);
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setData(List<K> data) {
|
|
||||||
this.data.clear();
|
|
||||||
this.data.addAll(data);
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addLoadingFooter() {
|
|
||||||
isLoadingAdded = true;
|
|
||||||
notifyItemInserted(data.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide loading footer
|
|
||||||
public void removeLoadingFooter() {
|
|
||||||
isLoadingAdded = false;
|
|
||||||
int position = data.size();
|
|
||||||
if (position > 0)
|
|
||||||
notifyItemRemoved(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
|
||||||
if (viewType == TYPE_ITEM) {
|
|
||||||
T viewBinding = getViewBinding(parent);
|
|
||||||
return new VHolder<>(viewBinding);
|
|
||||||
} else {
|
|
||||||
// Inflate footer layout
|
|
||||||
ItemFooterLoadingBinding inflate = ItemFooterLoadingBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
|
||||||
return new VHolder<>(inflate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract T getViewBinding(ViewGroup parent);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemViewType(int position) {
|
|
||||||
return (position == data.size() && isLoadingAdded) ? TYPE_FOOTER : TYPE_ITEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return data.size() + (isLoadingAdded ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class VHolder<V extends ViewBinding> extends RecyclerView.ViewHolder {
|
|
||||||
|
|
||||||
private V vb;
|
|
||||||
|
|
||||||
public V getVb() {
|
|
||||||
return vb;
|
|
||||||
}
|
|
||||||
|
|
||||||
public VHolder(@NonNull V itemView) {
|
|
||||||
super(itemView.getRoot());
|
|
||||||
vb = itemView;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class FooterHolder extends RecyclerView.ViewHolder {
|
|
||||||
|
|
||||||
private ItemFooterLoadingBinding vb;
|
|
||||||
|
|
||||||
public ItemFooterLoadingBinding getVb() {
|
|
||||||
return vb;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FooterHolder(@NonNull ItemFooterLoadingBinding itemView) {
|
|
||||||
super(itemView.getRoot());
|
|
||||||
vb = itemView;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package com.hi.music.player.adapter;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
|
||||||
|
|
||||||
import com.hi.music.player.ui.fragmnt.HomeFragment;
|
|
||||||
import com.hi.music.player.ui.fragmnt.ProfileFragment;
|
|
||||||
import com.hi.music.player.ui.fragmnt.SearchFragment;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class HomeViewPagerAdapter extends FragmentStateAdapter {
|
|
||||||
|
|
||||||
private final List<Fragment> fragments = new ArrayList<>();
|
|
||||||
|
|
||||||
public HomeViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
|
|
||||||
super(fragmentActivity);
|
|
||||||
fragments.add(new HomeFragment());
|
|
||||||
fragments.add(new SearchFragment());
|
|
||||||
fragments.add(new ProfileFragment());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public Fragment createFragment(int position) {
|
|
||||||
return fragments.get(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return fragments.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,100 +0,0 @@
|
|||||||
package com.hi.music.player.api;
|
|
||||||
|
|
||||||
import androidx.media3.exoplayer.offline.Download;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.BoxLikeSong;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseSearch;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseCategory;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseResultListChild;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSearchChild;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
|
|
||||||
public interface HomeItemClickListener {
|
|
||||||
|
|
||||||
|
|
||||||
//首页点击了单曲
|
|
||||||
default void onClickItemSinger(ResponseSingle data) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//首页点击了分类合集
|
|
||||||
default void onClickItemCategory(ResponseCategory data) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//分类合集点击了某一首歌曲
|
|
||||||
default void onClickItemCategoryList(ResponsePlayListInfo data,int musicIndex) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 点击了搜索建议
|
|
||||||
* @param isSearch true 直接搜索 false 输入搜索建议文字
|
|
||||||
* @param data
|
|
||||||
*/
|
|
||||||
default void onClickItemSuggestion(boolean isSearch,String data) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 点击搜索最佳结果第一个
|
|
||||||
* @param
|
|
||||||
*/
|
|
||||||
default void onClickSearchResultBest(ResponseSearch responseSearch){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 点击搜索结果
|
|
||||||
* @param
|
|
||||||
*/
|
|
||||||
default void onClickSearchResult(ResponseSearchChild responseSearchChild){
|
|
||||||
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 搜索结果详情页面点击单曲
|
|
||||||
* @param child
|
|
||||||
* @param index
|
|
||||||
*/
|
|
||||||
default void onClickResultSong(ResponseResultListChild child,int index){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
default void onClickResultAlbum(ResponseResultListChild child,int index){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 点击喜爱歌曲列表的某一首歌曲
|
|
||||||
* @param boxLikeSong
|
|
||||||
* @param index
|
|
||||||
*/
|
|
||||||
default void onClickLikeSong(BoxLikeSong boxLikeSong, int index){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始下载歌曲
|
|
||||||
* @param boxLikeSong
|
|
||||||
* @param index
|
|
||||||
*/
|
|
||||||
default void onDownloadSong(String videoId, int index){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 点击下载歌曲列表的某一首歌曲
|
|
||||||
* @param index
|
|
||||||
*/
|
|
||||||
default void onClickDownloadSong(Download download, int index){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
package com.hi.music.player.api;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.BoxLikeSong;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface LikeSongListener {
|
|
||||||
|
|
||||||
void onLikeSongChange(List<BoxLikeSong> data);
|
|
||||||
}
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
package com.hi.music.player.api;
|
|
||||||
|
|
||||||
import androidx.media3.common.MediaItem;
|
|
||||||
|
|
||||||
public interface MediaControllerListener {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void onPlayStatus(int playStatus);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param videoId
|
|
||||||
* @param playListIndex 在播放列表中的位置索引
|
|
||||||
* @param playNow 立即播放
|
|
||||||
*/
|
|
||||||
void onRequestNextUri(String videoId,int playListIndex,boolean playNow);
|
|
||||||
|
|
||||||
|
|
||||||
void onChangeMusic(MediaItem mediaItem);
|
|
||||||
}
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
package com.hi.music.player.api;
|
|
||||||
|
|
||||||
public interface MediaControllerStatusListener {
|
|
||||||
|
|
||||||
|
|
||||||
void onMediaControllerComplete(boolean isOk);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package com.hi.music.player.api;
|
|
||||||
|
|
||||||
public interface OnHasUrlAction {
|
|
||||||
void onHasUrl();
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
package com.hi.music.player.api;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
public interface RequestListener<T> {
|
|
||||||
|
|
||||||
void onFail(String errorMsg);
|
|
||||||
|
|
||||||
void onSuccess(JSONObject data) ;
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package com.hi.music.player.api;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.CustomerDownload;
|
|
||||||
|
|
||||||
public interface onCheckDownload {
|
|
||||||
void onHasDownload(CustomerDownload customerDownload);
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package com.hi.music.player.api;
|
|
||||||
|
|
||||||
public interface onImageColorListener {
|
|
||||||
void onImageColor(int color);
|
|
||||||
}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
package com.hi.music.player.api;
|
|
||||||
|
|
||||||
public interface onPlayNextListener {
|
|
||||||
void onPlayNext(boolean hasNext);
|
|
||||||
}
|
|
||||||
@ -1,167 +0,0 @@
|
|||||||
package com.hi.music.player.customerview;
|
|
||||||
|
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.LinearInterpolator;
|
|
||||||
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
public class AnimaPlayingView extends View {
|
|
||||||
|
|
||||||
private Paint paint;
|
|
||||||
private int barColor = Color.GREEN; // 音量条的颜色
|
|
||||||
private int numBars = 5; // 音量条的数量
|
|
||||||
private float[] barHeights; // 每个音量条的高度
|
|
||||||
private int maxHeight = CommonUtils.dpToPx(20); // 音量条的最大高度
|
|
||||||
private int minHeight = CommonUtils.dpToPx(4); // 音量条的最小高度
|
|
||||||
|
|
||||||
// 每个柱子的宽度
|
|
||||||
private int barWidth = CommonUtils.dpToPx(4);
|
|
||||||
// 柱子之间的间距
|
|
||||||
private int barSpacing = CommonUtils.dpToPx(2);
|
|
||||||
|
|
||||||
private int cornerRadius = CommonUtils.dpToPx(16);
|
|
||||||
private Random random;
|
|
||||||
|
|
||||||
private ValueAnimator animator;
|
|
||||||
private List<ValueAnimator> valueAnimatorList;
|
|
||||||
|
|
||||||
public AnimaPlayingView(Context context) {
|
|
||||||
super(context);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AnimaPlayingView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AnimaPlayingView(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
valueAnimatorList = new ArrayList<>();
|
|
||||||
paint = new Paint();
|
|
||||||
paint.setColor(barColor);
|
|
||||||
paint.setStyle(Paint.Style.FILL);
|
|
||||||
barHeights = new float[numBars];
|
|
||||||
random = new Random();
|
|
||||||
|
|
||||||
// 初始化音量条高度
|
|
||||||
for (int i = 0; i < numBars; i++) {
|
|
||||||
barHeights[i] = 0;
|
|
||||||
}
|
|
||||||
initAnimating();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
super.onDraw(canvas);
|
|
||||||
|
|
||||||
int height = getHeight();
|
|
||||||
int width = getWidth();
|
|
||||||
|
|
||||||
int barCount = barHeights.length;
|
|
||||||
int totalWidth = barCount * barWidth + (barCount - 1) * barSpacing;
|
|
||||||
int startX = (width - totalWidth) / 2;
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < numBars; i++) {
|
|
||||||
|
|
||||||
float left = startX + i * (barWidth + barSpacing);
|
|
||||||
float top = height - barHeights[i];
|
|
||||||
float right = left + barWidth;
|
|
||||||
float bottom = height;
|
|
||||||
|
|
||||||
canvas.drawRoundRect(left, top, right, bottom, cornerRadius, cornerRadius, paint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startAnimating() {
|
|
||||||
for (ValueAnimator valueAnimator : valueAnimatorList) {
|
|
||||||
valueAnimator.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 启动固定动画,使音量条的高度变化
|
|
||||||
public void initAnimating() {
|
|
||||||
for (int i = 0; i < numBars; i++) {
|
|
||||||
animator = ValueAnimator.ofFloat(0, 1);
|
|
||||||
animator.setDuration(1000); // 每0.5秒更新一次
|
|
||||||
animator.setRepeatCount(ValueAnimator.INFINITE);
|
|
||||||
animator.setRepeatMode(ValueAnimator.REVERSE);
|
|
||||||
animator.setInterpolator(new LinearInterpolator());
|
|
||||||
int finalI = i;
|
|
||||||
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationUpdate(ValueAnimator animation) {
|
|
||||||
// 更新每个音量条的高度,使其不断变化
|
|
||||||
float animatedValue = (Float) animation.getAnimatedValue();
|
|
||||||
float v = animatedValue * maxHeight;
|
|
||||||
barHeights[finalI] = v;
|
|
||||||
invalidate(); // 重绘视图
|
|
||||||
}
|
|
||||||
});
|
|
||||||
valueAnimatorList.add(animator);
|
|
||||||
animator.setStartDelay(i * 200L);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pauseAnimating() {
|
|
||||||
for (ValueAnimator valueAnimator : valueAnimatorList) {
|
|
||||||
valueAnimator.pause();
|
|
||||||
}
|
|
||||||
for (int i = 0; i < numBars; i++) {
|
|
||||||
barHeights[i] = minHeight;
|
|
||||||
}
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 随机生成音量条的高度
|
|
||||||
private float randomHeight() {
|
|
||||||
return minHeight + random.nextFloat() * (maxHeight - minHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置音量条的颜色
|
|
||||||
public void setBarColor(int color) {
|
|
||||||
barColor = color;
|
|
||||||
paint.setColor(barColor);
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置音量条的最大高度
|
|
||||||
public void setMaxHeight(int maxHeight) {
|
|
||||||
this.maxHeight = maxHeight;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置音量条的最小高度
|
|
||||||
public void setMinHeight(int minHeight) {
|
|
||||||
this.minHeight = minHeight;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置音量条数量
|
|
||||||
public void setNumBars(int numBars) {
|
|
||||||
this.numBars = numBars;
|
|
||||||
barHeights = new float[numBars];
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
package com.hi.music.player.dialog;
|
|
||||||
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.Window;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.fragment.app.DialogFragment;
|
|
||||||
import androidx.viewbinding.ViewBinding;
|
|
||||||
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class BaseDialog<T extends ViewBinding> extends DialogFragment {
|
|
||||||
|
|
||||||
protected T vb;
|
|
||||||
|
|
||||||
|
|
||||||
protected abstract T getViewBinding(LayoutInflater inflater, ViewGroup container);
|
|
||||||
|
|
||||||
protected abstract void initView();
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
|
||||||
vb = getViewBinding(inflater, container);
|
|
||||||
init();
|
|
||||||
initView();
|
|
||||||
return vb.getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("ResourceType")
|
|
||||||
private void init() {
|
|
||||||
|
|
||||||
Dialog dialog = getDialog();
|
|
||||||
setCancelable(true);
|
|
||||||
|
|
||||||
if (dialog != null) {
|
|
||||||
Window window = dialog.getWindow();
|
|
||||||
if (window != null) {
|
|
||||||
|
|
||||||
if (isFullScreen()) {
|
|
||||||
window.setStatusBarColor(Color.YELLOW); // 设置状态栏为透明,或其他颜色
|
|
||||||
// 设置 dialog 占据全屏并延伸到状态栏
|
|
||||||
// window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
|
|
||||||
|
|
||||||
// 允许内容绘制到状态栏
|
|
||||||
window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
|
|
||||||
window.setBackgroundDrawableResource(R.color.color_transparent);
|
|
||||||
window.getDecorView().setPadding(0, 0, 0, 0);
|
|
||||||
WindowManager.LayoutParams attributes = window.getAttributes();
|
|
||||||
attributes.gravity = Gravity.BOTTOM;
|
|
||||||
attributes.width = WindowManager.LayoutParams.MATCH_PARENT;
|
|
||||||
attributes.height = WindowManager.LayoutParams.MATCH_PARENT;
|
|
||||||
window.setAttributes(attributes);
|
|
||||||
} else {
|
|
||||||
window.setBackgroundDrawableResource(R.color.color_transparent);
|
|
||||||
window.getDecorView().setPadding(0, 0, 0, 0);
|
|
||||||
|
|
||||||
WindowManager.LayoutParams attributes = window.getAttributes();
|
|
||||||
attributes.gravity = Gravity.BOTTOM;
|
|
||||||
attributes.width = WindowManager.LayoutParams.MATCH_PARENT;
|
|
||||||
attributes.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
|
||||||
window.setAttributes(attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract boolean isFullScreen();
|
|
||||||
|
|
||||||
public void closeDialog() {
|
|
||||||
dismiss();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,127 +0,0 @@
|
|||||||
package com.hi.music.player.dialog;
|
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.graphics.drawable.GradientDrawable;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.media3.common.MediaItem;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.adapter.AdapterPlayList;
|
|
||||||
import com.hi.music.player.api.onImageColorListener;
|
|
||||||
import com.hi.music.player.databinding.DialogPlayListBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
|
||||||
import com.hi.music.player.media3.MyControllerView;
|
|
||||||
import com.hi.music.player.media3.MyMediaControllerManager;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class DialogPlayList extends BaseDialog<DialogPlayListBinding> {
|
|
||||||
private MyMediaControllerManager instance;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected DialogPlayListBinding getViewBinding(LayoutInflater inflater, ViewGroup container) {
|
|
||||||
return DialogPlayListBinding.inflate(inflater, container, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initView() {
|
|
||||||
|
|
||||||
instance = MyMediaControllerManager.getInstance();
|
|
||||||
initPlayListUi();
|
|
||||||
|
|
||||||
MediaItem currentMediaItem = instance.getCurMediaItem();
|
|
||||||
if (currentMediaItem != null) {
|
|
||||||
Uri artworkUri = currentMediaItem.mediaMetadata.artworkUri;
|
|
||||||
vb.topSongName.setText(currentMediaItem.mediaMetadata.title);
|
|
||||||
vb.topSingerName.setText(currentMediaItem.mediaMetadata.artist);
|
|
||||||
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(10))))
|
|
||||||
.load(artworkUri)
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
CommonUtils.LogMsg(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
CommonUtils.getDominantDarkColor1(resource, new onImageColorListener() {
|
|
||||||
@Override
|
|
||||||
public void onImageColor(int color) {
|
|
||||||
if (color == -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int lighterColor = CommonUtils.adjustBrightness(color, 1.2f); // 比原始颜色亮 20%
|
|
||||||
int darkerColor = CommonUtils.adjustBrightness(color, 0.8f); // 比原始颜色暗 20%
|
|
||||||
// GradientDrawable gradientDrawable = new GradientDrawable(
|
|
||||||
// GradientDrawable.Orientation.TOP_BOTTOM,
|
|
||||||
// new int[]{lighterColor, darkerColor} // 浅到深渐变
|
|
||||||
// );
|
|
||||||
vb.topLayout.setBackgroundColor(darkerColor);
|
|
||||||
Drawable newDrawable = CommonUtils.getNewDrawable(lighterColor, 24f, 24f, 0, 0);
|
|
||||||
vb.listLayout.setBackground(newDrawable);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(vb.topIm);
|
|
||||||
}
|
|
||||||
vb.imPlay.setSelected(instance.getIsPlaying());
|
|
||||||
|
|
||||||
vb.imPlay.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
vb.imPlay.setSelected(!vb.imPlay.isSelected());
|
|
||||||
if (vb.imPlay.isSelected()) {
|
|
||||||
instance.play();
|
|
||||||
} else {
|
|
||||||
instance.pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFullScreen() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initPlayListUi() {
|
|
||||||
List<ResponsePlayListInfo> playList = instance.getPlayList();
|
|
||||||
AdapterPlayList adapterPlayList = new AdapterPlayList();
|
|
||||||
vb.recyclerList.setLayoutManager(new LinearLayoutManager(MusicApplication.myApplication));
|
|
||||||
adapterPlayList.addData(playList);
|
|
||||||
vb.recyclerList.setAdapter(adapterPlayList);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,151 +0,0 @@
|
|||||||
package com.hi.music.player.firebase
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Application
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import android.os.Message
|
|
||||||
import android.text.TextUtils
|
|
||||||
import android.util.Log
|
|
||||||
import com.google.firebase.remoteconfig.ConfigUpdate
|
|
||||||
import com.google.firebase.remoteconfig.ConfigUpdateListener
|
|
||||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
|
|
||||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfigException
|
|
||||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings
|
|
||||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue
|
|
||||||
import com.hi.music.player.BuildConfig
|
|
||||||
import com.hi.music.player.helper.CommonUtils
|
|
||||||
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference
|
|
||||||
|
|
||||||
|
|
||||||
class RemoteConfig {
|
|
||||||
|
|
||||||
private var ctx: Context? = null
|
|
||||||
private var mFirebaseRemoteConfig: FirebaseRemoteConfig? = null
|
|
||||||
|
|
||||||
//配置是否初始化成功
|
|
||||||
private var isInit = false
|
|
||||||
|
|
||||||
//上次获取数据的时间
|
|
||||||
private var lastFetchTime: Long = 0
|
|
||||||
private val handler = MHandler(this)
|
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
|
|
||||||
const val key_open_type = "TYPE"
|
|
||||||
|
|
||||||
//进入A面
|
|
||||||
const val value_open_type_0 = "0"
|
|
||||||
//进入B面
|
|
||||||
const val value_open_type_1 = "1"
|
|
||||||
|
|
||||||
|
|
||||||
const val MSG_REFRESH_CONFIG = 1
|
|
||||||
val instance: RemoteConfig by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
|
|
||||||
RemoteConfig()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun init(ctx: Application) {
|
|
||||||
this.ctx = ctx
|
|
||||||
initConfig()
|
|
||||||
fetchConfig()
|
|
||||||
onConfigUpdate()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initConfig() {
|
|
||||||
var intervalTime = (60 * 10).toLong()
|
|
||||||
//如果是开发状态,则将提取时间缩短
|
|
||||||
if (BuildConfig.DEBUG) {
|
|
||||||
intervalTime = (60 * 5).toLong()
|
|
||||||
}
|
|
||||||
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance()
|
|
||||||
val configSettings =
|
|
||||||
FirebaseRemoteConfigSettings.Builder() //默认值12小时的最短提取间隔,如果在间隔内取值,则优先取上次的结果
|
|
||||||
.setMinimumFetchIntervalInSeconds(intervalTime).build()
|
|
||||||
mFirebaseRemoteConfig!!.setConfigSettingsAsync(configSettings)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onConfigUpdate() {
|
|
||||||
mFirebaseRemoteConfig!!.addOnConfigUpdateListener(object : ConfigUpdateListener {
|
|
||||||
override fun onUpdate(configUpdate: ConfigUpdate) {
|
|
||||||
|
|
||||||
CommonUtils.LogMsg("Updated keys: " + configUpdate.updatedKeys)
|
|
||||||
try {
|
|
||||||
mFirebaseRemoteConfig!!.activate().addOnCompleteListener { task ->
|
|
||||||
if (task.isSuccessful) {
|
|
||||||
updateData("onConfigUpdate", mFirebaseRemoteConfig!!.all)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (ignore: Exception) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onError(error: FirebaseRemoteConfigException) {
|
|
||||||
CommonUtils.LogMsg("Config update error with code: " + error.code)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun fetchConfig() {
|
|
||||||
//这里可能会抛出异常 FirebaseRemoteConfigFetchThrottledException
|
|
||||||
try {
|
|
||||||
mFirebaseRemoteConfig!!.fetchAndActivate().addOnCompleteListener { task ->
|
|
||||||
if (task.isSuccessful) {
|
|
||||||
isInit = true
|
|
||||||
lastFetchTime = System.currentTimeMillis()
|
|
||||||
updateData("fetchAndActivate", mFirebaseRemoteConfig!!.all)
|
|
||||||
//24小时后,重新再去获取
|
|
||||||
handler.removeMessages(MSG_REFRESH_CONFIG)
|
|
||||||
handler.sendEmptyMessageDelayed(
|
|
||||||
MSG_REFRESH_CONFIG, (1000 * 60 * 60 * 24).toLong()
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
//15分钟后重新再去获取
|
|
||||||
handler.removeMessages(MSG_REFRESH_CONFIG)
|
|
||||||
handler.sendEmptyMessageDelayed(MSG_REFRESH_CONFIG, (1000 * 60 * 15).toLong())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (ignore: Exception) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateData(from: String, all: Map<String, FirebaseRemoteConfigValue>) {
|
|
||||||
for ((key, value) in all) {
|
|
||||||
try {
|
|
||||||
CommonUtils.LogMsg( "from = " + from + "Key = " + key + " Value = " + value.asString()
|
|
||||||
)
|
|
||||||
if (TextUtils.equals(key_open_type, key)) {
|
|
||||||
Sp.getInstance()
|
|
||||||
.putStringValue(key_open_type, value.asString()).commit()
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (ignore: Exception) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MHandler(remoteConfig: RemoteConfig) : Handler(Looper.getMainLooper()) {
|
|
||||||
private val weakReference: WeakReference<RemoteConfig>
|
|
||||||
|
|
||||||
init {
|
|
||||||
weakReference = WeakReference(remoteConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun handleMessage(msg: Message) {
|
|
||||||
super.handleMessage(msg)
|
|
||||||
val remoteConfig = weakReference.get()
|
|
||||||
if (remoteConfig?.ctx != null) {
|
|
||||||
if (msg.what == MSG_REFRESH_CONFIG) {
|
|
||||||
remoteConfig.fetchConfig()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,167 +0,0 @@
|
|||||||
package com.hi.music.player.firebase;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.google.android.gms.tasks.OnCompleteListener;
|
|
||||||
import com.google.android.gms.tasks.Task;
|
|
||||||
import com.google.firebase.BuildConfig;
|
|
||||||
import com.google.firebase.remoteconfig.ConfigUpdate;
|
|
||||||
import com.google.firebase.remoteconfig.ConfigUpdateListener;
|
|
||||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfig;
|
|
||||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfigException;
|
|
||||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings;
|
|
||||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfigValue;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class RemoteConfigJava {
|
|
||||||
|
|
||||||
private static RemoteConfigJava remoteConfigJava;
|
|
||||||
public static String key_open_type = "TYPE";
|
|
||||||
|
|
||||||
//进入A面
|
|
||||||
public static String value_open_type_0 = "0";
|
|
||||||
//进入B面
|
|
||||||
public static String value_open_type_1 = "1";
|
|
||||||
|
|
||||||
|
|
||||||
private static int MSG_REFRESH_CONFIG = 1;
|
|
||||||
|
|
||||||
|
|
||||||
private Context ctx;
|
|
||||||
private FirebaseRemoteConfig mFirebaseRemoteConfig;
|
|
||||||
|
|
||||||
//配置是否初始化成功
|
|
||||||
private boolean isInit = false;
|
|
||||||
|
|
||||||
//上次获取数据的时间
|
|
||||||
private long lastFetchTime = 0;
|
|
||||||
private MHandler handler = new MHandler(this);
|
|
||||||
|
|
||||||
|
|
||||||
private Context getCtx() {
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RemoteConfigJava getInstance(){
|
|
||||||
if(remoteConfigJava == null){
|
|
||||||
remoteConfigJava = new RemoteConfigJava();
|
|
||||||
}
|
|
||||||
return remoteConfigJava;
|
|
||||||
}
|
|
||||||
private static class MHandler extends Handler {
|
|
||||||
private WeakReference<RemoteConfigJava> weakReference;
|
|
||||||
|
|
||||||
|
|
||||||
public MHandler(RemoteConfigJava remoteConfig) {
|
|
||||||
super(Looper.getMainLooper());
|
|
||||||
weakReference = new WeakReference<>(remoteConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMessage(@NonNull Message msg) {
|
|
||||||
super.handleMessage(msg);
|
|
||||||
|
|
||||||
RemoteConfigJava remoteConfig1 = weakReference.get();
|
|
||||||
if (remoteConfig1.getCtx() != null) {
|
|
||||||
if (msg.what == MSG_REFRESH_CONFIG) {
|
|
||||||
remoteConfig1.fetchConfig();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(Context context) {
|
|
||||||
this.ctx = context;
|
|
||||||
initConfig();
|
|
||||||
fetchConfig();
|
|
||||||
onConfigUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initConfig() {
|
|
||||||
long intervalTime = 60L * 10L;
|
|
||||||
//如果是开发状态,则将提取时间缩短
|
|
||||||
if (BuildConfig.DEBUG) {
|
|
||||||
intervalTime = 60L * 5L;
|
|
||||||
}
|
|
||||||
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
|
|
||||||
FirebaseRemoteConfigSettings configSettings = new FirebaseRemoteConfigSettings.Builder() //默认值12小时的最短提取间隔,如果在间隔内取值,则优先取上次的结果
|
|
||||||
.setMinimumFetchIntervalInSeconds(intervalTime).build();
|
|
||||||
mFirebaseRemoteConfig.setConfigSettingsAsync(configSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onConfigUpdate() {
|
|
||||||
mFirebaseRemoteConfig.addOnConfigUpdateListener(new ConfigUpdateListener() {
|
|
||||||
@Override
|
|
||||||
public void onUpdate(@NonNull ConfigUpdate configUpdate) {
|
|
||||||
CommonUtils.LogMsg("Updated keys: " + configUpdate.getUpdatedKeys());
|
|
||||||
try {
|
|
||||||
mFirebaseRemoteConfig.activate().addOnCompleteListener(new OnCompleteListener<Boolean>() {
|
|
||||||
@Override
|
|
||||||
public void onComplete(@NonNull Task<Boolean> task) {
|
|
||||||
if (task.isSuccessful()) {
|
|
||||||
updateData("onConfigUpdate", mFirebaseRemoteConfig.getAll());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception ignore) {
|
|
||||||
CommonUtils.LogErrorMsg("onConfigUpdate Exception " + ignore.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(@NonNull FirebaseRemoteConfigException error) {
|
|
||||||
CommonUtils.LogErrorMsg("onConfigUpdate onError " + error.getMessage());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fetchConfig() {
|
|
||||||
//这里可能会抛出异常 FirebaseRemoteConfigFetchThrottledException
|
|
||||||
try {
|
|
||||||
mFirebaseRemoteConfig.fetchAndActivate().addOnCompleteListener(new OnCompleteListener<Boolean>() {
|
|
||||||
@Override
|
|
||||||
public void onComplete(@NonNull Task<Boolean> task) {
|
|
||||||
if (task.isSuccessful()) {
|
|
||||||
isInit = true;
|
|
||||||
lastFetchTime = System.currentTimeMillis();
|
|
||||||
updateData("fetchAndActivate", mFirebaseRemoteConfig.getAll());
|
|
||||||
//24小时后,重新再去获取
|
|
||||||
handler.removeMessages(MSG_REFRESH_CONFIG);
|
|
||||||
handler.sendEmptyMessageDelayed(
|
|
||||||
MSG_REFRESH_CONFIG, 1000 * 60 * 60 * 24L);
|
|
||||||
} else {
|
|
||||||
//15分钟后重新再去获取
|
|
||||||
handler.removeMessages(MSG_REFRESH_CONFIG);
|
|
||||||
handler.sendEmptyMessageDelayed(MSG_REFRESH_CONFIG, 1000 * 60 * 15L);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception exception) {
|
|
||||||
CommonUtils.LogErrorMsg(" exception = " + exception.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void updateData(String from, Map<String, FirebaseRemoteConfigValue> all) {
|
|
||||||
for (Map.Entry<String, FirebaseRemoteConfigValue> entry : all.entrySet()) {
|
|
||||||
FirebaseRemoteConfigValue value = entry.getValue();
|
|
||||||
String key = entry.getKey();
|
|
||||||
CommonUtils.LogMsg("from = " + from + "Key = " + key + " Value = " + value.asString());
|
|
||||||
|
|
||||||
if (TextUtils.equals(key_open_type, key)) {
|
|
||||||
Sp.getInstance()
|
|
||||||
.putStringValue(key_open_type, value.asString()).commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
package com.hi.music.player.firebase;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class Sp {
|
|
||||||
|
|
||||||
private static String spName = "AD_SHOW";
|
|
||||||
private static Sp instance;
|
|
||||||
private SharedPreferences.Editor editor;
|
|
||||||
|
|
||||||
private SharedPreferences preferences;
|
|
||||||
|
|
||||||
private Sp(Context context) {
|
|
||||||
preferences = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
|
|
||||||
editor = preferences.edit();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void init(Context context){
|
|
||||||
instance = new Sp(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Sp getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Sp putStringValue(String key, String value) {
|
|
||||||
editor.putString(key, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean commit() {
|
|
||||||
return editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStringValue(String key) {
|
|
||||||
return preferences.getString(key, RemoteConfigJava.value_open_type_1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package com.hi.music.player.helper;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.lifecycle.ViewModelStore;
|
|
||||||
import androidx.lifecycle.ViewModelStoreOwner;
|
|
||||||
|
|
||||||
public class BaseViewModelStoreOwner implements ViewModelStoreOwner {
|
|
||||||
private final static BaseViewModelStoreOwner sInstance = new BaseViewModelStoreOwner();
|
|
||||||
private ViewModelStore mAppViewModelStore;
|
|
||||||
|
|
||||||
private BaseViewModelStoreOwner() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BaseViewModelStoreOwner getInstance() {
|
|
||||||
return sInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public ViewModelStore getViewModelStore() {
|
|
||||||
if (mAppViewModelStore == null) mAppViewModelStore = new ViewModelStore();
|
|
||||||
return mAppViewModelStore;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,324 +0,0 @@
|
|||||||
package com.hi.music.player.helper;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.graphics.drawable.GradientDrawable;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.media3.common.MediaItem;
|
|
||||||
import androidx.media3.common.MediaMetadata;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.datasource.cache.Cache;
|
|
||||||
import androidx.media3.datasource.cache.CacheEvictor;
|
|
||||||
import androidx.media3.datasource.cache.CacheSpan;
|
|
||||||
import androidx.media3.datasource.cache.SimpleCache;
|
|
||||||
import androidx.media3.exoplayer.offline.Download;
|
|
||||||
import androidx.palette.graphics.Palette;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.api.onImageColorListener;
|
|
||||||
import com.hi.music.player.javabean.BoxDownloadSong;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
import java.util.NavigableSet;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
public class CommonUtils {
|
|
||||||
|
|
||||||
private static String TAG = "----MUSIC---------";
|
|
||||||
|
|
||||||
private static String TAG_ERROR = "----MUSIC---------ERROR--";
|
|
||||||
|
|
||||||
public static void LogMsg(String msg) {
|
|
||||||
Log.d(TAG, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void LogErrorMsg(String msg) {
|
|
||||||
Log.e(TAG_ERROR, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JSONObject toJsonObject(ResponseBody body) {
|
|
||||||
try {
|
|
||||||
String string = body.string();
|
|
||||||
return new JSONObject(string);
|
|
||||||
} catch (IOException | JSONException exception) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static int dpToPx(int dp) {
|
|
||||||
return Math.round(dp * (MusicApplication.myApplication.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int pxToDp(int px) {
|
|
||||||
return Math.round(px / (MusicApplication.myApplication.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取导航栏高度的方法
|
|
||||||
public int getNavigationBarHeight(Context context) {
|
|
||||||
int navigationBarHeight = 0;
|
|
||||||
int resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
|
|
||||||
if (resourceId > 0) {
|
|
||||||
navigationBarHeight = context.getResources().getDimensionPixelSize(resourceId);
|
|
||||||
}
|
|
||||||
return navigationBarHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getStatusBarHeight(Context context) {
|
|
||||||
int statusBarHeight = 0;
|
|
||||||
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
|
||||||
if (resourceId > 0) {
|
|
||||||
statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
|
|
||||||
}
|
|
||||||
return statusBarHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//time 3:45 转换成毫秒
|
|
||||||
public static long convertToMilliseconds(String time) {
|
|
||||||
String[] parts = time.split(":");
|
|
||||||
if (parts.length == 2) {
|
|
||||||
//3:45
|
|
||||||
int minutes = Integer.parseInt(parts[0]);
|
|
||||||
int seconds = Integer.parseInt(parts[1]);
|
|
||||||
|
|
||||||
return (minutes * 60L + seconds) * 1000 - 1000;
|
|
||||||
} else {
|
|
||||||
//3:45:07
|
|
||||||
int hours = Integer.parseInt(parts[0]);
|
|
||||||
int minutes = Integer.parseInt(parts[1]);
|
|
||||||
int seconds = Integer.parseInt(parts[2]);
|
|
||||||
return (hours * 60L * 60L + minutes * 60L + seconds) * 1000 - 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static String convertMillisToTime(long millis) {
|
|
||||||
long seconds = millis / 1000;
|
|
||||||
long hours = seconds / 3600;
|
|
||||||
long minutes = (seconds % 3600) / 60;
|
|
||||||
long remainingSeconds = seconds % 60;
|
|
||||||
|
|
||||||
|
|
||||||
// long seconds = (millis / 1000) % 60;
|
|
||||||
// long minutes = (millis / (1000 * 60)) % 60;
|
|
||||||
if (hours > 0) {
|
|
||||||
return String.format(MusicApplication.myApplication.getString(R.string.time_format), hours, minutes, remainingSeconds); // 格式化为 mm:ss
|
|
||||||
} else {
|
|
||||||
return String.format(MusicApplication.myApplication.getString(R.string.minute_time_format), minutes, remainingSeconds); // 格式化为 mm:ss
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getMyColor(int resId) {
|
|
||||||
return MusicApplication.myApplication.getColor(resId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 使用 Palette 提取深色主色调
|
|
||||||
public static void getDominantDarkColor1(Drawable imDraw, onImageColorListener listener) {
|
|
||||||
// 异步生成 Palette
|
|
||||||
BitmapDrawable drawable = (BitmapDrawable) imDraw;
|
|
||||||
if (drawable != null) {
|
|
||||||
Bitmap bitmap = drawable.getBitmap();
|
|
||||||
Palette.from(bitmap)
|
|
||||||
.generate(new Palette.PaletteAsyncListener() {
|
|
||||||
@Override
|
|
||||||
public void onGenerated(Palette palette) {
|
|
||||||
// 首先尝试获取深色活力色
|
|
||||||
Palette.Swatch darkVibrantSwatch = palette.getDarkVibrantSwatch();
|
|
||||||
|
|
||||||
// 如果没有深色活力色,尝试获取深色柔和色
|
|
||||||
if (darkVibrantSwatch == null) {
|
|
||||||
darkVibrantSwatch = palette.getDarkMutedSwatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果存在深色样本,则获取其 RGB 颜色值
|
|
||||||
if (darkVibrantSwatch != null) {
|
|
||||||
int dominantDarkColor = darkVibrantSwatch.getRgb();
|
|
||||||
listener.onImageColor(dominantDarkColor);
|
|
||||||
String dominantColorHex = String.format("#%06X", (0xFFFFFF & dominantDarkColor));
|
|
||||||
Log.d("Dominant Dark Color", "主色调: " + dominantColorHex); // 打印主色调
|
|
||||||
} else {
|
|
||||||
Log.d("Dominant Dark Color", "未找到深色主色调");
|
|
||||||
listener.onImageColor(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
listener.onImageColor(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 调整颜色的亮度,factor > 1 表示变亮,factor < 1 表示变暗
|
|
||||||
public static int adjustBrightness(int color, float factor) {
|
|
||||||
// 将 RGB 颜色转换为 HSV
|
|
||||||
float[] hsv = new float[3];
|
|
||||||
Color.colorToHSV(color, hsv);
|
|
||||||
|
|
||||||
// 调整亮度(V 值)
|
|
||||||
hsv[2] = Math.min(1.0f, hsv[2] * factor); // 亮度值最多是 1.0
|
|
||||||
|
|
||||||
// 返回调整后的颜色(HSV 转回 RGB)
|
|
||||||
return Color.HSVToColor(hsv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void getMainColor(Drawable imDraw, onImageColorListener listener) {
|
|
||||||
|
|
||||||
BitmapDrawable drawable = (BitmapDrawable) imDraw;
|
|
||||||
// 使用 Palette 提取颜色
|
|
||||||
if (drawable != null) {
|
|
||||||
Bitmap bitmap = drawable.getBitmap();
|
|
||||||
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
|
|
||||||
@Override
|
|
||||||
public void onGenerated(Palette palette) {
|
|
||||||
// 获取占比最大的颜色
|
|
||||||
Palette.Swatch dominantSwatch = palette.getDominantSwatch();
|
|
||||||
if (dominantSwatch != null) {
|
|
||||||
int dominantColor = dominantSwatch.getRgb(); // 获取 RGB 颜色
|
|
||||||
listener.onImageColor(dominantColor);
|
|
||||||
} else {
|
|
||||||
listener.onImageColor(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Drawable getNewDrawable(int color, float RadiusTopLeft, float RadiusTopRight, float RadiusBottomRight, float RadiusBottomLeft) {
|
|
||||||
// 创建 GradientDrawable
|
|
||||||
GradientDrawable drawable = new GradientDrawable();
|
|
||||||
|
|
||||||
// 设置形状为矩形
|
|
||||||
drawable.setShape(GradientDrawable.RECTANGLE);
|
|
||||||
|
|
||||||
// 设置背景颜色
|
|
||||||
drawable.setColor(color);
|
|
||||||
|
|
||||||
// 设置顶部圆角 (top-left and top-right)
|
|
||||||
float[] radii = new float[]{
|
|
||||||
RadiusTopLeft, RadiusTopLeft, // top-left radius
|
|
||||||
RadiusTopRight, RadiusTopRight, // top-right radius
|
|
||||||
RadiusBottomRight, RadiusBottomRight, // bottom-right radius
|
|
||||||
RadiusBottomLeft, RadiusBottomLeft // bottom-left radius
|
|
||||||
};
|
|
||||||
drawable.setCornerRadii(radii);
|
|
||||||
return drawable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void extractColorsFromImage(Drawable drawable, View view) {
|
|
||||||
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
|
|
||||||
|
|
||||||
Palette.from(bitmap).generate(palette -> {
|
|
||||||
if (palette != null) {
|
|
||||||
// 获取主色
|
|
||||||
int vibrantColor = palette.getVibrantColor(0);
|
|
||||||
int mutedColor = palette.getMutedColor(0);
|
|
||||||
|
|
||||||
// 创建左右渐变色
|
|
||||||
createGradientBackground(vibrantColor, mutedColor, view);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void createGradientBackground(int leftColor, int rightColor, View view) {
|
|
||||||
GradientDrawable gradientDrawable = new android.graphics.drawable.GradientDrawable(
|
|
||||||
android.graphics.drawable.GradientDrawable.Orientation.LEFT_RIGHT,
|
|
||||||
new int[]{leftColor, rightColor}
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
view.setBackground(gradientDrawable);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 当前媒体项是否有有效的播放地址
|
|
||||||
*
|
|
||||||
* @param mediaItem
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static boolean hasValidUri(MediaItem mediaItem) {
|
|
||||||
MediaItem.LocalConfiguration localConfiguration = mediaItem.localConfiguration;
|
|
||||||
if (localConfiguration != null) {
|
|
||||||
if (CommonUtils.isUriFormat(localConfiguration.uri)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isUriFormat(Uri parsedUri) {
|
|
||||||
// 3. 检查 URI 是否具有正确的格式
|
|
||||||
try {
|
|
||||||
if (parsedUri.getScheme() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LogMsg("URI parsing failed: " + e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static BoxDownloadSong downloadToBean(Download download) {
|
|
||||||
@OptIn(markerClass = UnstableApi.class) byte[] data = download.request.data;
|
|
||||||
String additionalData = new String(data, StandardCharsets.UTF_8);
|
|
||||||
Gson gson = new Gson();
|
|
||||||
|
|
||||||
return gson.fromJson(additionalData, BoxDownloadSong.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
public static MediaItem downloadToMediaItem(Download data){
|
|
||||||
MediaItem mediaItem = data.request.toMediaItem();
|
|
||||||
BoxDownloadSong boxDownloadSong = CommonUtils.downloadToBean(data);
|
|
||||||
MediaItem.Builder builder = mediaItem.buildUpon();
|
|
||||||
|
|
||||||
MediaMetadata.Builder metadataBuilder = new MediaMetadata.Builder();
|
|
||||||
metadataBuilder.setArtist(boxDownloadSong.getSingerName());
|
|
||||||
metadataBuilder.setDescription(boxDownloadSong.getDuration());
|
|
||||||
metadataBuilder.setDurationMs(boxDownloadSong.getDurationMs());
|
|
||||||
metadataBuilder.setArtworkUri(Uri.parse(boxDownloadSong.getCovert()));
|
|
||||||
metadataBuilder.setTitle(boxDownloadSong.getSongName());
|
|
||||||
builder.setMediaMetadata(metadataBuilder.build());
|
|
||||||
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
// @OptIn(markerClass = UnstableApi.class)
|
|
||||||
// public static boolean isSongCached(SimpleCache cache, String id) {
|
|
||||||
//
|
|
||||||
// return cachedFile.exists();
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
@ -1,130 +0,0 @@
|
|||||||
package com.hi.music.player.helper;
|
|
||||||
|
|
||||||
public class MyValue {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 现场表演
|
|
||||||
public static final String PAGE_TYPE_MV_LIST="MUSIC_PAGE_TYPE_USER_CHANNEL";
|
|
||||||
|
|
||||||
|
|
||||||
//个人live
|
|
||||||
public static final String PAGE_TYPE_MV="MUSIC_PAGE_TYPE_ARTIST";
|
|
||||||
|
|
||||||
|
|
||||||
//风格音乐合集:乡村音乐
|
|
||||||
public static final String PAGE_TYPE_LIST="MUSIC_PAGE_TYPE_PLAYLIST";
|
|
||||||
|
|
||||||
//专辑
|
|
||||||
public static final String PAGE_TYPE_ALBUM="MUSIC_PAGE_TYPE_ALBUM";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------PlayActivity
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 歌手单曲进入的数据key
|
|
||||||
*/
|
|
||||||
public static String KEY_PLAY_ACTIVITY_SINGER = "click_singer";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 音乐列表进入的数据key和点击的列表位置key
|
|
||||||
*/
|
|
||||||
public static String KEY_PLAY_ACTIVITY_CATEGORY_LIST = "click_category_list";
|
|
||||||
public static String KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX = "click_category_list_index";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MV进入的数据key
|
|
||||||
*/
|
|
||||||
public static String KEY_PLAY_ACTIVITY_MV = "click_mv";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进入PlayActivity传递的即将播放的歌曲videoId
|
|
||||||
*/
|
|
||||||
public static String KEY_PLAY_VIDEO_ID = "video_id";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进入PlayActivity传递的即将播放的歌曲index(针对在进入PlayActivity之前已经调用vmApplication.reSetPlayList
|
|
||||||
* 重置了播放列表的情况)
|
|
||||||
*/
|
|
||||||
public static String KEY_PLAY_INDEX = "play_index";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//播放错误
|
|
||||||
public final static int PLAY_STATUS_CODE_ERROR = -1;
|
|
||||||
|
|
||||||
//正在播放
|
|
||||||
public final static int PLAY_STATUS_CODE_PLAYING = -2;
|
|
||||||
|
|
||||||
|
|
||||||
//暂停或者停止
|
|
||||||
public final static int PLAY_STATUS_CODE_PAUSE = -3;
|
|
||||||
|
|
||||||
//切歌
|
|
||||||
public final static int PLAY_STATUS_CHANGE_MUSIC= -4;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 进入播放页面的来源
|
|
||||||
* 0--首页单曲进入、 1--首页音乐分类合集列表进入 2--首页单个视频mv进入
|
|
||||||
* 3--控制面板进入
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static String KEY_ENTER_SOURCE = "ENTER_SOURCE";
|
|
||||||
public final static int TYPE_ENTER_SOURCE_SINGLE = 0;
|
|
||||||
|
|
||||||
public final static int TYPE_ENTER_SOURCE_CATEGORY = 1;
|
|
||||||
|
|
||||||
public final static int TYPE_ENTER_SOURCE_MV = 2;
|
|
||||||
|
|
||||||
|
|
||||||
public final static int TYPE_ENTER_PANEL = 3;
|
|
||||||
|
|
||||||
|
|
||||||
//从喜爱歌曲进入
|
|
||||||
public final static int TYPE_ENTER_LIKE= 4;
|
|
||||||
|
|
||||||
//从下载歌曲进入
|
|
||||||
public final static int TYPE_ENTER_DOWNLOAD= 5;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------CategoryListActivity
|
|
||||||
public static String KEY_PLAY_ACTIVITY_CATEGORY= "click_category";
|
|
||||||
|
|
||||||
public static String KEY_CATEGORY_LIST_TYPE= "page_type";
|
|
||||||
public static String KEY_CATEGORY_LIST_SINGER_NAME= "singer_name";
|
|
||||||
|
|
||||||
public static String KEY_CATEGORY_LIST_BROWSER_ID= "browser_id";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//------------------------ResultListActivity
|
|
||||||
public static String KEY_SEARCH_RESULT_BROWSER_ID= "search_result_browser_id";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------LikeSongActivity
|
|
||||||
public static String KEY_ENTER_LIKE_ACTIVITY_TYPE = "song_type";
|
|
||||||
|
|
||||||
public final static int KEY_ENTER_LIKE_ACTIVITY_TYPE_LIKE = 0;
|
|
||||||
public final static int KEY_ENTER_LIKE_ACTIVITY_TYPE_DOWNLOAD = 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package com.hi.music.player.helper;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.lifecycle.ViewModel;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
|
||||||
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
|
|
||||||
public class ViewModelScope {
|
|
||||||
private ViewModelProvider mFragmentProvider;
|
|
||||||
private ViewModelProvider mActivityProvider;
|
|
||||||
private ViewModelProvider mApplicationProvider;
|
|
||||||
|
|
||||||
public <T extends ViewModel> T getFragmentScopeViewModel(@NonNull Fragment fragment, @NonNull Class<T> modelClass) {
|
|
||||||
if (mFragmentProvider == null) mFragmentProvider = new ViewModelProvider(fragment);
|
|
||||||
return mFragmentProvider.get(modelClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T extends ViewModel> T getActivityScopeViewModel(@NonNull AppCompatActivity activity, @NonNull Class<T> modelClass) {
|
|
||||||
if (mActivityProvider == null) mActivityProvider = new ViewModelProvider(activity);
|
|
||||||
return mActivityProvider.get(modelClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T extends ViewModel> T getApplicationScopeViewModel(@NonNull Class<T> modelClass) {
|
|
||||||
if (mApplicationProvider == null)
|
|
||||||
mApplicationProvider = new ViewModelProvider(BaseViewModelStoreOwner.getInstance());
|
|
||||||
return mApplicationProvider.get(modelClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
package com.hi.music.player.javabean;
|
|
||||||
|
|
||||||
import io.objectbox.annotation.Entity;
|
|
||||||
import io.objectbox.annotation.Id;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class BoxDownloadSong {
|
|
||||||
@Id
|
|
||||||
public long id;
|
|
||||||
private String songName;
|
|
||||||
|
|
||||||
private String singerName;
|
|
||||||
private String videoId;
|
|
||||||
|
|
||||||
private String covert;
|
|
||||||
private long durationMs;
|
|
||||||
private String duration ;
|
|
||||||
|
|
||||||
// 音视频文件uri
|
|
||||||
private String videoUrl ;
|
|
||||||
|
|
||||||
public BoxDownloadSong( ) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public BoxDownloadSong(String songName, String singerName, String videoId, String covert, long durationMs, String duration) {
|
|
||||||
this.songName = songName;
|
|
||||||
this.singerName = singerName;
|
|
||||||
this.videoId = videoId;
|
|
||||||
this.covert = covert;
|
|
||||||
this.durationMs = durationMs;
|
|
||||||
this.duration = duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVideoUrl() {
|
|
||||||
return videoUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVideoUrl(String videoUrl) {
|
|
||||||
this.videoUrl = videoUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getDurationMs() {
|
|
||||||
return durationMs;
|
|
||||||
}
|
|
||||||
public String getDuration() {
|
|
||||||
return duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDuration(String duration) {
|
|
||||||
this.duration = duration;
|
|
||||||
}
|
|
||||||
public void setDurationMs(long durationMs) {
|
|
||||||
this.durationMs = durationMs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSingerName() {
|
|
||||||
return singerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSingerName(String singerName) {
|
|
||||||
this.singerName = singerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVideoId() {
|
|
||||||
return videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVideoId(String videoId) {
|
|
||||||
this.videoId = videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCovert() {
|
|
||||||
return covert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCovert(String covert) {
|
|
||||||
this.covert = covert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSongName() {
|
|
||||||
return songName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongName(String songName) {
|
|
||||||
this.songName = songName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
package com.hi.music.player.javabean;
|
|
||||||
|
|
||||||
import io.objectbox.annotation.Entity;
|
|
||||||
import io.objectbox.annotation.Id;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class BoxLikeSong {
|
|
||||||
@Id
|
|
||||||
public long id;
|
|
||||||
private String songName;
|
|
||||||
|
|
||||||
private String singerName;
|
|
||||||
private String videoId;
|
|
||||||
|
|
||||||
private String covert;
|
|
||||||
private long durationMs;
|
|
||||||
private String duration ;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public BoxLikeSong( ) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public BoxLikeSong(String songName, String singerName, String videoId, String covert,long durationMs,String duration) {
|
|
||||||
this.songName = songName;
|
|
||||||
this.singerName = singerName;
|
|
||||||
this.videoId = videoId;
|
|
||||||
this.covert = covert;
|
|
||||||
this.durationMs = durationMs;
|
|
||||||
this.duration = duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public long getDurationMs() {
|
|
||||||
return durationMs;
|
|
||||||
}
|
|
||||||
public String getDuration() {
|
|
||||||
return duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDuration(String duration) {
|
|
||||||
this.duration = duration;
|
|
||||||
}
|
|
||||||
public void setDurationMs(long durationMs) {
|
|
||||||
this.durationMs = durationMs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSingerName() {
|
|
||||||
return singerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSingerName(String singerName) {
|
|
||||||
this.singerName = singerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVideoId() {
|
|
||||||
return videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVideoId(String videoId) {
|
|
||||||
this.videoId = videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCovert() {
|
|
||||||
return covert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCovert(String covert) {
|
|
||||||
this.covert = covert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSongName() {
|
|
||||||
return songName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongName(String songName) {
|
|
||||||
this.songName = songName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package com.hi.music.player.javabean;
|
|
||||||
|
|
||||||
import androidx.media3.exoplayer.offline.Download;
|
|
||||||
|
|
||||||
public class CustomerDownload {
|
|
||||||
|
|
||||||
private Download download;
|
|
||||||
|
|
||||||
private boolean isDownload;
|
|
||||||
|
|
||||||
|
|
||||||
public CustomerDownload(Download download, boolean isDownload) {
|
|
||||||
this.download = download;
|
|
||||||
this.isDownload = isDownload;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Download getDownloadData() {
|
|
||||||
return download;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDownload() {
|
|
||||||
return isDownload;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
package com.hi.music.player.javabean;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
|
||||||
|
|
||||||
public class CustomerUrlInfo {
|
|
||||||
|
|
||||||
private ResponsePlayUrl playUrl;
|
|
||||||
private int playMusicIndex;
|
|
||||||
private boolean needPlayNow;
|
|
||||||
private String videoId;
|
|
||||||
|
|
||||||
|
|
||||||
public String getVideoId() {
|
|
||||||
return videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVideoId(String videoId) {
|
|
||||||
this.videoId = videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResponsePlayUrl getPlayUrl() {
|
|
||||||
return playUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlayUrl(ResponsePlayUrl playUrl) {
|
|
||||||
this.playUrl = playUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPlayMusicIndex() {
|
|
||||||
return playMusicIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlayMusicIndex(int playMusicIndex) {
|
|
||||||
this.playMusicIndex = playMusicIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isNeedPlayNow() {
|
|
||||||
return needPlayNow;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNeedPlayNow(boolean needPlayNow) {
|
|
||||||
this.needPlayNow = needPlayNow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.requestbody;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.requestbody.child.ContextBody;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 首页接口请求体
|
|
||||||
*/
|
|
||||||
public class BodyHome implements Serializable {
|
|
||||||
|
|
||||||
private String browseId = "FEmusic_home";
|
|
||||||
|
|
||||||
|
|
||||||
public String getBrowseId() {
|
|
||||||
return browseId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBrowseId(String browseId) {
|
|
||||||
this.browseId = browseId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ContextBody context = new ContextBody();
|
|
||||||
|
|
||||||
public ContextBody getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContext(ContextBody context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.requestbody;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.requestbody.child.ContextBody;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 播放页面接口请求体
|
|
||||||
*/
|
|
||||||
public class BodyPlay implements Serializable {
|
|
||||||
|
|
||||||
|
|
||||||
private ContextBody context = new ContextBody();
|
|
||||||
private String tunerSettingValue = "AUTOMIX_SETTING_NORMAL";
|
|
||||||
private boolean isAudioOnly = true;
|
|
||||||
private Configs watchEndpointMusicSupportedConfigs = new Configs();
|
|
||||||
private int index;
|
|
||||||
private String playlistId;
|
|
||||||
private String videoId;
|
|
||||||
private String params;
|
|
||||||
private String playlistSetVideoId;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class Configs {
|
|
||||||
private String musicVideoType = "MUSIC_VIDEO_TYPE_ATV";
|
|
||||||
|
|
||||||
|
|
||||||
public String getMusicVideoType() {
|
|
||||||
return musicVideoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMusicVideoType(String musicVideoType) {
|
|
||||||
this.musicVideoType = musicVideoType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContextBody getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContext(ContextBody context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setTunerSettingValue(String tunerSettingValue) {
|
|
||||||
this.tunerSettingValue = tunerSettingValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIndex(int index) {
|
|
||||||
this.index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlaylistId(String playlistId) {
|
|
||||||
this.playlistId = playlistId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVideoId(String videoId) {
|
|
||||||
this.videoId = videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParams(String params) {
|
|
||||||
this.params = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlaylistSetVideoId(String playlistSetVideoId) {
|
|
||||||
this.playlistSetVideoId = playlistSetVideoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Configs getWatchEndpointMusicSupportedConfigs() {
|
|
||||||
return watchEndpointMusicSupportedConfigs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.requestbody;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.requestbody.child.ContextBody;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 首页接口请求体
|
|
||||||
*/
|
|
||||||
public class BodyPlayUrl implements Serializable {
|
|
||||||
|
|
||||||
private String videoId ;
|
|
||||||
|
|
||||||
private ContextBody context = new ContextBody();
|
|
||||||
|
|
||||||
// private String key = "AIzaSyC9XL3ZjwddXya6X74dJOCTL-WEYFDNX30" ;
|
|
||||||
private String params ="CgIQBg";
|
|
||||||
|
|
||||||
|
|
||||||
public String getVideoId() {
|
|
||||||
return videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVideoId(String videoId) {
|
|
||||||
this.videoId = videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContextBody getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContext(ContextBody context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.requestbody;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.requestbody.child.Client;
|
|
||||||
import com.hi.music.player.javabean.requestbody.child.ContextBody;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搜索建议接口
|
|
||||||
*/
|
|
||||||
public class BodySearch implements Serializable {
|
|
||||||
|
|
||||||
private String query = "";
|
|
||||||
private ContextBody context = new ContextBody();
|
|
||||||
|
|
||||||
public String getQuery() {
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setQuery(String query) {
|
|
||||||
this.query = query;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ContextBody getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContext(ContextBody context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,34 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.requestbody;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.requestbody.child.Client;
|
|
||||||
import com.hi.music.player.javabean.requestbody.child.ContextBody;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搜索建议接口
|
|
||||||
*/
|
|
||||||
public class BodySearchSuggestion implements Serializable {
|
|
||||||
|
|
||||||
private String input = "";
|
|
||||||
|
|
||||||
|
|
||||||
public String getInput() {
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInput(String input) {
|
|
||||||
this.input = input;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ContextBody context = new ContextBody();
|
|
||||||
|
|
||||||
public ContextBody getContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContext(ContextBody context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.requestbody.child;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
|
|
||||||
public class Client implements Serializable {
|
|
||||||
private String clientName = "WEB_REMIX";
|
|
||||||
//1.20240506.01.00
|
|
||||||
private String clientVersion = "1.20220918";
|
|
||||||
private String hl = Locale.getDefault().getLanguage();
|
|
||||||
private String gl = "US";
|
|
||||||
private String platform = "DESKTOP";
|
|
||||||
|
|
||||||
private String visitorData;
|
|
||||||
|
|
||||||
public String getVisitorData() {
|
|
||||||
return visitorData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVisitorData(String visitorData) {
|
|
||||||
this.visitorData = visitorData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setClientName(String clientName) {
|
|
||||||
this.clientName = clientName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClientVersion(String clientVersion) {
|
|
||||||
this.clientVersion = clientVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlatform(String platform) {
|
|
||||||
this.platform = platform;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getGl() {
|
|
||||||
return gl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGl(String gl) {
|
|
||||||
this.gl = gl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHl() {
|
|
||||||
return hl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHl(String hl) {
|
|
||||||
this.hl = hl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.requestbody.child;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
public class ContextBody {
|
|
||||||
|
|
||||||
private Client client = new Client();
|
|
||||||
|
|
||||||
private ThirdParty thirdParty = new ThirdParty();
|
|
||||||
|
|
||||||
|
|
||||||
public ThirdParty getThirdParty() {
|
|
||||||
return thirdParty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Client getClient() {
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClient(Client client) {
|
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static class ThirdParty{
|
|
||||||
//https://www.youtube.com/watch?v=UqyT8IEBkvY
|
|
||||||
private String embedUrl;
|
|
||||||
|
|
||||||
public void setEmbedUrl(String embedUrl) {
|
|
||||||
this.embedUrl = embedUrl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseCategoryListChild;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ResponseCategoryList implements Serializable {
|
|
||||||
|
|
||||||
private String covert;
|
|
||||||
private String title;
|
|
||||||
private String description;
|
|
||||||
private String secondSubtitle;
|
|
||||||
|
|
||||||
private String singName;
|
|
||||||
|
|
||||||
private List<ResponsePlayListInfo> list;
|
|
||||||
|
|
||||||
|
|
||||||
public String getSingName() {
|
|
||||||
return singName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSingName(String singName) {
|
|
||||||
this.singName = singName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCovert() {
|
|
||||||
return covert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCovert(String covert) {
|
|
||||||
this.covert = covert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTitle(String title) {
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(String description) {
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSecondSubtitle() {
|
|
||||||
return secondSubtitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSecondSubtitle(String secondSubtitle) {
|
|
||||||
this.secondSubtitle = secondSubtitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ResponsePlayListInfo> getList() {
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setList(List<ResponsePlayListInfo> list) {
|
|
||||||
this.list = list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,68 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseHomeChild;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ResponseHome {
|
|
||||||
|
|
||||||
|
|
||||||
//用于更多数据请求的cit
|
|
||||||
private String clickTrackingParams;
|
|
||||||
|
|
||||||
//用于更多数据请求的ctoken
|
|
||||||
private String continuation;
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
//用于更多数据请求的visitorData(只有第一个接口会返回该值,youtubei/v1/browse?prettyPrint=false)
|
|
||||||
private String visitorData;
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private String backgroundUrl;
|
|
||||||
private List<ResponseHomeChild> childList;
|
|
||||||
|
|
||||||
|
|
||||||
public List<ResponseHomeChild> getChildList() {
|
|
||||||
return childList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChildList(List<ResponseHomeChild> childList) {
|
|
||||||
this.childList = childList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getClickTrackingParams() {
|
|
||||||
return clickTrackingParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setClickTrackingParams(String clickTrackingParams) {
|
|
||||||
this.clickTrackingParams = clickTrackingParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getContinuation() {
|
|
||||||
return continuation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContinuation(String continuation) {
|
|
||||||
this.continuation = continuation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVisitorData() {
|
|
||||||
return visitorData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVisitorData(String visitorData) {
|
|
||||||
this.visitorData = visitorData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBackgroundUrl() {
|
|
||||||
return backgroundUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBackgroundUrl(String backgroundUrl) {
|
|
||||||
this.backgroundUrl = backgroundUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,179 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response;
|
|
||||||
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 播放列表
|
|
||||||
*/
|
|
||||||
public class ResponsePlayListInfo implements Serializable {
|
|
||||||
|
|
||||||
//封面
|
|
||||||
private String covert;
|
|
||||||
|
|
||||||
|
|
||||||
//小尺寸封面
|
|
||||||
private String smallCovert;
|
|
||||||
|
|
||||||
//歌曲名字
|
|
||||||
private String SongTitle;
|
|
||||||
|
|
||||||
//歌手名字
|
|
||||||
private String SingerName;
|
|
||||||
|
|
||||||
//专辑名称
|
|
||||||
private String AlbumTitle;
|
|
||||||
|
|
||||||
//发行年份
|
|
||||||
private String Year;
|
|
||||||
|
|
||||||
//歌曲时长
|
|
||||||
private String Duration;
|
|
||||||
|
|
||||||
|
|
||||||
//歌曲时长 毫秒
|
|
||||||
private long DurationMs;
|
|
||||||
|
|
||||||
private String describe;
|
|
||||||
|
|
||||||
|
|
||||||
private String videoId;
|
|
||||||
private String playlistId;
|
|
||||||
private String params;
|
|
||||||
private String musicVideoType;
|
|
||||||
|
|
||||||
public ResponsePlayListInfo() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResponsePlayListInfo(String covert, String songTitle, String singerName, long durationMs, String videoId,String duration) {
|
|
||||||
this.covert = covert;
|
|
||||||
SongTitle = songTitle;
|
|
||||||
SingerName = singerName;
|
|
||||||
DurationMs = durationMs;
|
|
||||||
this.Duration = duration;
|
|
||||||
this.videoId = videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescribe() {
|
|
||||||
return describe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescribe(String describe) {
|
|
||||||
this.describe = describe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSmallCovert() {
|
|
||||||
return smallCovert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSmallCovert(String smallCovert) {
|
|
||||||
this.smallCovert = smallCovert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getDurationMs() {
|
|
||||||
return DurationMs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDurationMs(long durationMs) {
|
|
||||||
DurationMs = durationMs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDuration() {
|
|
||||||
return Duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDuration(String duration) {
|
|
||||||
Duration = duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCovert() {
|
|
||||||
return covert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCovert(String covert) {
|
|
||||||
this.covert = covert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSongTitle() {
|
|
||||||
return SongTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongTitle(String songTitle) {
|
|
||||||
SongTitle = songTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSingerName() {
|
|
||||||
return SingerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSingerName(String singerName) {
|
|
||||||
SingerName = singerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAlbumTitle() {
|
|
||||||
return AlbumTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAlbumTitle(String albumTitle) {
|
|
||||||
AlbumTitle = albumTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getYear() {
|
|
||||||
return Year;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setYear(String year) {
|
|
||||||
Year = year;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVideoId() {
|
|
||||||
return videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVideoId(String videoId) {
|
|
||||||
this.videoId = videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPlaylistId() {
|
|
||||||
return playlistId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlaylistId(String playlistId) {
|
|
||||||
this.playlistId = playlistId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getParams() {
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParams(String params) {
|
|
||||||
this.params = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMusicVideoType() {
|
|
||||||
return musicVideoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMusicVideoType(String musicVideoType) {
|
|
||||||
this.musicVideoType = musicVideoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// public String getAudioUrlLow() {
|
|
||||||
// return audioUrlLow;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void setAudioUrlLow(String audioUrlLow) {
|
|
||||||
// this.audioUrlLow = audioUrlLow;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public String getAudioUrlMedium() {
|
|
||||||
// return audioUrlMedium;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void setAudioUrlMedium(String audioUrlMedium) {
|
|
||||||
// this.audioUrlMedium = audioUrlMedium;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 音频源地址
|
|
||||||
*/
|
|
||||||
public class ResponsePlayUrl {
|
|
||||||
|
|
||||||
private String status;
|
|
||||||
private String audioUrlLow;
|
|
||||||
|
|
||||||
private String audioUrlMedium;
|
|
||||||
private String videoId;
|
|
||||||
|
|
||||||
private String BigCovert;
|
|
||||||
private String videoUrlMedium;
|
|
||||||
|
|
||||||
|
|
||||||
public String getVideoUrlMedium() {
|
|
||||||
return videoUrlMedium;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVideoUrlMedium(String videoUrlMedium) {
|
|
||||||
this.videoUrlMedium = videoUrlMedium;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBigCovert() {
|
|
||||||
return BigCovert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBigCovert(String bigCovert) {
|
|
||||||
BigCovert = bigCovert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAudioUrlMedium() {
|
|
||||||
return audioUrlMedium;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAudioUrlMedium(String audioUrlMedium) {
|
|
||||||
this.audioUrlMedium = audioUrlMedium;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///AUDIO_QUALITY_MEDIUM、AUDIO_QUALITY_LOW
|
|
||||||
// private String audioQuality;
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// public String getAudioQuality() {
|
|
||||||
// return audioQuality;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public void setAudioQuality(String audioQuality) {
|
|
||||||
// this.audioQuality = audioQuality;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public String getVideoId() {
|
|
||||||
return videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVideoId(String videoId) {
|
|
||||||
this.videoId = videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(String status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAudioUrlLow() {
|
|
||||||
return audioUrlLow;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAudioUrlLow(String audioUrlLow) {
|
|
||||||
this.audioUrlLow = audioUrlLow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ResponseResult {
|
|
||||||
|
|
||||||
private String mainTitle;
|
|
||||||
private String mainCovert;
|
|
||||||
|
|
||||||
private List<ResponseResultList> list;
|
|
||||||
|
|
||||||
|
|
||||||
public String getMainTitle() {
|
|
||||||
return mainTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMainTitle(String mainTitle) {
|
|
||||||
this.mainTitle = mainTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMainCovert() {
|
|
||||||
return mainCovert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMainCovert(String mainCovert) {
|
|
||||||
this.mainCovert = mainCovert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ResponseResultList> getList() {
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setList(List<ResponseResultList> list) {
|
|
||||||
this.list = list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseResultListChild;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ResponseResultList {
|
|
||||||
|
|
||||||
private String headerTitle;
|
|
||||||
|
|
||||||
private List<ResponseResultListChild> childList;
|
|
||||||
|
|
||||||
|
|
||||||
public String getHeaderTitle() {
|
|
||||||
return headerTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeaderTitle(String headerTitle) {
|
|
||||||
this.headerTitle = headerTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ResponseResultListChild> getChildList() {
|
|
||||||
return childList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChildList(List<ResponseResultListChild> childList) {
|
|
||||||
this.childList = childList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response;
|
|
||||||
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSearchChild;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ResponseSearch {
|
|
||||||
|
|
||||||
private String headerTitle;
|
|
||||||
|
|
||||||
|
|
||||||
private String beastSongTitle;
|
|
||||||
private String beastSongTCovert;
|
|
||||||
private String beastSongDescribe;
|
|
||||||
|
|
||||||
private String beastBrowserId;
|
|
||||||
|
|
||||||
private String beastVideoId;
|
|
||||||
|
|
||||||
private String pageType;
|
|
||||||
|
|
||||||
|
|
||||||
private List<ResponseSearchChild> list;
|
|
||||||
|
|
||||||
|
|
||||||
public String getBeastVideoId() {
|
|
||||||
return beastVideoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBeastVideoId(String beastVideoId) {
|
|
||||||
this.beastVideoId = beastVideoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHeaderTitle() {
|
|
||||||
return headerTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeaderTitle(String headerTitle) {
|
|
||||||
this.headerTitle = headerTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ResponseSearchChild> getList() {
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setList(List<ResponseSearchChild> list) {
|
|
||||||
this.list = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getBeastSongTitle() {
|
|
||||||
return beastSongTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBeastSongTitle(String beastSongTitle) {
|
|
||||||
this.beastSongTitle = beastSongTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBeastSongTCovert() {
|
|
||||||
return beastSongTCovert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBeastSongTCovert(String beastSongTCovert) {
|
|
||||||
this.beastSongTCovert = beastSongTCovert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBeastSongDescribe() {
|
|
||||||
return beastSongDescribe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBeastSongDescribe(String beastSongDescribe) {
|
|
||||||
this.beastSongDescribe = beastSongDescribe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBeastBrowserId() {
|
|
||||||
return beastBrowserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBeastBrowserId(String beastBrowserId) {
|
|
||||||
this.beastBrowserId = beastBrowserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPageType() {
|
|
||||||
return pageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPageType(String pageType) {
|
|
||||||
this.pageType = pageType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,117 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response.child;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class ResponseCategory implements Serializable {
|
|
||||||
|
|
||||||
//类别封面
|
|
||||||
private String covert;
|
|
||||||
//类别标题
|
|
||||||
private String twoTitle;
|
|
||||||
|
|
||||||
//类别描述
|
|
||||||
/**
|
|
||||||
* PAGE_TYPE_ALBUM : 专辑.歌手名字
|
|
||||||
* PAGE_TYPE_LIST :多个歌手名字
|
|
||||||
*/
|
|
||||||
private String twoSubtitle;
|
|
||||||
|
|
||||||
|
|
||||||
private String browseId;
|
|
||||||
|
|
||||||
private String videoId;
|
|
||||||
|
|
||||||
private String playListId;
|
|
||||||
|
|
||||||
private String params;
|
|
||||||
private String musicVideoType;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 视频Mv合集
|
|
||||||
*MUSIC_PAGE_TYPE_USER_CHANNEL
|
|
||||||
*
|
|
||||||
* 视频Mv单个
|
|
||||||
* MUSIC_PAGE_TYPE_USER_CHANNEL
|
|
||||||
*
|
|
||||||
* 音乐合集列表
|
|
||||||
* MUSIC_PAGE_TYPE_PLAYLIST
|
|
||||||
*
|
|
||||||
* 专辑
|
|
||||||
*MUSIC_PAGE_TYPE_ALBUM
|
|
||||||
*/
|
|
||||||
private String pageType;
|
|
||||||
|
|
||||||
public String getParams() {
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParams(String params) {
|
|
||||||
this.params = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMusicVideoType() {
|
|
||||||
return musicVideoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMusicVideoType(String musicVideoType) {
|
|
||||||
this.musicVideoType = musicVideoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPlayListId() {
|
|
||||||
return playListId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlayListId(String playListId) {
|
|
||||||
this.playListId = playListId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVideoId() {
|
|
||||||
return videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVideoId(String videoId) {
|
|
||||||
this.videoId = videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPageType() {
|
|
||||||
return pageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPageType(String pageType) {
|
|
||||||
this.pageType = pageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBrowseId() {
|
|
||||||
return browseId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBrowseId(String browseId) {
|
|
||||||
this.browseId = browseId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCovert() {
|
|
||||||
return covert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCovert(String covert) {
|
|
||||||
this.covert = covert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTwoTitle() {
|
|
||||||
return twoTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTwoTitle(String twoTitle) {
|
|
||||||
this.twoTitle = twoTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTwoSubtitle() {
|
|
||||||
return twoSubtitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTwoSubtitle(String twoSubtitle) {
|
|
||||||
this.twoSubtitle = twoSubtitle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response.child;
|
|
||||||
|
|
||||||
public class ResponseCategoryListChild {
|
|
||||||
private String SongTitle;
|
|
||||||
|
|
||||||
private String SingerName;
|
|
||||||
|
|
||||||
private String SongCovert;
|
|
||||||
|
|
||||||
private String SongDuration;
|
|
||||||
|
|
||||||
|
|
||||||
public String getSongCovert() {
|
|
||||||
return SongCovert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongCovert(String songCovert) {
|
|
||||||
SongCovert = songCovert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSongDuration() {
|
|
||||||
return SongDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongDuration(String songDuration) {
|
|
||||||
SongDuration = songDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSongTitle() {
|
|
||||||
return SongTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongTitle(String songTitle) {
|
|
||||||
SongTitle = songTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSingerName() {
|
|
||||||
return SingerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSingerName(String singerName) {
|
|
||||||
SingerName = singerName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response.child;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ResponseHomeChild {
|
|
||||||
|
|
||||||
private String HeaderTitle;
|
|
||||||
|
|
||||||
private List<ResponseSingle> singleList;
|
|
||||||
private List<ResponseCategory> categoryList;
|
|
||||||
|
|
||||||
|
|
||||||
public String getHeaderTitle() {
|
|
||||||
return HeaderTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeaderTitle(String headerTitle) {
|
|
||||||
HeaderTitle = headerTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ResponseSingle> getSingleList() {
|
|
||||||
return singleList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSingleList(List<ResponseSingle> singleList) {
|
|
||||||
this.singleList = singleList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ResponseCategory> getCategoryList() {
|
|
||||||
return categoryList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCategoryList(List<ResponseCategory> categoryList) {
|
|
||||||
this.categoryList = categoryList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response.child;
|
|
||||||
|
|
||||||
public class ResponseResultListChild {
|
|
||||||
private String thumbnail;
|
|
||||||
|
|
||||||
|
|
||||||
private String songName;
|
|
||||||
private String subTitle;
|
|
||||||
private String playCount;
|
|
||||||
private String videoId;
|
|
||||||
private String playListId;
|
|
||||||
|
|
||||||
private String browserId;
|
|
||||||
|
|
||||||
private String pageType;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String getThumbnail() {
|
|
||||||
return thumbnail;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setThumbnail(String thumbnail) {
|
|
||||||
this.thumbnail = thumbnail;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSongName() {
|
|
||||||
return songName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongName(String songName) {
|
|
||||||
this.songName = songName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSubTitle() {
|
|
||||||
return subTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSubTitle(String subTitle) {
|
|
||||||
this.subTitle = subTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBrowserId() {
|
|
||||||
return browserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBrowserId(String browserId) {
|
|
||||||
this.browserId = browserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPageType() {
|
|
||||||
return pageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPageType(String pageType) {
|
|
||||||
this.pageType = pageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPlayCount() {
|
|
||||||
return playCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlayCount(String playCount) {
|
|
||||||
this.playCount = playCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVideoId() {
|
|
||||||
return videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVideoId(String videoId) {
|
|
||||||
this.videoId = videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPlayListId() {
|
|
||||||
return playListId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlayListId(String playListId) {
|
|
||||||
this.playListId = playListId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response.child;
|
|
||||||
|
|
||||||
public class ResponseSearchChild {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private String songTitle;
|
|
||||||
private String songCovert;
|
|
||||||
private String songDescribe;
|
|
||||||
private String songPlayCount;
|
|
||||||
private String songVideoId;
|
|
||||||
|
|
||||||
private String browserId;
|
|
||||||
|
|
||||||
private String pageType;
|
|
||||||
|
|
||||||
|
|
||||||
public String getBrowserId() {
|
|
||||||
return browserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBrowserId(String browserId) {
|
|
||||||
this.browserId = browserId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPageType() {
|
|
||||||
return pageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPageType(String pageType) {
|
|
||||||
this.pageType = pageType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSongTitle() {
|
|
||||||
return songTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongTitle(String songTitle) {
|
|
||||||
this.songTitle = songTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSongCovert() {
|
|
||||||
return songCovert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongCovert(String songCovert) {
|
|
||||||
this.songCovert = songCovert;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSongDescribe() {
|
|
||||||
return songDescribe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongDescribe(String songDescribe) {
|
|
||||||
this.songDescribe = songDescribe;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSongPlayCount() {
|
|
||||||
return songPlayCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongPlayCount(String songPlayCount) {
|
|
||||||
this.songPlayCount = songPlayCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSongVideoId() {
|
|
||||||
return songVideoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongVideoId(String songVideoId) {
|
|
||||||
this.songVideoId = songVideoId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
package com.hi.music.player.javabean.response.child;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
public class ResponseSingle implements Serializable {
|
|
||||||
|
|
||||||
//歌手头像
|
|
||||||
private String SingerHead;
|
|
||||||
//歌曲名字
|
|
||||||
private String SongTitle;
|
|
||||||
|
|
||||||
//歌手名字
|
|
||||||
private String SingerName;
|
|
||||||
//描述
|
|
||||||
private String Description;
|
|
||||||
|
|
||||||
|
|
||||||
private String videoId;
|
|
||||||
private String playlistId;
|
|
||||||
private String params;
|
|
||||||
private String musicVideoType;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public String getSingerHead() {
|
|
||||||
return SingerHead;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSingerHead(String singerHead) {
|
|
||||||
SingerHead = singerHead;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSongTitle() {
|
|
||||||
return SongTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSongTitle(String songTitle) {
|
|
||||||
SongTitle = songTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSingerName() {
|
|
||||||
return SingerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSingerName(String singerName) {
|
|
||||||
SingerName = singerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return Description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(String description) {
|
|
||||||
Description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setVideoId(String videoId) {
|
|
||||||
this.videoId = videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlaylistId(String playlistId) {
|
|
||||||
this.playlistId = playlistId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParams(String params) {
|
|
||||||
this.params = params;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMusicVideoType(String musicVideoType) {
|
|
||||||
this.musicVideoType = musicVideoType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getVideoId() {
|
|
||||||
return videoId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPlaylistId() {
|
|
||||||
return playlistId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getParams() {
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMusicVideoType() {
|
|
||||||
return musicVideoType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,154 +0,0 @@
|
|||||||
package com.hi.music.player.media3;
|
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
import androidx.media3.common.MediaItem;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.datasource.DataSource;
|
|
||||||
import androidx.media3.datasource.DataSpec;
|
|
||||||
import androidx.media3.datasource.DefaultDataSource;
|
|
||||||
import androidx.media3.datasource.DefaultDataSourceFactory;
|
|
||||||
import androidx.media3.datasource.DefaultHttpDataSource;
|
|
||||||
import androidx.media3.datasource.ResolvingDataSource;
|
|
||||||
import androidx.media3.datasource.cache.CacheDataSource;
|
|
||||||
import androidx.media3.datasource.cache.SimpleCache;
|
|
||||||
import androidx.media3.exoplayer.ExoPlayer;
|
|
||||||
import androidx.media3.exoplayer.drm.DrmSessionManagerProvider;
|
|
||||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
|
||||||
import androidx.media3.exoplayer.source.MediaSource;
|
|
||||||
import androidx.media3.exoplayer.source.MediaSourceFactory;
|
|
||||||
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
|
|
||||||
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
|
|
||||||
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.api.RequestListener;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
|
||||||
import com.hi.music.player.network.JsonHelper;
|
|
||||||
import com.hi.music.player.network.RetrofitManager;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
|
|
||||||
public class DynamicMediaSourceFactory implements MediaSource.Factory {
|
|
||||||
|
|
||||||
private DataSource.Factory mediaSourceFactory;
|
|
||||||
private SimpleCache simpleCache;
|
|
||||||
|
|
||||||
public DynamicMediaSourceFactory(DataSource.Factory factory) {
|
|
||||||
|
|
||||||
this.mediaSourceFactory = factory;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@UnstableApi
|
|
||||||
@Override
|
|
||||||
public MediaSource.Factory setDrmSessionManagerProvider(DrmSessionManagerProvider drmSessionManagerProvider) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@UnstableApi
|
|
||||||
@Override
|
|
||||||
public MediaSource.Factory setLoadErrorHandlingPolicy(LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@UnstableApi
|
|
||||||
@Override
|
|
||||||
public int[] getSupportedTypes() {
|
|
||||||
return new int[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@UnstableApi
|
|
||||||
@Override
|
|
||||||
public MediaSource createMediaSource(MediaItem mediaItem) {
|
|
||||||
|
|
||||||
|
|
||||||
CommonUtils.LogMsg("------createMediaSource----------=" + mediaItem.mediaId + "---------" + mediaItem.mediaMetadata.title);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// DefaultHttpDataSource.Factory httpDataSourceFactory = new DefaultHttpDataSource.Factory().setAllowCrossProtocolRedirects(true);
|
|
||||||
// 这里的DefaultDataSource同时支持本地和HTTP请求的资源,自动实现检测 (The DefaultDataSource supports both local and Http sources. It automatically detects which one to use.)
|
|
||||||
|
|
||||||
//实现缓存
|
|
||||||
// CacheDataSource.Factory cacheDataSourceFactory = new CacheDataSource.Factory()
|
|
||||||
// .setCache(simpleCache)
|
|
||||||
// .setUpstreamDataSourceFactory(mediaSourceFactory)
|
|
||||||
// .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
|
|
||||||
|
|
||||||
MediaSource mediaSource = new ProgressiveMediaSource.Factory(mediaSourceFactory)
|
|
||||||
.createMediaSource(mediaItem);
|
|
||||||
|
|
||||||
return mediaSource;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// return new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
|
|
||||||
// .createMediaSource(MediaItem.fromUri(responsePlayUrl.getAudioUrlMedium()));
|
|
||||||
// 可以在这里根据 mediaItem 的 ID 动态生成新的 URI
|
|
||||||
// String updatedUri = "https://rr1---sn-tt1e7nlz.googlevideo.com/videoplayback?expire=1727628605&ei=3TD5ZuWFEe-yzN0P27WuqQ4&ip=146.19.167.8&id=o-ANGM0PjEvsfYH7TmYV_DFuD-65tipJeeLe2URDOk90sL&itag=140&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&mh=xj&mm=31%2C29&mn=sn-tt1e7nlz%2Csn-vgqsknsk&ms=au%2Crdu&mv=m&mvi=1&pl=24&pcm2=no&gcr=us&initcwndbps=7610000&vprv=1&svpuc=1&mime=audio%2Fmp4&rqh=1&gir=yes&clen=5440168&dur=335.973&lmt=1709326903801285&mt=1727606690&fvip=5&keepalive=yes&fexp=51299152&c=ANDROID_MUSIC&txp=2318224&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cpcm2%2Cgcr%2Cvprv%2Csvpuc%2Cmime%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AJfQdSswRQIhALmM_S8Cmagr60muB3wDOby0OdcjF-x6f7TcEenixH0KAiAnR0-hmA03MeVzSg2wi5ncJ4Ve5FFlpZnlSoRNGWgGhQ%3D%3D&lsparams=mh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Cinitcwndbps&lsig=ABPmVW0wRQIhAPv5slfEnf8_E7o6yjEkussQ6JIFFaSY6QtP9HXncTTcAiAjlhMa71t76Wu1R1rcmsHoO6pyxjhGYouio4D0deJqEA%3D%3D";
|
|
||||||
// Uri updateUri = null;
|
|
||||||
//
|
|
||||||
// MediaItem.Builder builder = mediaItem.buildUpon();
|
|
||||||
// if (mediaItem.localConfiguration != null) {
|
|
||||||
// updateUri = mediaItem.localConfiguration.uri;
|
|
||||||
// builder.setUri(updateUri);
|
|
||||||
// CommonUtils.LogErrorMsg("----updateUri=成功 builder="+mediaItem.mediaId+"--updateUri="+updateUri);
|
|
||||||
// }else {
|
|
||||||
// CommonUtils.LogErrorMsg("----updateUri=null builder="+mediaItem.mediaId);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return mediaSourceFactory.createMediaSource(builder.build());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// @UnstableApi
|
|
||||||
// @Override
|
|
||||||
// public DataSource createDataSource() {
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//// RetrofitManager.getInstance().getPlayUrl(mediaItem.mediaId, new RequestListener<ResponseBody>() {
|
|
||||||
////
|
|
||||||
//// @Override
|
|
||||||
//// public void onFail(String errorMsg) {
|
|
||||||
////
|
|
||||||
//// }
|
|
||||||
////
|
|
||||||
//// @Override
|
|
||||||
//// public void onSuccess(ResponseBody data) {
|
|
||||||
//// JSONObject jsonObject = CommonUtils.toJsonObject(data);
|
|
||||||
//// if (jsonObject != null) {
|
|
||||||
//// ResponsePlayUrl responsePlayUrl = JsonHelper.ResolvePlayUrlJson(jsonObject);
|
|
||||||
//// if (responsePlayUrl == null) {
|
|
||||||
//// // TODO: 2024/9/27
|
|
||||||
//// return;
|
|
||||||
//// }
|
|
||||||
//// String uri = "";
|
|
||||||
//// if (responsePlayUrl.getAudioUrlMedium() != null) {
|
|
||||||
//// uri = responsePlayUrl.getAudioUrlMedium();
|
|
||||||
//// } else {
|
|
||||||
//// uri = responsePlayUrl.getAudioUrlLow();
|
|
||||||
//// }
|
|
||||||
//// CommonUtils.LogMsg("------createMediaSource----------="+mediaItem.mediaId+"---------"+uri);
|
|
||||||
//// ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
|
|
||||||
//// .createMediaSource(MediaItem.fromUri(uri));
|
|
||||||
//// player.setMediaSource(mediaSource);
|
|
||||||
//// player.prepare();
|
|
||||||
////
|
|
||||||
//// }
|
|
||||||
////
|
|
||||||
////
|
|
||||||
//// }
|
|
||||||
//// });
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
package com.hi.music.player.media3;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.ui.PlayerControlView;
|
|
||||||
|
|
||||||
@UnstableApi
|
|
||||||
public class MyControllerView extends PlayerControlView{
|
|
||||||
public MyControllerView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
package com.hi.music.player.media3;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.database.StandaloneDatabaseProvider;
|
|
||||||
import androidx.media3.datasource.cache.NoOpCacheEvictor;
|
|
||||||
import androidx.media3.datasource.cache.SimpleCache;
|
|
||||||
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下载缓存
|
|
||||||
*/
|
|
||||||
public class MyDownloadCacheManager {
|
|
||||||
|
|
||||||
private static SimpleCache downloadCache;
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
public static SimpleCache getMyCache(StandaloneDatabaseProvider databaseProvider){
|
|
||||||
if(downloadCache == null){
|
|
||||||
Context myApplication = MusicApplication.myApplication;
|
|
||||||
File musicApp = new File(myApplication.getCacheDir(), "Music_App");
|
|
||||||
downloadCache = new SimpleCache(musicApp, new NoOpCacheEvictor(), databaseProvider);
|
|
||||||
}
|
|
||||||
return downloadCache;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,193 +0,0 @@
|
|||||||
package com.hi.music.player.media3;
|
|
||||||
|
|
||||||
import android.app.Notification;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Pair;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.database.StandaloneDatabaseProvider;
|
|
||||||
import androidx.media3.datasource.DefaultHttpDataSource;
|
|
||||||
import androidx.media3.datasource.cache.SimpleCache;
|
|
||||||
import androidx.media3.exoplayer.offline.Download;
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadCursor;
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadIndex;
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadManager;
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadNotificationHelper;
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadService;
|
|
||||||
import androidx.media3.exoplayer.scheduler.Scheduler;
|
|
||||||
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.api.onCheckDownload;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.CustomerDownload;
|
|
||||||
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
import io.reactivex.Observable;
|
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
||||||
import io.reactivex.disposables.Disposable;
|
|
||||||
import io.reactivex.schedulers.Schedulers;
|
|
||||||
|
|
||||||
|
|
||||||
@UnstableApi
|
|
||||||
public class MyDownloadService extends DownloadService {
|
|
||||||
private static final int FOREGROUND_NOTIFICATION_ID = 1;
|
|
||||||
private static final String CHANNEL_ID = "download_song_channel_id";
|
|
||||||
|
|
||||||
private static DownloadManager mDownloadManager;
|
|
||||||
|
|
||||||
public MyDownloadService() {
|
|
||||||
super(FOREGROUND_NOTIFICATION_ID,
|
|
||||||
DEFAULT_FOREGROUND_NOTIFICATION_UPDATE_INTERVAL,
|
|
||||||
CHANNEL_ID, // 通知渠道 ID
|
|
||||||
R.string.app_name, // 通知渠道名称
|
|
||||||
0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void init(Context context, StandaloneDatabaseProvider databaseProvider) {
|
|
||||||
if (mDownloadManager == null) {
|
|
||||||
SimpleCache downloadCache = MyDownloadCacheManager.getMyCache(databaseProvider);
|
|
||||||
DefaultHttpDataSource.Factory factory = new DefaultHttpDataSource.Factory();
|
|
||||||
Executor downloadExecutor = Runnable::run;
|
|
||||||
|
|
||||||
mDownloadManager = new DownloadManager(
|
|
||||||
context,
|
|
||||||
databaseProvider, // 数据库提供者
|
|
||||||
downloadCache,
|
|
||||||
factory, // 数据源工厂
|
|
||||||
downloadExecutor // 线程池
|
|
||||||
);
|
|
||||||
|
|
||||||
mDownloadManager.setMaxParallelDownloads(3); // 设置最大并行下载数
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized DownloadManager getMyDownloadManager() {
|
|
||||||
|
|
||||||
return mDownloadManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addDownloadListener(VMApplication vmApplication) {
|
|
||||||
mDownloadManager.addListener(new DownloadManager.Listener() {
|
|
||||||
@Override
|
|
||||||
public void onDownloadChanged(@NonNull DownloadManager downloadManager, Download download, @Nullable Exception finalException) {
|
|
||||||
String id = download.request.id;
|
|
||||||
|
|
||||||
|
|
||||||
if (download.state == Download.STATE_COMPLETED) {
|
|
||||||
// 下载完成
|
|
||||||
vmApplication.setDownloadChange(new Pair<>(true,download));
|
|
||||||
CommonUtils.LogMsg("----------------下载完成 id=" + id + "--thread=" + Thread.currentThread().getName());
|
|
||||||
updateDownloadUi(vmApplication);
|
|
||||||
|
|
||||||
} else if (download.state == Download.STATE_FAILED) {
|
|
||||||
// 下载失败
|
|
||||||
CommonUtils.LogMsg("----------------下载失败 id=" + id + "---finalException=" + finalException.getMessage());
|
|
||||||
|
|
||||||
vmApplication.setDownloadChange(new Pair<>(false,download));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDownloadRemoved(DownloadManager downloadManager, Download download) {
|
|
||||||
String id = download.request.id;
|
|
||||||
CommonUtils.LogMsg("----------------onDownloadRemoved id=" + id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void queryIsDownload(String videoId, onCheckDownload listener) {
|
|
||||||
Disposable subscribe = Observable.fromCallable(() -> {
|
|
||||||
// 不允许返回null,所以采用CustomerDownload类包装
|
|
||||||
DownloadIndex downloadIndex = mDownloadManager.getDownloadIndex();
|
|
||||||
Download download = downloadIndex.getDownload(videoId);
|
|
||||||
|
|
||||||
return new CustomerDownload(download, download != null);
|
|
||||||
|
|
||||||
}).subscribeOn(Schedulers.io())
|
|
||||||
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(listener::onHasDownload);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下载完成的数量增加
|
|
||||||
*
|
|
||||||
* @param vmApplication
|
|
||||||
*/
|
|
||||||
@UnstableApi
|
|
||||||
public static void updateDownloadUi(VMApplication vmApplication) {
|
|
||||||
Disposable subscribe = Observable.fromCallable(() -> {
|
|
||||||
// 第一部分操作:在IO线程
|
|
||||||
DownloadIndex downloadIndex = mDownloadManager.getDownloadIndex();
|
|
||||||
DownloadCursor downloads = downloadIndex.getDownloads(Download.STATE_COMPLETED);
|
|
||||||
|
|
||||||
return downloads;
|
|
||||||
})
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
// .observeOn(Schedulers.computation()) // 切换到计算线程
|
|
||||||
// .map(result -> {
|
|
||||||
// // 第二部分操作:在computation线程
|
|
||||||
// return result + " -> Step 2 completed";
|
|
||||||
// })
|
|
||||||
.observeOn(AndroidSchedulers.mainThread()) // 切换到主线程
|
|
||||||
.subscribe(finalResult -> {
|
|
||||||
// 最终结果处理:在主线程
|
|
||||||
Download curDownload = null;
|
|
||||||
// int count = finalResult.getCount();
|
|
||||||
// if (finalResult.moveToLast()) {
|
|
||||||
// curDownload = finalResult.getDownload();
|
|
||||||
// }
|
|
||||||
List<Download> downloadList = new ArrayList<>();
|
|
||||||
while (finalResult.moveToNext()) {
|
|
||||||
Download download = finalResult.getDownload();
|
|
||||||
downloadList.add(download);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CommonUtils.LogMsg("----------------下载总数量 -count=" + downloadList.size());
|
|
||||||
vmApplication.setDownloadData(downloadList);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
protected DownloadManager getDownloadManager() {
|
|
||||||
return getMyDownloadManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
protected Scheduler getScheduler() {
|
|
||||||
// 返回 null 表示不需要使用调度器
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Notification getForegroundNotification(List<Download> downloads, int notMetRequirements) {
|
|
||||||
// 构建用于显示下载进度的通知
|
|
||||||
return buildNotification(downloads, notMetRequirements);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Notification buildNotification(
|
|
||||||
List<Download> downloads, int notMetRequirements) {
|
|
||||||
|
|
||||||
return new DownloadNotificationHelper(this, CHANNEL_ID)
|
|
||||||
.buildProgressNotification(this, R.drawable.ic_download, null, null, downloads, notMetRequirements);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,421 +0,0 @@
|
|||||||
package com.hi.music.player.media3;
|
|
||||||
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.media3.common.MediaItem;
|
|
||||||
import androidx.media3.common.MediaMetadata;
|
|
||||||
import androidx.media3.common.PlaybackException;
|
|
||||||
import androidx.media3.common.Player;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.session.MediaController;
|
|
||||||
import androidx.media3.session.SessionToken;
|
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.api.MediaControllerListener;
|
|
||||||
import com.hi.music.player.api.MediaControllerStatusListener;
|
|
||||||
import com.hi.music.player.api.OnHasUrlAction;
|
|
||||||
import com.hi.music.player.api.onCheckDownload;
|
|
||||||
import com.hi.music.player.api.onPlayNextListener;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.CustomerDownload;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
|
||||||
import com.hi.music.player.network.RetrofitManager;
|
|
||||||
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
public class MyMediaControllerManager {
|
|
||||||
|
|
||||||
private static volatile MyMediaControllerManager myMediaControllerManagerInstance;
|
|
||||||
|
|
||||||
private MediaController mediaController;
|
|
||||||
|
|
||||||
private MediaControllerListener mListener;
|
|
||||||
|
|
||||||
private VMApplication mVmApplication;
|
|
||||||
|
|
||||||
|
|
||||||
//播放列表总数量
|
|
||||||
private List<ResponsePlayListInfo> playList;
|
|
||||||
|
|
||||||
public static MyMediaControllerManager getInstance() {
|
|
||||||
if (myMediaControllerManagerInstance == null) {
|
|
||||||
synchronized (RetrofitManager.class) {
|
|
||||||
if (myMediaControllerManagerInstance == null) {
|
|
||||||
myMediaControllerManagerInstance = new MyMediaControllerManager();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return myMediaControllerManagerInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(MediaControllerStatusListener statusListener) {
|
|
||||||
SessionToken sessionToken =
|
|
||||||
new SessionToken(MusicApplication.myApplication, new ComponentName(MusicApplication.myApplication, PlaybackService.class));
|
|
||||||
ListenableFuture<MediaController> controllerFuture =
|
|
||||||
new MediaController.Builder(MusicApplication.myApplication, sessionToken).buildAsync();
|
|
||||||
controllerFuture.addListener(() -> {
|
|
||||||
// Call controllerFuture.get() to retrieve the MediaController.
|
|
||||||
// MediaController implements the Player interface, so it can be
|
|
||||||
// attached to the PlayerView UI component.
|
|
||||||
// playerView.setPlayer(controllerFuture.get());
|
|
||||||
try {
|
|
||||||
mediaController = controllerFuture.get();
|
|
||||||
statusListener.onMediaControllerComplete(true);
|
|
||||||
CommonUtils.LogMsg("=-----mediaController+" + mediaController);
|
|
||||||
} catch (ExecutionException | InterruptedException e) {
|
|
||||||
CommonUtils.LogErrorMsg(e.getMessage());
|
|
||||||
statusListener.onMediaControllerComplete(false);
|
|
||||||
}
|
|
||||||
}, MoreExecutors.directExecutor());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addListener(VMApplication vmApplication, MediaControllerListener listener) {
|
|
||||||
mVmApplication = vmApplication;
|
|
||||||
mListener = listener;
|
|
||||||
mediaController.addListener(new Player.Listener() {
|
|
||||||
@Override
|
|
||||||
public void onPlayerError(PlaybackException error) {
|
|
||||||
mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_ERROR);
|
|
||||||
mVmApplication.setPlayStatus(MyValue.PLAY_STATUS_CODE_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPlaylistMetadataChanged(MediaMetadata mediaMetadata) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMediaItemTransition(@Nullable MediaItem mediaItem, int reason) {
|
|
||||||
//当前媒体项发生变化,切歌
|
|
||||||
if (mediaItem == null) {
|
|
||||||
//第二次进入PlayActitivity ,调用resetPlayList(),这里为null
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mListener.onChangeMusic(mediaItem);
|
|
||||||
mVmApplication.setPlayStatus(MyValue.PLAY_STATUS_CHANGE_MUSIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onIsPlayingChanged(boolean isPlaying) {
|
|
||||||
|
|
||||||
if (isPlaying) {
|
|
||||||
mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_PLAYING);
|
|
||||||
mVmApplication.setPlayStatus(MyValue.PLAY_STATUS_CODE_PLAYING);
|
|
||||||
// TODO: 2024/10/15 自动播放完成切歌到下一首播放没有触发这里请求下一首
|
|
||||||
checkUrl(false);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// 播放器暂停或停止
|
|
||||||
mListener.onPlayStatus(MyValue.PLAY_STATUS_CODE_PAUSE);
|
|
||||||
mVmApplication.setPlayStatus(MyValue.PLAY_STATUS_CODE_PAUSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPlaybackStateChanged(int playbackState) {
|
|
||||||
mListener.onPlayStatus(playbackState);
|
|
||||||
mVmApplication.setPlayStatus(playbackState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPositionDiscontinuity(Player.PositionInfo oldPosition, Player.PositionInfo newPosition, int reason) {
|
|
||||||
// 快进、快退等操作
|
|
||||||
// CommonUtils.LogMsg("=-----快进、快退+" + newPosition.positionMs);
|
|
||||||
// mediaControllerListener.onPlayStatus(playbackState);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkUrl(boolean playNextNow) {
|
|
||||||
if (mediaController.hasNextMediaItem()) {
|
|
||||||
int nextMediaItemIndex = mediaController.getNextMediaItemIndex();
|
|
||||||
onCallRequestUrl(nextMediaItemIndex, playNextNow, new OnHasUrlAction() {
|
|
||||||
@Override
|
|
||||||
public void onHasUrl() {
|
|
||||||
CommonUtils.LogMsg("-------------有有效URl--播放检查下一首 位置=" + nextMediaItemIndex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (mediaController.hasPreviousMediaItem()) {
|
|
||||||
int previousMediaItemIndex = mediaController.getPreviousMediaItemIndex();
|
|
||||||
onCallRequestUrl(previousMediaItemIndex, false, new OnHasUrlAction() {
|
|
||||||
@Override
|
|
||||||
public void onHasUrl() {
|
|
||||||
CommonUtils.LogMsg("-------------有有效URl--播放检查上一首 位置=" + previousMediaItemIndex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MediaController getMediaController() {
|
|
||||||
return mediaController;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 针对已经下载过的数据,从download构造出MediaItem 直接替换
|
|
||||||
* @param index
|
|
||||||
* @param mediaItem
|
|
||||||
*/
|
|
||||||
public void replaceMediaItem(int index, MediaItem mediaItem) {
|
|
||||||
mediaController.replaceMediaItem(index, mediaItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getContentPos() {
|
|
||||||
if (mediaController == null) return 0;
|
|
||||||
return mediaController.getContentPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getBufferPos() {
|
|
||||||
if (mediaController == null) return 0;
|
|
||||||
return mediaController.getBufferedPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
public MediaItem getCurMediaItem() {
|
|
||||||
return mediaController.getCurrentMediaItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean getIsPlaying() {
|
|
||||||
return mediaController.isPlaying();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurIndex() {
|
|
||||||
return mediaController.getCurrentMediaItemIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* //0 不循环、1 单曲循环、2 列表循环、
|
|
||||||
*
|
|
||||||
* @param mode
|
|
||||||
*/
|
|
||||||
public void setMode(int mode) {
|
|
||||||
switch (mode) {
|
|
||||||
case 0:
|
|
||||||
mediaController.setRepeatMode(Player.REPEAT_MODE_OFF);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
mediaController.setRepeatMode(Player.REPEAT_MODE_ONE);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
mediaController.setRepeatMode(Player.REPEAT_MODE_ALL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRepeatMode() {
|
|
||||||
return mediaController.getRepeatMode();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCurVideoId() {
|
|
||||||
MediaItem currentMediaItem = mediaController.getCurrentMediaItem();
|
|
||||||
if (currentMediaItem != null) {
|
|
||||||
return currentMediaItem.mediaId;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新播放列表中的音频url
|
|
||||||
*
|
|
||||||
* @param playUrl
|
|
||||||
*/
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
public void UpdateAudioUrl(ResponsePlayUrl playUrl, int index) {
|
|
||||||
for (int i = 0; i < mediaController.getMediaItemCount(); i++) {
|
|
||||||
MediaItem mediaItemAt = mediaController.getMediaItemAt(i);
|
|
||||||
if (mediaItemAt.mediaId.equals(playUrl.getVideoId())) {
|
|
||||||
|
|
||||||
MediaItem.Builder builder = mediaItemAt.buildUpon();
|
|
||||||
builder.setMediaId(playUrl.getVideoId());
|
|
||||||
builder.setUri(playUrl.getVideoUrlMedium());
|
|
||||||
builder.setCustomCacheKey(playUrl.getVideoUrlMedium());
|
|
||||||
//针对于,已经从分类合集列表页面进入播放页面的数据(只有小的封面图)
|
|
||||||
if (mediaItemAt.mediaMetadata.artworkUri == null) {
|
|
||||||
MediaMetadata.Builder builder1 = mediaItemAt.mediaMetadata.buildUpon();
|
|
||||||
builder1.setArtworkUri(Uri.parse(playUrl.getBigCovert()));
|
|
||||||
builder.setMediaMetadata(builder1.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
CharSequence title = mediaController.getMediaItemAt(i).mediaMetadata.title;
|
|
||||||
CommonUtils.LogMsg("-------------更新播放列表中的音频--id=" + playUrl.getVideoId());
|
|
||||||
mediaController.replaceMediaItem(i, builder.build());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlayList(List<ResponsePlayListInfo> playList) {
|
|
||||||
this.playList = playList;
|
|
||||||
addMusicPlayList(playList);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ResponsePlayListInfo> getPlayList() {
|
|
||||||
return playList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetPlayList() {
|
|
||||||
mediaController.clearMediaItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加播放列表(不带音频url)
|
|
||||||
* 注意没有setUri的不会被实际添加到mediaController(mediaController.getMediaItemCount())
|
|
||||||
* 这里setUri 一个占位
|
|
||||||
*
|
|
||||||
* @param listInfo
|
|
||||||
*/
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
public void addMusicPlayList(List<ResponsePlayListInfo> listInfo) {
|
|
||||||
playList = listInfo;
|
|
||||||
for (int i = 0; i < listInfo.size(); i++) {
|
|
||||||
ResponsePlayListInfo playInfo = listInfo.get(i);
|
|
||||||
|
|
||||||
MediaItem.Builder builder = new MediaItem.Builder();
|
|
||||||
String videoId = playInfo.getVideoId();
|
|
||||||
//唯一标识符
|
|
||||||
builder.setMediaId(videoId);
|
|
||||||
builder.setUri("-------test-----");
|
|
||||||
builder.setCustomCacheKey(videoId);
|
|
||||||
MediaMetadata.Builder MediaMetadata_builder = new MediaMetadata.Builder();
|
|
||||||
|
|
||||||
MediaMetadata_builder.setArtist(playInfo.getSingerName());
|
|
||||||
MediaMetadata_builder.setDescription(playInfo.getDuration());
|
|
||||||
MediaMetadata_builder.setDurationMs(playInfo.getDurationMs());
|
|
||||||
if (playInfo.getCovert() != null && !playInfo.getCovert().isEmpty())
|
|
||||||
MediaMetadata_builder.setArtworkUri(Uri.parse(playInfo.getCovert()));
|
|
||||||
MediaMetadata_builder.setTitle(playInfo.getSongTitle());
|
|
||||||
|
|
||||||
CommonUtils.LogMsg("----------添加播放列表 i=" + i + "---" + playInfo.getSingerName() + "-------VideoId=" + videoId + "---playInfo.getDuration()=" + playInfo.getDuration());
|
|
||||||
// MediaMetadata_builder.setRecordingYear(Integer.parseInt(playInfo.getYear()));
|
|
||||||
builder.setMediaMetadata(MediaMetadata_builder.build());
|
|
||||||
mediaController.addMediaItem(builder.build());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void addMusicPlayList(MediaItem mediaItem) {
|
|
||||||
mediaController.addMediaItem(mediaItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void play() {
|
|
||||||
if (!mediaController.isPlaying()) {
|
|
||||||
CommonUtils.LogMsg("-----------prepare");
|
|
||||||
mediaController.prepare();
|
|
||||||
mediaController.play();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pause() {
|
|
||||||
if (mediaController.isPlaying())
|
|
||||||
mediaController.pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop() {
|
|
||||||
if (mediaController.isPlaying())
|
|
||||||
mediaController.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playNext(onPlayNextListener listener) {
|
|
||||||
if (mediaController.hasNextMediaItem()) {
|
|
||||||
int nextMediaItemIndex = mediaController.getNextMediaItemIndex();
|
|
||||||
|
|
||||||
onCallRequestUrl(nextMediaItemIndex, true, new OnHasUrlAction() {
|
|
||||||
@Override
|
|
||||||
public void onHasUrl() {
|
|
||||||
mediaController.seekToNextMediaItem();
|
|
||||||
mediaController.play();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
listener.onPlayNext(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playPrevious() {
|
|
||||||
if (mediaController.hasPreviousMediaItem()) {
|
|
||||||
|
|
||||||
int previousMediaItemIndex = mediaController.getPreviousMediaItemIndex();
|
|
||||||
onCallRequestUrl(previousMediaItemIndex, true, new OnHasUrlAction() {
|
|
||||||
@Override
|
|
||||||
public void onHasUrl() {
|
|
||||||
mediaController.seekToPreviousMediaItem();
|
|
||||||
mediaController.play();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
mediaController.seekTo(0);
|
|
||||||
mediaController.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 播放指定播放列表位置的歌曲
|
|
||||||
*
|
|
||||||
* @param index
|
|
||||||
*/
|
|
||||||
public void playPositionMusic(int index) {
|
|
||||||
if (index >= mediaController.getMediaItemCount()) {
|
|
||||||
CommonUtils.LogErrorMsg("-------------数组越界");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
stop();
|
|
||||||
mediaController.seekTo(index, 0);
|
|
||||||
onCallRequestUrl(index, true, new OnHasUrlAction() {
|
|
||||||
@Override
|
|
||||||
public void onHasUrl() {
|
|
||||||
mediaController.play();
|
|
||||||
CommonUtils.LogMsg("-------------有有效URl--播放指定播放列表位置的歌曲 index=" + index);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
private void onCallRequestUrl(int index, boolean playNow, OnHasUrlAction action) {
|
|
||||||
MediaItem mediaItemAt = mediaController.getMediaItemAt(index);
|
|
||||||
boolean b = CommonUtils.hasValidUri(mediaItemAt);
|
|
||||||
if (!b) {
|
|
||||||
//查看
|
|
||||||
MyDownloadService.queryIsDownload(mediaItemAt.mediaId, new onCheckDownload() {
|
|
||||||
@Override
|
|
||||||
public void onHasDownload(CustomerDownload customerDownload) {
|
|
||||||
if (customerDownload.isDownload()) {
|
|
||||||
MediaItem mediaItem = CommonUtils.downloadToMediaItem(customerDownload.getDownloadData());
|
|
||||||
mediaController.replaceMediaItem(index, mediaItem);
|
|
||||||
CommonUtils.LogMsg("-------------请求URl 已经下载过 index" + index + "---playNow=" + playNow);
|
|
||||||
} else {
|
|
||||||
CommonUtils.LogMsg("-------------请求URl index" + index + "---playNow=" + playNow);
|
|
||||||
mListener.onRequestNextUri(mediaItemAt.mediaId, index, playNow);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
action.onHasUrl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
package com.hi.music.player.media3;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.database.StandaloneDatabaseProvider;
|
|
||||||
import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor;
|
|
||||||
import androidx.media3.datasource.cache.SimpleCache;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 播放缓存
|
|
||||||
*/
|
|
||||||
public class MyPlayCacheManager {
|
|
||||||
|
|
||||||
private static SimpleCache playCache;
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
public static SimpleCache getInitPlayCache(Context context) {
|
|
||||||
if (playCache == null) {
|
|
||||||
File cacheDir = new File(context.getCacheDir(), "media_cache");
|
|
||||||
long maxCacheSize = 100 * 1024 * 1024; // 缓存大小 100MB
|
|
||||||
StandaloneDatabaseProvider databaseProvider = new StandaloneDatabaseProvider(context);
|
|
||||||
playCache = new SimpleCache(cacheDir, new LeastRecentlyUsedCacheEvictor(maxCacheSize), databaseProvider);
|
|
||||||
MyDownloadService.init(context,databaseProvider);
|
|
||||||
}
|
|
||||||
return playCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SimpleCache getPlayCache() {
|
|
||||||
return playCache;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
package com.hi.music.player.media3;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.media3.common.Player;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.datasource.DataSource;
|
|
||||||
import androidx.media3.datasource.DataSpec;
|
|
||||||
import androidx.media3.datasource.DefaultDataSource;
|
|
||||||
import androidx.media3.datasource.ResolvingDataSource;
|
|
||||||
import androidx.media3.datasource.TransferListener;
|
|
||||||
import androidx.media3.datasource.cache.CacheDataSource;
|
|
||||||
import androidx.media3.exoplayer.DefaultLoadControl;
|
|
||||||
import androidx.media3.exoplayer.ExoPlayer;
|
|
||||||
|
|
||||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
|
||||||
import androidx.media3.exoplayer.source.MediaSource;
|
|
||||||
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
|
|
||||||
import androidx.media3.session.MediaSession;
|
|
||||||
import androidx.media3.session.MediaSessionService;
|
|
||||||
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
|
|
||||||
public class PlaybackService extends MediaSessionService {
|
|
||||||
private MediaSession mediaSession = null;
|
|
||||||
private ExoPlayer player;
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
super.onCreate();
|
|
||||||
|
|
||||||
DynamicMediaSourceFactory customMediaSourceFactory = new DynamicMediaSourceFactory(getCacheDataSourceFactory(this));
|
|
||||||
DefaultMediaSourceFactory defaultMediaSourceFactory1 = new DefaultMediaSourceFactory(getUrlFactory());
|
|
||||||
|
|
||||||
|
|
||||||
// 创建 DefaultLoadControl,配置缓冲参数
|
|
||||||
DefaultLoadControl loadControl = new DefaultLoadControl.Builder()
|
|
||||||
.setBufferDurationsMs(3000, // minBufferMs: 播放前的最小缓冲时间(毫秒)
|
|
||||||
300000, // maxBufferMs: 最大缓冲时间(毫秒)
|
|
||||||
3000, // bufferForPlaybackMs: 播放时的目标缓冲时间(毫秒)
|
|
||||||
2000) // bufferForPlaybackAfterRebufferMs: 重新缓冲后的缓冲时间(毫秒)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
|
|
||||||
CacheDataSource.Factory cacheDataSourceFactory = getCacheDataSourceFactory(this);
|
|
||||||
MediaSource.Factory mediaSourceFactory = new ProgressiveMediaSource.Factory(cacheDataSourceFactory);
|
|
||||||
CacheDataSource dataSource = cacheDataSourceFactory.createDataSource();
|
|
||||||
|
|
||||||
player = new ExoPlayer.Builder(this)
|
|
||||||
.setMediaSourceFactory(mediaSourceFactory)
|
|
||||||
.setLoadControl(loadControl)
|
|
||||||
.build();
|
|
||||||
mediaSession = new MediaSession.Builder(this, player)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建带缓存的数据源工厂
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
private CacheDataSource.Factory getCacheDataSourceFactory(Context context) {
|
|
||||||
DefaultDataSource.Factory factory = new DefaultDataSource.Factory(this);
|
|
||||||
return new CacheDataSource.Factory()
|
|
||||||
.setCache(MyPlayCacheManager.getInitPlayCache(context))
|
|
||||||
.setUpstreamDataSourceFactory(factory)
|
|
||||||
.setFlags(CacheDataSource.FLAG_BLOCK_ON_CACHE | CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
|
|
||||||
// .setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
private DataSource.Factory getUrlFactory() {
|
|
||||||
CommonUtils.LogMsg("--------getUrlFactory");
|
|
||||||
return new ResolvingDataSource.Factory(getCacheDataSourceFactory(this), new ResolvingDataSource.Resolver() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DataSpec resolveDataSpec(DataSpec dataSpec) {
|
|
||||||
|
|
||||||
CommonUtils.LogMsg("--------resolveDataSpec=" + dataSpec.key);
|
|
||||||
|
|
||||||
String string = "https://rr5---sn-ab5sznzy.googlevideo.com//videoplayback?expire=1730814877&ei=PM8pZ_37PL6b2_gP1LeTsQY&ip=146.19.167.8&id=o-AOdAohYUdM95I2jXmxqV5-JBeVgnMYAS3AKn2fsaiz72&itag=18&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&met=1730793277%2C&mh=Od&mm=31%2C29&mn=sn-ab5sznzy%2Csn-tt1e7nls&ms=au%2Crdu&mv=m&mvi=5&pl=24&rms=au%2Cau&gcr=us&initcwndbps=7066250&vprv=1&svpuc=1&xtags=heaudio%3Dtrue&mime=video%2Fmp4&rqh=1&cnr=14&ratebypass=yes&dur=181.394&lmt=1711913129189608&mt=1730792707&fvip=2&fexp=51312688%2C51326932&c=ANDROID&txp=4538434&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cgcr%2Cvprv%2Csvpuc%2Cxtags%2Cmime%2Crqh%2Ccnr%2Cratebypass%2Cdur%2Clmt&sig=AJfQdSswRgIhAMmdioipTMb9rGt1ZIzbhTPL0yWZGnuorRv7jOS9THllAiEAnkSJJhOkXt3SdMYmeNuRMEosaJl2H00SQxORzbbGRP4%3D&lsparams=met%2Cmh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Crms%2Cinitcwndbps&lsig=ACJ0pHgwRQIhANId6hdBj5z2g7IWnbCdzQ6MyYO_wit31Zaxh3VWahe7AiAIlubSJiPZP4deLNaBQ8eyT12Zf7nPkJ_ZZYBHeFf9XA%3D%3D";
|
|
||||||
return dataSpec.withUri(Uri.parse(dataSpec.key));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
|
|
||||||
return mediaSession;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTaskRemoved(@Nullable Intent rootIntent) {
|
|
||||||
Player player = mediaSession.getPlayer();
|
|
||||||
if (!player.getPlayWhenReady()
|
|
||||||
|| player.getMediaItemCount() == 0
|
|
||||||
|| player.getPlaybackState() == Player.STATE_ENDED) {
|
|
||||||
// Stop the service if not playing, continue playing in the background
|
|
||||||
// otherwise.
|
|
||||||
stopSelf();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
mediaSession.getPlayer().release();
|
|
||||||
mediaSession.release();
|
|
||||||
mediaSession = null;
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
package com.hi.music.player.media3;
|
|
||||||
|
|
||||||
import androidx.media3.common.MediaItem;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.datasource.DataSource;
|
|
||||||
import androidx.media3.exoplayer.drm.DrmSessionManagerProvider;
|
|
||||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
|
||||||
import androidx.media3.exoplayer.source.MediaSource;
|
|
||||||
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
|
|
||||||
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
|
|
||||||
|
|
||||||
public class testSourceFactory implements DataSource.Factory {
|
|
||||||
// private final CacheDataSource.Factory cacheDataSourceFactory;
|
|
||||||
// private final ExoPlayer player;
|
|
||||||
private DefaultMediaSourceFactory mediaSourceFactory;
|
|
||||||
|
|
||||||
// public DynamicMediaSourceFactory(DefaultMediaSourceFactory factory,CacheDataSource.Factory cacheDataSourceFactory, ExoPlayer exoPlayer) {
|
|
||||||
// this.cacheDataSourceFactory = cacheDataSourceFactory;
|
|
||||||
// this.player = exoPlayer;
|
|
||||||
// this.mediaSourceFactory = factory;
|
|
||||||
// }
|
|
||||||
public testSourceFactory(DefaultMediaSourceFactory factory) {
|
|
||||||
|
|
||||||
this.mediaSourceFactory = factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@UnstableApi
|
|
||||||
@Override
|
|
||||||
public DataSource createDataSource() {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// RetrofitManager.getInstance().getPlayUrl(mediaItem.mediaId, new RequestListener<ResponseBody>() {
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onFail(String errorMsg) {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onSuccess(ResponseBody data) {
|
|
||||||
// JSONObject jsonObject = CommonUtils.toJsonObject(data);
|
|
||||||
// if (jsonObject != null) {
|
|
||||||
// ResponsePlayUrl responsePlayUrl = JsonHelper.ResolvePlayUrlJson(jsonObject);
|
|
||||||
// if (responsePlayUrl == null) {
|
|
||||||
// // TODO: 2024/9/27
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// String uri = "";
|
|
||||||
// if (responsePlayUrl.getAudioUrlMedium() != null) {
|
|
||||||
// uri = responsePlayUrl.getAudioUrlMedium();
|
|
||||||
// } else {
|
|
||||||
// uri = responsePlayUrl.getAudioUrlLow();
|
|
||||||
// }
|
|
||||||
// CommonUtils.LogMsg("------createMediaSource----------="+mediaItem.mediaId+"---------"+uri);
|
|
||||||
// ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory)
|
|
||||||
// .createMediaSource(MediaItem.fromUri(uri));
|
|
||||||
// player.setMediaSource(mediaSource);
|
|
||||||
// player.prepare();
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,74 +0,0 @@
|
|||||||
package com.hi.music.player.network;
|
|
||||||
|
|
||||||
import io.reactivex.Observable;
|
|
||||||
import okhttp3.RequestBody;
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
import retrofit2.http.Body;
|
|
||||||
import retrofit2.http.GET;
|
|
||||||
import retrofit2.http.Header;
|
|
||||||
import retrofit2.http.Headers;
|
|
||||||
import retrofit2.http.POST;
|
|
||||||
import retrofit2.http.Query;
|
|
||||||
|
|
||||||
public interface MusicApi {
|
|
||||||
|
|
||||||
|
|
||||||
//首页数据
|
|
||||||
@POST("youtubei/v1/browse?prettyPrint=false")
|
|
||||||
@Headers("X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8")
|
|
||||||
Observable<ResponseBody> getHomeData(@Body RequestBody requestBody);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//首页更多数据
|
|
||||||
@POST("youtubei/v1/browse")
|
|
||||||
@Headers("X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8")
|
|
||||||
Observable<ResponseBody> getHomeMoreData(@Query("ctoken") String token,
|
|
||||||
@Query("continuation") String continuation,
|
|
||||||
@Query("type") String type,
|
|
||||||
@Query("itct") String itct,
|
|
||||||
@Query("prettyPrint") boolean prettyPrint,@Body RequestBody requestBody);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// X-Goog-FieldMask: contents.singleColumnMusicWatchNextResultsRenderer.tabbedRenderer.watchNextTabbedResultsRenderer.tabs.tabRenderer.content.musicQueueRenderer.content.playlistPanelRenderer(continuations,contents(automixPreviewVideoRenderer,playlistPanelVideoRenderer(title,navigationEndpoint,longBylineText,shortBylineText,thumbnail,lengthText)))
|
|
||||||
|
|
||||||
//获取播放列表(返回的是每首歌曲详情列表)
|
|
||||||
@POST("youtubei/v1/next?prettyPrint=false")
|
|
||||||
@Headers("X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8")
|
|
||||||
Observable<ResponseBody> getMusicPlayPage(@Header("X-Goog-FieldMask") String customHeader, @Body RequestBody requestBody);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// "X-Goog-FieldMask:playabilityStatus.status,playerConfig.audioConfig,streamingData.adaptiveFormats,videoDetails.videoId,videoDetails.thumbnail"
|
|
||||||
//获取播放音频资源url "X-Goog-Api-Key:AIzaSyC9XL3ZjwddXya6X74dJOCTL-WEYFDNX30"
|
|
||||||
@POST("youtubei/v1/player?prettyPrint=false")
|
|
||||||
@Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8"})
|
|
||||||
Observable<ResponseBody> getMusicPlayUrl(@Body RequestBody requestBody);
|
|
||||||
|
|
||||||
|
|
||||||
//首页分类项下的播放列表子页面 (类型1:单曲合集、2:专辑、3:音乐视频合集 ,不同类型返回数据结构有区别)
|
|
||||||
@POST("youtubei/v1/browse?prettyPrint=false")
|
|
||||||
@Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8"})
|
|
||||||
Observable<ResponseBody> getCategoryList(@Body RequestBody requestBody);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@POST("youtubei/v1/music/get_search_suggestions?prettyPrint=false")
|
|
||||||
@Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8",
|
|
||||||
"X-Goog-FieldMask:contents.searchSuggestionsSectionRenderer.contents.searchSuggestionRenderer.navigationEndpoint.searchEndpoint.query"})
|
|
||||||
Observable<ResponseBody> getSearchSuggestion(@Body RequestBody requestBody);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// "X-Goog-FieldMask:contents.tabbedSearchResultsRenderer.tabs.tabRenderer.content.sectionListRenderer.contents.musicShelfRenderer(continuations,contents.musicResponsiveListItemRenderer(flexColumns,fixedColumns,thumbnail,navigationEndpoint))"
|
|
||||||
@POST("youtubei/v1/search?prettyPrint=false")
|
|
||||||
@Headers({"X-Goog-Api-Key:AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8"})
|
|
||||||
Observable<ResponseBody> getSearch(@Body RequestBody requestBody);
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
package com.hi.music.player.network;
|
|
||||||
|
|
||||||
import com.hi.music.player.api.RequestListener;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import io.reactivex.Observer;
|
|
||||||
import io.reactivex.disposables.Disposable;
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
public class ObserverWrapper<T> implements Observer<T> {
|
|
||||||
private RequestListener<T> requestListener;
|
|
||||||
|
|
||||||
public ObserverWrapper(RequestListener<T> requestListener) {
|
|
||||||
this.requestListener = requestListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSubscribe(Disposable d) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNext(T t) {
|
|
||||||
ResponseBody responseBody = (ResponseBody) t;
|
|
||||||
JSONObject jsonObject = CommonUtils.toJsonObject(responseBody);
|
|
||||||
try {
|
|
||||||
if (jsonObject != null) {
|
|
||||||
if (jsonObject.has("playabilityStatus")) {
|
|
||||||
String status = jsonObject.getJSONObject("playabilityStatus").getString("status");
|
|
||||||
if (!status.equals("OK")) {
|
|
||||||
requestListener.onFail("");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
requestListener.onSuccess(jsonObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (JSONException e) {
|
|
||||||
requestListener.onFail(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable e) {
|
|
||||||
CommonUtils.LogMsg("----------onError---" + e.getMessage());
|
|
||||||
requestListener.onFail(e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onComplete() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,212 +0,0 @@
|
|||||||
package com.hi.music.player.network;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.api.RequestListener;
|
|
||||||
import com.hi.music.player.javabean.requestbody.BodyHome;
|
|
||||||
import com.hi.music.player.javabean.requestbody.BodyPlay;
|
|
||||||
import com.hi.music.player.javabean.requestbody.BodyPlayUrl;
|
|
||||||
import com.hi.music.player.javabean.requestbody.BodySearch;
|
|
||||||
import com.hi.music.player.javabean.requestbody.BodySearchSuggestion;
|
|
||||||
import com.hi.music.player.javabean.requestbody.child.Client;
|
|
||||||
import com.hi.music.player.javabean.requestbody.child.ContextBody;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
||||||
import io.reactivex.schedulers.Schedulers;
|
|
||||||
import okhttp3.MediaType;
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import okhttp3.RequestBody;
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
import okhttp3.logging.HttpLoggingInterceptor;
|
|
||||||
import retrofit2.Retrofit;
|
|
||||||
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
|
|
||||||
import retrofit2.converter.gson.GsonConverterFactory;
|
|
||||||
|
|
||||||
public class RetrofitManager {
|
|
||||||
|
|
||||||
private String base_Host = "https://music.youtube.com/";
|
|
||||||
|
|
||||||
private String base_Host_test = "https://rr2---sn-tt1e7nlz.googlevideo.com/";
|
|
||||||
private static volatile RetrofitManager REQUEST_MANAGER;
|
|
||||||
|
|
||||||
private Retrofit retrofit;
|
|
||||||
public MediaType JSON = MediaType.get("application/json; charset=utf-8");
|
|
||||||
private MusicApi musicApi;
|
|
||||||
|
|
||||||
private String header1 = "playlistPanelVideoRenderer(title,navigationEndpoint,longBylineText,shortBylineText,thumbnail,lengthText)";
|
|
||||||
private String header = "contents.singleColumnMusicWatchNextResultsRenderer.tabbedRenderer.watchNextTabbedResultsRenderer.tabs.tabRenderer.content.musicQueueRenderer.content.playlistPanelRenderer(continuations,contents(automixPreviewVideoRenderer," + header1 + "))";
|
|
||||||
|
|
||||||
private RetrofitManager() {
|
|
||||||
|
|
||||||
musicApi = getRetrofit().create(MusicApi.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// public <T> T getService(Class<T> cls){
|
|
||||||
// return getRetrofit().create(cls);
|
|
||||||
// }
|
|
||||||
private synchronized Retrofit getRetrofit() {
|
|
||||||
if (retrofit == null) {
|
|
||||||
long DEFAULT_TIMEOUT = 5;
|
|
||||||
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
|
|
||||||
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
|
||||||
OkHttpClient client = new OkHttpClient.Builder()
|
|
||||||
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
|
||||||
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
|
||||||
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
|
||||||
.addInterceptor(httpLoggingInterceptor)
|
|
||||||
.build();
|
|
||||||
retrofit = new Retrofit.Builder()
|
|
||||||
.baseUrl(base_Host)
|
|
||||||
.client(client)
|
|
||||||
.addConverterFactory(GsonConverterFactory.create())
|
|
||||||
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
return retrofit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RetrofitManager getInstance() {
|
|
||||||
if (REQUEST_MANAGER == null) {
|
|
||||||
synchronized (RetrofitManager.class) { //锁,防止线程问题
|
|
||||||
if (REQUEST_MANAGER == null) {
|
|
||||||
REQUEST_MANAGER = new RetrofitManager();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return REQUEST_MANAGER;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void getHomeData(RequestListener<ResponseBody> requestListener) {
|
|
||||||
BodyHome bodyHome = new BodyHome();
|
|
||||||
Gson gson = new Gson();
|
|
||||||
String s = gson.toJson(bodyHome);
|
|
||||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
|
||||||
musicApi.getHomeData(requestBody)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.unsubscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getHomeMoreData(String continuation, String itct, String visitorData, RequestListener<ResponseBody> requestListener) {
|
|
||||||
BodyHome bodyHome = new BodyHome();
|
|
||||||
bodyHome.getContext().getClient().setVisitorData(visitorData);
|
|
||||||
Gson gson = new Gson();
|
|
||||||
String s = gson.toJson(bodyHome);
|
|
||||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
|
||||||
|
|
||||||
HashMap<String, String> stringHashMap = new HashMap<>();
|
|
||||||
stringHashMap.put("ctoken", continuation);
|
|
||||||
stringHashMap.put("continuation", continuation);
|
|
||||||
stringHashMap.put("type", "next");
|
|
||||||
stringHashMap.put("itct", itct);
|
|
||||||
stringHashMap.put("prettyPrint", "false");
|
|
||||||
musicApi.getHomeMoreData(continuation, continuation, "next", itct, false, requestBody)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.unsubscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void getPlayList(String params, String playlistId, String videoId, String musicVideoType, RequestListener<ResponseBody> requestListener) {
|
|
||||||
BodyPlay bodyPlay = new BodyPlay();
|
|
||||||
bodyPlay.setParams(params);
|
|
||||||
bodyPlay.setPlaylistId(playlistId);
|
|
||||||
bodyPlay.setVideoId(videoId);
|
|
||||||
bodyPlay.getWatchEndpointMusicSupportedConfigs().setMusicVideoType(musicVideoType);
|
|
||||||
Gson gson = new Gson();
|
|
||||||
String s = gson.toJson(bodyPlay);
|
|
||||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
|
||||||
musicApi.getMusicPlayPage(header, requestBody)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.unsubscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void getPlayUrl(String videoId, RequestListener<ResponseBody> requestListener) {
|
|
||||||
BodyPlayUrl bodyPlay = new BodyPlayUrl();
|
|
||||||
bodyPlay.setVideoId(videoId);
|
|
||||||
Client client = bodyPlay.getContext().getClient();
|
|
||||||
client.setClientName("ANDROID");
|
|
||||||
client.setClientVersion("19.05.36");
|
|
||||||
client.setPlatform("DESKTOP");
|
|
||||||
String visitorData = MusicApplication.getVisitorData();
|
|
||||||
// client.setVisitorData("CgtWN1RXaURPN3LNZyiZK9e4BjIKCgJVUXIEGgAgPW%3D%3D");
|
|
||||||
client.setVisitorData(visitorData);
|
|
||||||
bodyPlay.getContext().getThirdParty().setEmbedUrl("https://www.youtube.com/watch?v="+videoId);
|
|
||||||
|
|
||||||
|
|
||||||
Gson gson = new Gson();
|
|
||||||
String s = gson.toJson(bodyPlay);
|
|
||||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
|
||||||
musicApi.getMusicPlayUrl(requestBody)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.unsubscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(new ObserverWrapper<ResponseBody>(requestListener));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void getCategoryList(String browserId, RequestListener<ResponseBody> requestListener) {
|
|
||||||
BodyHome bodyHome = new BodyHome();
|
|
||||||
bodyHome.setBrowseId(browserId);
|
|
||||||
// bodyHome.setBrowseId("VLPLI-asvmHZWNo_xjMMfD_v2O2lTyCdrjaK");
|
|
||||||
|
|
||||||
Client client = bodyHome.getContext().getClient();
|
|
||||||
client.setClientVersion("1.20240506.01.00");
|
|
||||||
|
|
||||||
|
|
||||||
Gson gson = new Gson();
|
|
||||||
String s = gson.toJson(bodyHome);
|
|
||||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
|
||||||
|
|
||||||
|
|
||||||
musicApi.getCategoryList(requestBody)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.unsubscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(new ObserverWrapper<>(requestListener));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void getSearchSuggestion(String input, RequestListener<ResponseBody> requestListener) {
|
|
||||||
BodySearchSuggestion body = new BodySearchSuggestion();
|
|
||||||
body.setInput(input);
|
|
||||||
Client client = body.getContext().getClient();
|
|
||||||
client.setClientVersion("1.20240506.01.00");
|
|
||||||
Gson gson = new Gson();
|
|
||||||
String s = gson.toJson(body);
|
|
||||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
|
||||||
musicApi.getSearchSuggestion(requestBody)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.unsubscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(new ObserverWrapper<>(requestListener));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void getSearch(String query, RequestListener<ResponseBody> requestListener) {
|
|
||||||
BodySearch body = new BodySearch();
|
|
||||||
body.setQuery(query);
|
|
||||||
Client client = body.getContext().getClient();
|
|
||||||
client.setClientVersion("1.20240506.01.00");
|
|
||||||
Gson gson = new Gson();
|
|
||||||
String s = gson.toJson(body);
|
|
||||||
RequestBody requestBody = RequestBody.Companion.create(s, JSON);
|
|
||||||
musicApi.getSearch(requestBody)
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.unsubscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(new ObserverWrapper<>(requestListener));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,109 +0,0 @@
|
|||||||
package com.hi.music.player.objectbox;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.hi.music.player.api.LikeSongListener;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.BoxLikeSong;
|
|
||||||
import com.hi.music.player.javabean.BoxLikeSong_;
|
|
||||||
import com.hi.music.player.javabean.MyObjectBox;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import io.objectbox.Box;
|
|
||||||
import io.objectbox.BoxStore;
|
|
||||||
import io.objectbox.android.AndroidScheduler;
|
|
||||||
import io.objectbox.query.Query;
|
|
||||||
import io.objectbox.query.QueryBuilder;
|
|
||||||
import io.objectbox.reactive.DataObserver;
|
|
||||||
import io.objectbox.reactive.DataSubscription;
|
|
||||||
import io.objectbox.reactive.DataSubscriptionList;
|
|
||||||
|
|
||||||
public class ObjectBoxManager {
|
|
||||||
|
|
||||||
private static BoxStore boxStore;
|
|
||||||
|
|
||||||
private static Box<BoxLikeSong> boxLikeSongBox;
|
|
||||||
|
|
||||||
private static DataSubscription observer;
|
|
||||||
|
|
||||||
|
|
||||||
public static void init(Context context) {
|
|
||||||
boxStore = MyObjectBox.builder().androidContext(context).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Box<BoxLikeSong> getObjectBoxLike() {
|
|
||||||
if (boxLikeSongBox == null) {
|
|
||||||
return boxStore.boxFor(BoxLikeSong.class);
|
|
||||||
}
|
|
||||||
return boxLikeSongBox;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DataSubscription setLikeDataListener(LikeSongListener listener) {
|
|
||||||
Query<BoxLikeSong> build = getObjectBoxLike().query().build();
|
|
||||||
return build.subscribe(new DataSubscriptionList())
|
|
||||||
.on(AndroidScheduler.mainThread())
|
|
||||||
.observer(new DataObserver<List<BoxLikeSong>>() {
|
|
||||||
@Override
|
|
||||||
public void onData(@NonNull List<BoxLikeSong> data) {
|
|
||||||
CommonUtils.LogMsg("------ProfileFragment 11data=" + data.size());
|
|
||||||
listener.onLikeSongChange(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void insertOrUpdateLike(BoxLikeSong boxLikeSong) {
|
|
||||||
Box<BoxLikeSong> objectBoxLike = getObjectBoxLike();
|
|
||||||
String videoId = boxLikeSong.getVideoId();
|
|
||||||
BoxLikeSong first = objectBoxLike.query()
|
|
||||||
.equal(BoxLikeSong_.videoId, videoId, QueryBuilder.StringOrder.CASE_SENSITIVE)
|
|
||||||
.build()
|
|
||||||
.findFirst();
|
|
||||||
if (first == null) {
|
|
||||||
CommonUtils.LogErrorMsg("-----------添加 song=" + boxLikeSong.getSongName() + "---videoId=" + videoId);
|
|
||||||
objectBoxLike.put(boxLikeSong);
|
|
||||||
} else {
|
|
||||||
CommonUtils.LogErrorMsg("-----------已经存在 song=" + boxLikeSong.getSongName() + "---videoId=" + videoId);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void deleteLike(BoxLikeSong boxLikeSong) {
|
|
||||||
Box<BoxLikeSong> objectBoxLike = getObjectBoxLike();
|
|
||||||
String videoId = boxLikeSong.getVideoId();
|
|
||||||
List<BoxLikeSong> boxLikeSongs = objectBoxLike.query()
|
|
||||||
.equal(BoxLikeSong_.videoId, videoId, QueryBuilder.StringOrder.CASE_SENSITIVE)
|
|
||||||
.build()
|
|
||||||
.find();
|
|
||||||
for (BoxLikeSong song : boxLikeSongs) {
|
|
||||||
objectBoxLike.remove(song);
|
|
||||||
CommonUtils.LogErrorMsg("-------onLikeSongChange-deleteLike song=" + song.getSongName());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<BoxLikeSong> queryAllLike() {
|
|
||||||
return getObjectBoxLike().query()
|
|
||||||
.build()
|
|
||||||
.find();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean queryIsLike(String videoId) {
|
|
||||||
Box<BoxLikeSong> objectBoxLike = getObjectBoxLike();
|
|
||||||
BoxLikeSong first = objectBoxLike.query()
|
|
||||||
.equal(BoxLikeSong_.videoId, videoId, QueryBuilder.StringOrder.CASE_SENSITIVE)
|
|
||||||
.build()
|
|
||||||
.findFirst();
|
|
||||||
if (first == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -5,8 +5,6 @@ import android.os.CountDownTimer;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.hi.music.player.databinding.ActivityAsplashBinding;
|
import com.hi.music.player.databinding.ActivityAsplashBinding;
|
||||||
import com.hi.music.player.firebase.RemoteConfigJava;
|
|
||||||
import com.hi.music.player.firebase.Sp;
|
|
||||||
|
|
||||||
|
|
||||||
public class A_SplashActivity extends BaseActivity<ActivityAsplashBinding> {
|
public class A_SplashActivity extends BaseActivity<ActivityAsplashBinding> {
|
||||||
@ -76,13 +74,7 @@ public class A_SplashActivity extends BaseActivity<ActivityAsplashBinding> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void enterHome() {
|
private void enterHome() {
|
||||||
String stringValue = Sp.getInstance().getStringValue(RemoteConfigJava.key_open_type);
|
Intent intent = new Intent(A_SplashActivity.this, A_HomeActivity.class);
|
||||||
Intent intent;
|
|
||||||
if(stringValue.equals(RemoteConfigJava.value_open_type_0)){
|
|
||||||
intent = new Intent(A_SplashActivity.this, A_HomeActivity.class);
|
|
||||||
}else {
|
|
||||||
intent = new Intent(A_SplashActivity.this, HomeActivity.class);
|
|
||||||
}
|
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
finish();
|
finish();
|
||||||
|
|
||||||
|
|||||||
@ -1,44 +1,23 @@
|
|||||||
package com.hi.music.player.ui.activity;
|
package com.hi.music.player.ui.activity;
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.view.WindowCompat;
|
import androidx.core.view.WindowCompat;
|
||||||
import androidx.core.view.WindowInsetsControllerCompat;
|
import androidx.core.view.WindowInsetsControllerCompat;
|
||||||
import androidx.lifecycle.Observer;
|
|
||||||
import androidx.lifecycle.ViewModel;
|
import androidx.lifecycle.ViewModel;
|
||||||
import androidx.media3.common.MediaItem;
|
|
||||||
import androidx.media3.common.Player;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.viewbinding.ViewBinding;
|
import androidx.viewbinding.ViewBinding;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.api.onPlayNextListener;
|
|
||||||
import com.hi.music.player.databinding.ActivityBaseBinding;
|
import com.hi.music.player.databinding.ActivityBaseBinding;
|
||||||
import com.hi.music.player.databinding.LayoutPanelBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.helper.ViewModelScope;
|
|
||||||
import com.hi.music.player.media3.MyMediaControllerManager;
|
|
||||||
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
|
|
||||||
|
|
||||||
public abstract class BaseActivity<T extends ViewBinding> extends AppCompatActivity implements View.OnClickListener {
|
public abstract class BaseActivity<T extends ViewBinding> extends AppCompatActivity implements View.OnClickListener {
|
||||||
|
|
||||||
private final ViewModelScope mViewModelScope = new ViewModelScope();
|
// private final ViewModelScope mViewModelScope = new ViewModelScope();
|
||||||
|
|
||||||
protected T vb;
|
protected T vb;
|
||||||
|
|
||||||
@ -47,8 +26,8 @@ public abstract class BaseActivity<T extends ViewBinding> extends AppCompatActiv
|
|||||||
protected View mView;
|
protected View mView;
|
||||||
private ActivityBaseBinding rootVb;
|
private ActivityBaseBinding rootVb;
|
||||||
|
|
||||||
protected VMApplication vmApplication;
|
// protected VMApplication vmApplication;
|
||||||
protected MyMediaControllerManager mediaControllerManager;
|
// protected MyMediaControllerManager mediaControllerManager;
|
||||||
|
|
||||||
private Handler mHandler;
|
private Handler mHandler;
|
||||||
private Runnable mRunnable;
|
private Runnable mRunnable;
|
||||||
@ -64,11 +43,10 @@ public abstract class BaseActivity<T extends ViewBinding> extends AppCompatActiv
|
|||||||
window = getWindow();
|
window = getWindow();
|
||||||
decorView = window.getDecorView();
|
decorView = window.getDecorView();
|
||||||
mView = decorView.getRootView();
|
mView = decorView.getRootView();
|
||||||
vmApplication = getApplicationScopeViewModel(VMApplication.class);
|
// vmApplication = getApplicationScopeViewModel(VMApplication.class);
|
||||||
mediaControllerManager = MyMediaControllerManager.getInstance();
|
// mediaControllerManager = MyMediaControllerManager.getInstance();
|
||||||
|
|
||||||
|
|
||||||
if (showPanel())
|
|
||||||
initPanel();
|
|
||||||
setStatusBar();
|
setStatusBar();
|
||||||
if (isFullScreen()) {
|
if (isFullScreen()) {
|
||||||
// ImmersionBar.with(this).init();//设置沉浸式效果
|
// ImmersionBar.with(this).init();//设置沉浸式效果
|
||||||
@ -94,133 +72,11 @@ public abstract class BaseActivity<T extends ViewBinding> extends AppCompatActiv
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void initPanel() {
|
|
||||||
LayoutPanelBinding panelVb = LayoutPanelBinding.inflate(getLayoutInflater());
|
|
||||||
View panelView = panelVb.getRoot();
|
|
||||||
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
|
|
||||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
|
||||||
CommonUtils.dpToPx(74)
|
|
||||||
);
|
|
||||||
initProgressHandler(panelVb);
|
|
||||||
panelVb.imPlay.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
panelVb.imPlay.setSelected(!panelVb.imPlay.isSelected());
|
|
||||||
if (panelVb.imPlay.isSelected()) {
|
|
||||||
mediaControllerManager.play();
|
|
||||||
} else {
|
|
||||||
mediaControllerManager.pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
panelVb.imNext.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
mediaControllerManager.playNext(new onPlayNextListener() {
|
|
||||||
@Override
|
|
||||||
public void onPlayNext(boolean hasNext) {
|
|
||||||
if (!hasNext) {
|
|
||||||
Toast.makeText(MusicApplication.myApplication, getString(R.string.no_next_song_yet), Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
panelVb.layoutPanel.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Intent intent = new Intent(MusicApplication.myApplication, PlayActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_PANEL);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this instanceof HomeActivity) {
|
|
||||||
layoutParams.setMargins(CommonUtils.dpToPx(22), 0, CommonUtils.dpToPx(22), CommonUtils.dpToPx(82));
|
|
||||||
} else {
|
|
||||||
layoutParams.setMargins(CommonUtils.dpToPx(22), 0, CommonUtils.dpToPx(22), CommonUtils.dpToPx(10));
|
|
||||||
}
|
|
||||||
|
|
||||||
layoutParams.gravity = Gravity.BOTTOM;
|
|
||||||
vmApplication.playStatus.observe(this, new Observer<Integer>() {
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
|
||||||
public void onChanged(Integer integer) {
|
|
||||||
CommonUtils.LogMsg("----------面板 播放状态更新=" + integer);
|
|
||||||
if (panelView.getParent() == null) {
|
|
||||||
CommonUtils.LogMsg("----------显示面板");
|
|
||||||
rootVb.frameLayout.addView(panelView, layoutParams);
|
|
||||||
mHandler.post(mRunnable);
|
|
||||||
}
|
|
||||||
MediaItem currentMediaItem = mediaControllerManager.getCurMediaItem();
|
|
||||||
if(currentMediaItem!= null){
|
|
||||||
Uri artworkUri = currentMediaItem.mediaMetadata.artworkUri;
|
|
||||||
CharSequence title = currentMediaItem.mediaMetadata.title;
|
|
||||||
CharSequence artist = currentMediaItem.mediaMetadata.artist;
|
|
||||||
|
|
||||||
if (currentMediaItem.mediaMetadata.durationMs != null) {
|
|
||||||
long durationMs = currentMediaItem.mediaMetadata.durationMs;
|
|
||||||
panelVb.circularPb.setMaxProgress((int) durationMs);
|
|
||||||
}
|
|
||||||
if(artworkUri!= null){
|
|
||||||
CommonUtils.LogMsg("----------artworkUri="+artworkUri.toString());
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.load(artworkUri.toString())
|
|
||||||
.transform(new CircleCrop())
|
|
||||||
.into(panelVb.image);
|
|
||||||
}
|
|
||||||
panelVb.title.setText(title);
|
|
||||||
panelVb.singer.setText(artist);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (integer) {
|
|
||||||
case Player.STATE_IDLE:
|
|
||||||
|
|
||||||
case Player.STATE_ENDED:
|
|
||||||
case Player.STATE_READY:
|
|
||||||
|
|
||||||
case MyValue.PLAY_STATUS_CODE_PAUSE:
|
|
||||||
case Player.STATE_BUFFERING:
|
|
||||||
case MyValue.PLAY_STATUS_CODE_ERROR:
|
|
||||||
|
|
||||||
//快进没有缓冲的时候触发
|
|
||||||
//播放完成
|
|
||||||
panelVb.imPlay.setSelected(false);
|
|
||||||
break;
|
|
||||||
case MyValue.PLAY_STATUS_CHANGE_MUSIC:
|
|
||||||
case MyValue.PLAY_STATUS_CODE_PLAYING:
|
|
||||||
panelVb.imPlay.setSelected(true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void initProgressHandler(LayoutPanelBinding panelBinding) {
|
|
||||||
mHandler = new Handler();
|
|
||||||
mRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
updatePlaybackProgress(panelBinding);
|
|
||||||
mHandler.postDelayed(this, 1000);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updatePlaybackProgress(LayoutPanelBinding panelBinding) {
|
|
||||||
// 获取当前播放位置
|
|
||||||
long contentPos = mediaControllerManager.getContentPos();
|
|
||||||
long bufferPos = mediaControllerManager.getBufferPos();
|
|
||||||
|
|
||||||
// CommonUtils.LogMsg("---------播放进度-----contentPos=" + contentPos + "-----缓冲进度=" + bufferPos);
|
|
||||||
panelBinding.circularPb.setProgress((int) contentPos);
|
|
||||||
}
|
|
||||||
private void setStatusBar() {
|
private void setStatusBar() {
|
||||||
//深色模式
|
//深色模式
|
||||||
WindowInsetsControllerCompat insetsController = WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView());
|
WindowInsetsControllerCompat insetsController = WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView());
|
||||||
@ -234,13 +90,13 @@ public abstract class BaseActivity<T extends ViewBinding> extends AppCompatActiv
|
|||||||
mView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
mView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <K extends ViewModel> K getActivityScopeViewModel(@NonNull Class<K> modelClass) {
|
// protected <K extends ViewModel> K getActivityScopeViewModel(@NonNull Class<K> modelClass) {
|
||||||
return mViewModelScope.getActivityScopeViewModel(this, modelClass);
|
// return mViewModelScope.getActivityScopeViewModel(this, modelClass);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected <K extends ViewModel> K getApplicationScopeViewModel(@NonNull Class<K> modelClass) {
|
// protected <K extends ViewModel> K getApplicationScopeViewModel(@NonNull Class<K> modelClass) {
|
||||||
return mViewModelScope.getApplicationScopeViewModel(modelClass);
|
// return mViewModelScope.getApplicationScopeViewModel(modelClass);
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
|
|||||||
@ -1,259 +0,0 @@
|
|||||||
package com.hi.music.player.ui.activity;
|
|
||||||
|
|
||||||
import static com.bumptech.glide.request.RequestOptions.bitmapTransform;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.lifecycle.Observer;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.graphics.drawable.GradientDrawable;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.BitmapTransitionOptions;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.adapter.AdapterCategoryList;
|
|
||||||
import com.hi.music.player.api.HomeItemClickListener;
|
|
||||||
import com.hi.music.player.api.onImageColorListener;
|
|
||||||
import com.hi.music.player.databinding.ActivityCategoryListBinding;
|
|
||||||
import com.hi.music.player.databinding.ActivityHomeBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseCategoryList;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseCategory;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
|
|
||||||
import com.hi.music.player.ui.fragmnt.viewmodel.VMCategoryList;
|
|
||||||
import com.hi.music.player.ui.fragmnt.viewmodel.VMHome;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import jp.wasabeef.glide.transformations.BlurTransformation;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 音乐合集或者专辑列表页面
|
|
||||||
*/
|
|
||||||
public class CategoryListActivity extends BaseActivity<ActivityCategoryListBinding> implements HomeItemClickListener {
|
|
||||||
|
|
||||||
|
|
||||||
private VMCategoryList vm;
|
|
||||||
// private VMApplication vmApplication;
|
|
||||||
|
|
||||||
private ResponseCategoryList mCategoryList;
|
|
||||||
private String mPageType;
|
|
||||||
private String twoSubtitle;
|
|
||||||
private String browseId;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ActivityCategoryListBinding getViewBinding() {
|
|
||||||
return ActivityCategoryListBinding.inflate(getLayoutInflater());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreateInit() {
|
|
||||||
vm = getActivityScopeViewModel(VMCategoryList.class);
|
|
||||||
// vmApplication = getApplicationScopeViewModel(VMApplication.class);
|
|
||||||
Intent intent = getIntent();
|
|
||||||
if (intent == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mPageType= intent.getStringExtra(MyValue.KEY_CATEGORY_LIST_TYPE);
|
|
||||||
twoSubtitle = intent.getStringExtra(MyValue.KEY_CATEGORY_LIST_SINGER_NAME);
|
|
||||||
browseId = intent.getStringExtra(MyValue.KEY_CATEGORY_LIST_BROWSER_ID);
|
|
||||||
|
|
||||||
vb.pbLoading.setVisibility(View.VISIBLE);
|
|
||||||
vm.getList(browseId);
|
|
||||||
vm.data.observe(this, new Observer<ResponseCategoryList>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(ResponseCategoryList responseCategoryList) {
|
|
||||||
if (responseCategoryList == null) {
|
|
||||||
vb.pbLoading.setVisibility(View.GONE);
|
|
||||||
updateErrorLayout(getString(R.string.playList_loading_failed),true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mCategoryList = responseCategoryList;
|
|
||||||
loadInfo(mCategoryList);
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
private void updateErrorLayout(String msg, boolean isShow) {
|
|
||||||
if (isShow)
|
|
||||||
vb.layoutError.linearRetry.setVisibility(View.VISIBLE);
|
|
||||||
else vb.layoutError.linearRetry.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
if(msg!= null&&!msg.isEmpty()){
|
|
||||||
vb.layoutError.tvErrorMsg.setText(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
protected void onInitClick() {
|
|
||||||
vb.imBack.setOnClickListener(this);
|
|
||||||
vb.btnPlay.setOnClickListener(this);
|
|
||||||
vb.layoutError.tvRetry.setOnClickListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFullScreen() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean statusBarLight() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showPanel() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (v.equals(vb.imBack)) {
|
|
||||||
finish();
|
|
||||||
} else if (v.equals(vb.btnPlay)) {
|
|
||||||
int musicIndex = 0;
|
|
||||||
Intent intent = new Intent(this, PlayActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST, mCategoryList.getList().get(musicIndex));
|
|
||||||
// intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX,musicIndex);
|
|
||||||
intent.putExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_SOURCE_CATEGORY);
|
|
||||||
startActivity(intent);
|
|
||||||
vmApplication.reSetPlayList(mCategoryList.getList());
|
|
||||||
}else if(v.equals(vb.layoutError.tvRetry)){
|
|
||||||
vb.pbLoading.setVisibility(View.VISIBLE);
|
|
||||||
updateErrorLayout(null,false);
|
|
||||||
vm.getList(browseId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadInfo(ResponseCategoryList info) {
|
|
||||||
vb.btnPlay.setVisibility(View.VISIBLE);
|
|
||||||
switch (mPageType) {
|
|
||||||
case MyValue.PAGE_TYPE_LIST:
|
|
||||||
vb.tvSingerName.setVisibility(View.GONE);
|
|
||||||
break;
|
|
||||||
case MyValue.PAGE_TYPE_ALBUM:
|
|
||||||
vb.tvSingerName.setVisibility(View.VISIBLE);
|
|
||||||
String singNameValue = "";
|
|
||||||
String singName = info.getSingName();
|
|
||||||
if(singName!= null&&!singName.isEmpty()){
|
|
||||||
singNameValue= singName;
|
|
||||||
}else {
|
|
||||||
String[] split = twoSubtitle.split("•");
|
|
||||||
if (split != null && split.length > 1) {
|
|
||||||
singNameValue = split[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CommonUtils.LogMsg("singNameValue=" + singNameValue);
|
|
||||||
vb.tvSingerName.setText(singNameValue);
|
|
||||||
for (ResponsePlayListInfo playListInfo : info.getList()) {
|
|
||||||
playListInfo.setSingerName(singNameValue);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
vb.tvTitle.setText(info.getTitle());
|
|
||||||
vb.tvSubTitle.setText(info.getDescription());
|
|
||||||
|
|
||||||
AdapterCategoryList adapterCategoryList = new AdapterCategoryList();
|
|
||||||
adapterCategoryList.setHomeItemClickListener(this);
|
|
||||||
adapterCategoryList.setPageType(mPageType);
|
|
||||||
vb.recyclerview.setLayoutManager(new LinearLayoutManager(this));
|
|
||||||
adapterCategoryList.setData(info.getList());
|
|
||||||
vb.recyclerview.setAdapter(adapterCategoryList);
|
|
||||||
loadCovert(info.getCovert());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void loadCovert(String url) {
|
|
||||||
// 加载图片并应用高斯模糊效果
|
|
||||||
Glide.with(this)
|
|
||||||
.load(url)
|
|
||||||
.apply(bitmapTransform(new BlurTransformation(25, 3))) // 设置模糊半径和模糊采样
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
CommonUtils.extractColorsFromImage(resource,vb.imBg);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.preload();
|
|
||||||
|
|
||||||
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
// .apply(bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(10))))
|
|
||||||
.load(url)
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
CommonUtils.LogMsg(e.getMessage());
|
|
||||||
vb.pbLoading.setVisibility(View.GONE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
// CommonUtils.getDominantDarkColor1(resource, new onImageColorListener() {
|
|
||||||
// @Override
|
|
||||||
// public void onImageColor(int color) {
|
|
||||||
// if (color == -1) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
vb.pbLoading.setVisibility(View.GONE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(vb.imCovert);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClickItemCategoryList(ResponsePlayListInfo data, int musicIndex) {
|
|
||||||
Intent intent = new Intent(this, PlayActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST, data);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX, musicIndex);
|
|
||||||
intent.putExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_SOURCE_CATEGORY);
|
|
||||||
startActivity(intent);
|
|
||||||
vmApplication.reSetPlayList(mCategoryList.getList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,131 +0,0 @@
|
|||||||
package com.hi.music.player.ui.activity;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
import com.google.android.material.tabs.TabLayout;
|
|
||||||
import com.google.android.material.tabs.TabLayoutMediator;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.adapter.HomeViewPagerAdapter;
|
|
||||||
import com.hi.music.player.databinding.ActivityHomeBinding;
|
|
||||||
import com.hi.music.player.databinding.HomeTabCustomBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
|
|
||||||
public class HomeActivity extends BaseActivity<ActivityHomeBinding> {
|
|
||||||
|
|
||||||
// 图标数组定义为类成员,避免重复
|
|
||||||
private final int[] defaultIcons = {
|
|
||||||
R.drawable.home_unselect,
|
|
||||||
R.drawable.search_unselect,
|
|
||||||
R.drawable.profile_unselect
|
|
||||||
};
|
|
||||||
|
|
||||||
private final int[] selectedIcons = {
|
|
||||||
R.drawable.home_select,
|
|
||||||
R.drawable.search_select,
|
|
||||||
R.drawable.profile_select
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ActivityHomeBinding getViewBinding() {
|
|
||||||
return ActivityHomeBinding.inflate(getLayoutInflater());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreateInit() {
|
|
||||||
initView(); // 可以在这里初始化视图
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onInitClick() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFullScreen() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean statusBarLight() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showPanel() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initView() {
|
|
||||||
|
|
||||||
int statusBarHeight = CommonUtils.getStatusBarHeight(MusicApplication.myApplication);
|
|
||||||
View root = vb.getRoot();
|
|
||||||
root.setPadding(0,statusBarHeight,0,0);
|
|
||||||
|
|
||||||
HomeViewPagerAdapter adapter = new HomeViewPagerAdapter(this);
|
|
||||||
vb.homeViewPager.setAdapter(adapter);
|
|
||||||
vb.homeViewPager.setUserInputEnabled(false);
|
|
||||||
|
|
||||||
// 设置TabLayout的图标
|
|
||||||
new TabLayoutMediator(vb.homeTabLayout, vb.homeViewPager, (tab, position) -> {
|
|
||||||
HomeTabCustomBinding tabBinding = HomeTabCustomBinding.inflate(LayoutInflater.from(this));
|
|
||||||
tab.setCustomView(tabBinding.getRoot());
|
|
||||||
tabBinding.homeIcon.setImageResource(defaultIcons[position]); // 默认图标
|
|
||||||
}).attach();
|
|
||||||
|
|
||||||
// 添加Tab选中与未选中事件监听器
|
|
||||||
vb.homeTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
|
||||||
@Override
|
|
||||||
public void onTabSelected(TabLayout.Tab tab) {
|
|
||||||
updateTabIcon(tab, true); // 更新选中的图标
|
|
||||||
int position = tab.getPosition();
|
|
||||||
switch (position){
|
|
||||||
case 0:
|
|
||||||
vb.view.setVisibility(View.VISIBLE);
|
|
||||||
vb.homeLayout.setBackgroundColor(ContextCompat.getColor(HomeActivity.this,R.color.black));
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
vb.view.setVisibility(View.GONE);
|
|
||||||
vb.homeLayout.setBackgroundColor(ContextCompat.getColor(HomeActivity.this,R.color.default_play_list_color));
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
vb.view.setVisibility(View.GONE);
|
|
||||||
vb.homeLayout.setBackground(ContextCompat.getDrawable(HomeActivity.this,R.mipmap.bg_library));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void onTabUnselected(TabLayout.Tab tab) {
|
|
||||||
|
|
||||||
updateTabIcon(tab, false); // 恢复未选中图标
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void onTabReselected(TabLayout.Tab tab) {
|
|
||||||
// 可选:重复选择Tab时的操作
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 设置默认选中第一个
|
|
||||||
TabLayout.Tab firstTab = vb.homeTabLayout.getTabAt(0);
|
|
||||||
if (firstTab != null) {
|
|
||||||
firstTab.select();
|
|
||||||
updateTabIcon(firstTab, true); // 设置选中的图标
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateTabIcon(TabLayout.Tab tab, boolean isSelected) {
|
|
||||||
HomeTabCustomBinding tabBinding = HomeTabCustomBinding.bind(tab.getCustomView());
|
|
||||||
int position = tab.getPosition();
|
|
||||||
tabBinding.homeIcon.setImageResource(isSelected ? selectedIcons[position] : defaultIcons[position]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,171 +0,0 @@
|
|||||||
package com.hi.music.player.ui.activity;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.util.Pair;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.lifecycle.Observer;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.exoplayer.offline.Download;
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadManager;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.adapter.AdapterDownloadSong;
|
|
||||||
import com.hi.music.player.adapter.AdapterLikeSong;
|
|
||||||
import com.hi.music.player.api.HomeItemClickListener;
|
|
||||||
import com.hi.music.player.databinding.ActivityLikeSongBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.BoxLikeSong;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
|
||||||
import com.hi.music.player.media3.MyDownloadService;
|
|
||||||
import com.hi.music.player.objectbox.ObjectBoxManager;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class LikeSongActivity extends BaseActivity<ActivityLikeSongBinding> implements HomeItemClickListener {
|
|
||||||
|
|
||||||
|
|
||||||
private List<BoxLikeSong> boxLikeSongs;
|
|
||||||
private int mType;
|
|
||||||
|
|
||||||
private List<Pair<Integer, String>> downloadList = new ArrayList<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ActivityLikeSongBinding getViewBinding() {
|
|
||||||
return ActivityLikeSongBinding.inflate(getLayoutInflater());
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
|
||||||
protected void onCreateInit() {
|
|
||||||
Intent intent = getIntent();
|
|
||||||
mType = intent.getIntExtra(MyValue.KEY_ENTER_LIKE_ACTIVITY_TYPE, MyValue.KEY_ENTER_LIKE_ACTIVITY_TYPE_LIKE);
|
|
||||||
|
|
||||||
switch (mType) {
|
|
||||||
case MyValue.KEY_ENTER_LIKE_ACTIVITY_TYPE_LIKE:
|
|
||||||
vb.tvTitle.setText(getString(R.string.text_like_song));
|
|
||||||
boxLikeSongs = ObjectBoxManager.queryAllLike();
|
|
||||||
AdapterLikeSong adapterLikeSong = new AdapterLikeSong(this, vmApplication);
|
|
||||||
adapterLikeSong.setHomeItemClickListener(this);
|
|
||||||
adapterLikeSong.setData(boxLikeSongs);
|
|
||||||
vb.recycler.setLayoutManager(new LinearLayoutManager(this));
|
|
||||||
vb.recycler.setAdapter(adapterLikeSong);
|
|
||||||
vb.tvSongSize.setText(String.format(getString(R.string.like_song), boxLikeSongs.size()));
|
|
||||||
MyDownloadService.addDownloadListener(vmApplication);
|
|
||||||
vmApplication.downloadChange.observe(this, new Observer<Pair<Boolean, Download>>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(Pair<Boolean, Download> booleanDownloadPair) {
|
|
||||||
Boolean first = booleanDownloadPair.first;
|
|
||||||
Download downloads = booleanDownloadPair.second;
|
|
||||||
|
|
||||||
String id = downloads.request.id;
|
|
||||||
for (Pair<Integer,String> pair:downloadList){
|
|
||||||
Integer position = pair.first;
|
|
||||||
String videoId = pair.second;
|
|
||||||
if(id.equals(videoId)){
|
|
||||||
adapterLikeSong.updateDownloadStatus(first,position,videoId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MyValue.KEY_ENTER_LIKE_ACTIVITY_TYPE_DOWNLOAD:
|
|
||||||
vb.tvTitle.setText(getString(R.string.text_offline_song));
|
|
||||||
MyDownloadService.updateDownloadUi(vmApplication);
|
|
||||||
vmApplication.downloadData.observe(this, new Observer<List<Download>>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(List<Download> downloads) {
|
|
||||||
AdapterDownloadSong adapterDownloadSong = new AdapterDownloadSong();
|
|
||||||
adapterDownloadSong.setHomeItemClickListener(LikeSongActivity.this);
|
|
||||||
adapterDownloadSong.setData(downloads);
|
|
||||||
vb.recycler.setLayoutManager(new LinearLayoutManager(LikeSongActivity.this));
|
|
||||||
vb.recycler.setAdapter(adapterDownloadSong);
|
|
||||||
vb.tvSongSize.setText(String.format(getString(R.string.download_song), downloads.size()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onInitClick() {
|
|
||||||
vb.imBack.setOnClickListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFullScreen() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean statusBarLight() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showPanel() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (v.equals(vb.imBack)) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClickLikeSong(BoxLikeSong boxLikeSong, int index) {
|
|
||||||
List<ResponsePlayListInfo> playList = new ArrayList<>();
|
|
||||||
for (BoxLikeSong song : boxLikeSongs) {
|
|
||||||
String videoId1 = song.getVideoId();
|
|
||||||
String songName = song.getSongName();
|
|
||||||
String covert = song.getCovert();
|
|
||||||
String singerName = song.getSingerName();
|
|
||||||
long durationMs = song.getDurationMs();
|
|
||||||
String duration = song.getDuration();
|
|
||||||
|
|
||||||
ResponsePlayListInfo playListInfo = new ResponsePlayListInfo(covert, songName, singerName, durationMs, videoId1, duration);
|
|
||||||
playList.add(playListInfo);
|
|
||||||
}
|
|
||||||
vmApplication.reSetPlayList(playList);
|
|
||||||
|
|
||||||
String videoId = boxLikeSong.getVideoId();
|
|
||||||
CommonUtils.LogMsg("-------------like进入 传值 videoId= " + videoId);
|
|
||||||
Intent intent = new Intent(this, PlayActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_VIDEO_ID, videoId);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_INDEX, index);
|
|
||||||
intent.putExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_LIKE);
|
|
||||||
startActivity(intent);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
|
||||||
public void onClickDownloadSong(Download download, int index) {
|
|
||||||
|
|
||||||
// MyDownloadService.updateDownloadUi(vmApplication)
|
|
||||||
|
|
||||||
String videoId = download.request.id;
|
|
||||||
CommonUtils.LogMsg("------------Download进入 传值 videoId= " + videoId);
|
|
||||||
Intent intent = new Intent(this, PlayActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_VIDEO_ID, videoId);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_INDEX, index);
|
|
||||||
intent.putExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_DOWNLOAD);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDownloadSong(String videoId, int index) {
|
|
||||||
Pair<Integer, String> integerStringPair = new Pair<>(index, videoId);
|
|
||||||
downloadList.add(integerStringPair);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,862 +0,0 @@
|
|||||||
package com.hi.music.player.ui.activity;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.graphics.drawable.GradientDrawable;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.Animation;
|
|
||||||
import android.view.animation.AnimationUtils;
|
|
||||||
import android.widget.SeekBar;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
import androidx.lifecycle.Observer;
|
|
||||||
import androidx.media3.common.MediaItem;
|
|
||||||
import androidx.media3.common.MediaMetadata;
|
|
||||||
import androidx.media3.common.Player;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.datasource.cache.SimpleCache;
|
|
||||||
import androidx.media3.exoplayer.offline.Download;
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadManager;
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadRequest;
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadService;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.adapter.AdapterDownloadSong;
|
|
||||||
import com.hi.music.player.adapter.AdapterPlayList;
|
|
||||||
import com.hi.music.player.api.LikeSongListener;
|
|
||||||
import com.hi.music.player.api.MediaControllerListener;
|
|
||||||
import com.hi.music.player.api.onCheckDownload;
|
|
||||||
import com.hi.music.player.api.onImageColorListener;
|
|
||||||
import com.hi.music.player.api.onPlayNextListener;
|
|
||||||
import com.hi.music.player.databinding.ActivityPlayBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.BoxDownloadSong;
|
|
||||||
import com.hi.music.player.javabean.BoxLikeSong;
|
|
||||||
import com.hi.music.player.javabean.CustomerDownload;
|
|
||||||
import com.hi.music.player.javabean.CustomerUrlInfo;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseCategory;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
import com.hi.music.player.media3.MyDownloadService;
|
|
||||||
import com.hi.music.player.media3.MyMediaControllerManager;
|
|
||||||
import com.hi.music.player.media3.MyPlayCacheManager;
|
|
||||||
import com.hi.music.player.objectbox.ObjectBoxManager;
|
|
||||||
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
|
|
||||||
import com.hi.music.player.ui.activity.viewmodel.VMPlay;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements SeekBar.OnSeekBarChangeListener {
|
|
||||||
|
|
||||||
|
|
||||||
//单曲进入传递的数据
|
|
||||||
private ResponseSingle responseSingle;
|
|
||||||
private VMPlay vmPlay;
|
|
||||||
|
|
||||||
|
|
||||||
private Handler mHandler;
|
|
||||||
private Runnable mRunnable;
|
|
||||||
|
|
||||||
|
|
||||||
private AdapterPlayList adapterPlayList;
|
|
||||||
|
|
||||||
|
|
||||||
//播放列表ui初始化
|
|
||||||
private boolean initPlayList = false;
|
|
||||||
|
|
||||||
private GradientDrawable gradientDrawable;
|
|
||||||
private int lighterColor, darkerColor;
|
|
||||||
|
|
||||||
// 0 播放列表请求失败 1 立即播放的歌曲请求失败 2 封面图加载失败
|
|
||||||
private int netError = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// 请求失败的立即播放的歌曲信息
|
|
||||||
private CustomerUrlInfo mCustomerUrlInfo;
|
|
||||||
private int mEnterType;
|
|
||||||
|
|
||||||
|
|
||||||
//-------单曲进入播放列表接口请求需要的参数
|
|
||||||
private String playlistId, videoId, params, musicVideoType = "";
|
|
||||||
//-------单曲进入播放列表接口请求需要的参数
|
|
||||||
|
|
||||||
private int mDefaultPlayStartIndex = 0;
|
|
||||||
|
|
||||||
|
|
||||||
private int[] imageStates = {
|
|
||||||
R.drawable.icon_looper_no,
|
|
||||||
R.drawable.icon_looper_1,
|
|
||||||
R.drawable.icon_looper
|
|
||||||
};
|
|
||||||
|
|
||||||
//0 不循环、1 列表循环、2 单曲循环、
|
|
||||||
private int currentMode = 0;
|
|
||||||
|
|
||||||
private List<BoxDownloadSong> downloadSongList = new ArrayList<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ActivityPlayBinding getViewBinding() {
|
|
||||||
return ActivityPlayBinding.inflate(getLayoutInflater());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreateInit() {
|
|
||||||
// vb.progressBarLoading.setVisibility(View.VISIBLE);
|
|
||||||
vmPlay = getActivityScopeViewModel(VMPlay.class);
|
|
||||||
initMediaController();
|
|
||||||
Intent intent = getIntent();
|
|
||||||
mEnterType = intent.getIntExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_SOURCE_SINGLE);
|
|
||||||
initPlayerView();
|
|
||||||
initProgressHandler();
|
|
||||||
|
|
||||||
CommonUtils.LogMsg("--------mEnterType=" + mEnterType);
|
|
||||||
switch (mEnterType) {
|
|
||||||
case MyValue.TYPE_ENTER_SOURCE_SINGLE:
|
|
||||||
// 0--首页单曲进入
|
|
||||||
updateMediaPlayList();
|
|
||||||
responseSingle = (ResponseSingle) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER);
|
|
||||||
playlistId = responseSingle.getPlaylistId();
|
|
||||||
videoId = responseSingle.getVideoId();
|
|
||||||
params = responseSingle.getParams();
|
|
||||||
musicVideoType = responseSingle.getMusicVideoType();
|
|
||||||
mDefaultPlayStartIndex = intent.getIntExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX, mDefaultPlayStartIndex);
|
|
||||||
|
|
||||||
SimpleCache playCache = MyPlayCacheManager.getPlayCache();
|
|
||||||
// boolean songCached = CommonUtils.isSongCached(playCache, videoId);
|
|
||||||
|
|
||||||
// CommonUtils.LogMsg("---------------是否有播放缓存--songCached="+songCached +"--name="+responseSingle.getSongTitle());
|
|
||||||
|
|
||||||
vmPlay.getPlayMusicList(playlistId, videoId, params, musicVideoType);
|
|
||||||
vmPlay.playList.observe(this, new Observer<List<ResponsePlayListInfo>>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(List<ResponsePlayListInfo> listInfos) {
|
|
||||||
vmApplication.reSetPlayList(listInfos);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case MyValue.TYPE_ENTER_SOURCE_CATEGORY:
|
|
||||||
// 1--首页音乐分类合集列表进入
|
|
||||||
|
|
||||||
updateMediaPlayList();
|
|
||||||
ResponsePlayListInfo playListInfo = (ResponsePlayListInfo) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST);
|
|
||||||
mDefaultPlayStartIndex = intent.getIntExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX, mDefaultPlayStartIndex);
|
|
||||||
videoId = playListInfo.getVideoId();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MyValue.TYPE_ENTER_SOURCE_MV:
|
|
||||||
// 2--首页单个视频mv进入
|
|
||||||
|
|
||||||
updateMediaPlayList();
|
|
||||||
ResponseCategory responseCategory = (ResponseCategory) intent.getSerializableExtra(MyValue.KEY_PLAY_ACTIVITY_MV);
|
|
||||||
videoId = responseCategory.getVideoId();
|
|
||||||
playlistId = responseCategory.getPlayListId();
|
|
||||||
params = responseCategory.getParams();
|
|
||||||
musicVideoType = responseCategory.getMusicVideoType();
|
|
||||||
vmPlay.getPlayMusicList(playlistId, videoId, params, musicVideoType);
|
|
||||||
vmPlay.playList.observe(this, new Observer<List<ResponsePlayListInfo>>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(List<ResponsePlayListInfo> listInfos) {
|
|
||||||
vmApplication.reSetPlayList(listInfos);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MyValue.TYPE_ENTER_PANEL:
|
|
||||||
// 3--控制面板进入
|
|
||||||
MediaItem curMediaItem = mediaControllerManager.getCurMediaItem();
|
|
||||||
loadInfo(curMediaItem);
|
|
||||||
mHandler.post(mRunnable);
|
|
||||||
vb.progressBarLoading.setVisibility(View.GONE);
|
|
||||||
vb.btnPlay.setSelected(mediaControllerManager.getIsPlaying());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MyValue.TYPE_ENTER_LIKE:
|
|
||||||
// 4--从喜爱歌曲进入
|
|
||||||
updateMediaPlayList();
|
|
||||||
videoId = intent.getStringExtra(MyValue.KEY_PLAY_VIDEO_ID);
|
|
||||||
mDefaultPlayStartIndex = intent.getIntExtra(MyValue.KEY_PLAY_INDEX, mDefaultPlayStartIndex);
|
|
||||||
CommonUtils.LogMsg("-------------like进入 videoId= " + videoId + "---mDefaultPlayStartIndex=" + mDefaultPlayStartIndex);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MyValue.TYPE_ENTER_DOWNLOAD:
|
|
||||||
// 5--从下载歌曲进入
|
|
||||||
videoId = intent.getStringExtra(MyValue.KEY_PLAY_VIDEO_ID);
|
|
||||||
mDefaultPlayStartIndex = intent.getIntExtra(MyValue.KEY_PLAY_INDEX, mDefaultPlayStartIndex);
|
|
||||||
CommonUtils.LogMsg("-------------下载歌曲 videoId= " + videoId + "---mDefaultPlayStartIndex=" + mDefaultPlayStartIndex);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
addDownloadListener();
|
|
||||||
vmPlay.playUrlLiveData.observe(this, new Observer<CustomerUrlInfo>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(CustomerUrlInfo customerUrlInfo) {
|
|
||||||
if (customerUrlInfo.isNeedPlayNow() && customerUrlInfo.getPlayUrl() == null) {
|
|
||||||
// TODO: 2024/9/26 需要马上播放这首歌曲,但是此次网络请求失败
|
|
||||||
CommonUtils.LogErrorMsg("-------------需要马上播放这首歌曲,但是此次网络请求失败");
|
|
||||||
updateErrorLayout(getString(R.string.song_loading_failed), true);
|
|
||||||
netError = 1;
|
|
||||||
mCustomerUrlInfo = customerUrlInfo;
|
|
||||||
initShowPlayList(false);
|
|
||||||
vb.progressBarLoading.setVisibility(View.GONE);
|
|
||||||
mediaControllerManager.pause();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int second = customerUrlInfo.getPlayMusicIndex();
|
|
||||||
if (customerUrlInfo.isNeedPlayNow()) {
|
|
||||||
mediaControllerManager.playPositionMusic(second);
|
|
||||||
// mediaControllerManager.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新播放列表
|
|
||||||
*/
|
|
||||||
private void updateMediaPlayList() {
|
|
||||||
vmApplication.playList.observe(this, new Observer<List<ResponsePlayListInfo>>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(List<ResponsePlayListInfo> playList) {
|
|
||||||
if (playList == null) {
|
|
||||||
CommonUtils.LogErrorMsg("--------更新-playList null");
|
|
||||||
netError = 0;
|
|
||||||
updateErrorLayout(getString(R.string.playList_loading_failed), true);
|
|
||||||
vb.progressBarLoading.setVisibility(View.GONE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CommonUtils.LogMsg("--------更新-playList " + playList.size() + "--videoId=" + videoId);
|
|
||||||
if (playList.size() > 0) {
|
|
||||||
updateErrorLayout(null, false);
|
|
||||||
setPlayListAndGetUrl(playList, videoId, mDefaultPlayStartIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateErrorLayout(String msg, boolean isShow) {
|
|
||||||
if (isShow)
|
|
||||||
vb.layoutError.linearRetry.setVisibility(View.VISIBLE);
|
|
||||||
else vb.layoutError.linearRetry.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
if (msg != null && !msg.isEmpty()) {
|
|
||||||
vb.layoutError.tvErrorMsg.setText(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置播放列表,并请求当前需要播放的音乐url
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
* @param id
|
|
||||||
* @param index
|
|
||||||
*/
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
private void setPlayListAndGetUrl(List<ResponsePlayListInfo> list, String id, int index) {
|
|
||||||
mediaControllerManager.resetPlayList();
|
|
||||||
MyMediaControllerManager.getInstance().setPlayList(list);
|
|
||||||
MyDownloadService.queryIsDownload(id, new onCheckDownload() {
|
|
||||||
@Override
|
|
||||||
public void onHasDownload(CustomerDownload customerDownload) {
|
|
||||||
if(customerDownload.isDownload()){
|
|
||||||
MediaItem mediaItem = CommonUtils.downloadToMediaItem(customerDownload.getDownloadData());
|
|
||||||
mediaControllerManager.replaceMediaItem(index,mediaItem);
|
|
||||||
CommonUtils.LogMsg("-------------setPlayListAndGetUrl已经下载过 index" + index + "---playNow=" + true);
|
|
||||||
mediaControllerManager.playPositionMusic(index);
|
|
||||||
}else {
|
|
||||||
CommonUtils.LogMsg("-------------setPlayListAndGetUrl index" + index + "---playNow=" + true);
|
|
||||||
vmPlay.getPlayUrl(id, index, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
private void initPlayerView() {
|
|
||||||
vb.playerView.setShowRewindButton(false);
|
|
||||||
vb.playerView.setShowPreviousButton(false);
|
|
||||||
vb.playerView.setPlayer(mediaControllerManager.getMediaController());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initMediaController() {
|
|
||||||
int repeatMode = mediaControllerManager.getRepeatMode();
|
|
||||||
CommonUtils.LogMsg("-------------repeatMode=" + repeatMode);
|
|
||||||
vb.btnLoop.setImageResource(imageStates[repeatMode]);
|
|
||||||
mediaControllerManager.addListener(vmApplication, new MediaControllerListener() {
|
|
||||||
@Override
|
|
||||||
public void onPlayStatus(int playStatus) {
|
|
||||||
|
|
||||||
switch (playStatus) {
|
|
||||||
case Player.STATE_IDLE:
|
|
||||||
CommonUtils.LogMsg("-------------IDLE");
|
|
||||||
break;
|
|
||||||
case Player.STATE_BUFFERING:
|
|
||||||
//快进没有缓冲的时候触发
|
|
||||||
vb.btnPlay.setSelected(false);
|
|
||||||
// vb.progressBarLoading.setVisibility(View.VISIBLE);
|
|
||||||
CommonUtils.LogMsg("-------------缓冲");
|
|
||||||
break;
|
|
||||||
case Player.STATE_READY:
|
|
||||||
vb.btnPlay.setSelected(true);
|
|
||||||
mHandler.post(mRunnable);
|
|
||||||
vb.progressBarLoading.setVisibility(View.GONE);
|
|
||||||
CommonUtils.LogMsg("-------------准备");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Player.STATE_ENDED:
|
|
||||||
//播放完成
|
|
||||||
vb.btnPlay.setSelected(false);
|
|
||||||
CommonUtils.LogMsg("------------- 播放完成");
|
|
||||||
mHandler.removeCallbacks(mRunnable); // 停止更新
|
|
||||||
updatePlayComplete();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MyValue.PLAY_STATUS_CODE_PAUSE:
|
|
||||||
CommonUtils.LogMsg("------------- 暂停");
|
|
||||||
vb.btnPlay.setSelected(false);
|
|
||||||
vb.layoutPlayList.imPlay.setSelected(false);
|
|
||||||
break;
|
|
||||||
case MyValue.PLAY_STATUS_CODE_PLAYING:
|
|
||||||
|
|
||||||
CommonUtils.LogMsg("------------- 播放ing getCurIndex=" + mediaControllerManager.getCurIndex());
|
|
||||||
vb.progressBarLoading.setVisibility(View.GONE);
|
|
||||||
updateErrorLayout(null, false);
|
|
||||||
vb.btnPlay.setSelected(true);
|
|
||||||
vb.layoutPlayList.imPlay.setSelected(true);
|
|
||||||
break;
|
|
||||||
case MyValue.PLAY_STATUS_CODE_ERROR:
|
|
||||||
vb.progressBarLoading.setVisibility(View.GONE);
|
|
||||||
int currentMediaItemIndex = mediaControllerManager.getMediaController().getCurrentMediaItemIndex();
|
|
||||||
CommonUtils.LogMsg("------------- 播放错误 currentMediaItemIndex=" + currentMediaItemIndex);
|
|
||||||
mediaControllerManager.playPositionMusic(currentMediaItemIndex);
|
|
||||||
// TODO: 2024/10/16
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRequestNextUri(String videoId, int playListIndex, boolean playNow) {
|
|
||||||
if (playNow) {
|
|
||||||
// vb.progressBarLoading.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
vmPlay.getPlayUrl(videoId, playListIndex, playNow);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onChangeMusic(MediaItem mediaItem) {
|
|
||||||
CommonUtils.LogMsg("歌曲切换-" + mediaItem.mediaMetadata.title + "---id=" + mediaItem.mediaId);
|
|
||||||
loadInfo(mediaItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onInitClick() {
|
|
||||||
vb.btnPlay.setOnClickListener(this);
|
|
||||||
vb.playProgress.setOnSeekBarChangeListener(this);
|
|
||||||
vb.btnNext.setOnClickListener(this);
|
|
||||||
vb.btnPrevious.setOnClickListener(this);
|
|
||||||
vb.imBack.setOnClickListener(this);
|
|
||||||
vb.btnMusicList.setOnClickListener(this);
|
|
||||||
vb.layoutError.tvRetry.setOnClickListener(this);
|
|
||||||
vb.btnLoop.setOnClickListener(this);
|
|
||||||
vb.layoutLike.setOnClickListener(this);
|
|
||||||
vb.layoutDownload.setOnClickListener(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新播放进度Ui、缓冲进度
|
|
||||||
*/
|
|
||||||
private void updatePlaybackProgress() {
|
|
||||||
// 获取当前播放位置
|
|
||||||
long contentPos = mediaControllerManager.getContentPos();
|
|
||||||
long bufferPos = mediaControllerManager.getBufferPos();
|
|
||||||
|
|
||||||
|
|
||||||
String s = CommonUtils.convertMillisToTime(contentPos);
|
|
||||||
vb.tvCurrent.setText(s);
|
|
||||||
vb.playProgress.setProgress((int) contentPos);
|
|
||||||
vb.progressBarBuffer.setProgress((int) bufferPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 播放完成 更新播放进度Ui
|
|
||||||
*/
|
|
||||||
private void updatePlayComplete() {
|
|
||||||
vb.tvCurrent.setText(vb.tvDuration.getText().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 加载当前播放歌曲信息
|
|
||||||
*/
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
private void loadInfo(MediaItem mediaItem) {
|
|
||||||
MediaMetadata mediaMetadata = mediaItem.mediaMetadata;
|
|
||||||
CommonUtils.LogMsg("--------------加载当前播放歌曲信息 title=" + mediaMetadata.title);
|
|
||||||
if (mediaMetadata.artworkUri != null) {
|
|
||||||
loadCovert(mediaMetadata.artworkUri.toString());
|
|
||||||
}
|
|
||||||
vb.tvSongName.setText(mediaMetadata.title);
|
|
||||||
vb.tvSingerName.setText(mediaMetadata.artist);
|
|
||||||
vb.tvDuration.setText(mediaMetadata.description);
|
|
||||||
|
|
||||||
if (mediaMetadata.durationMs != null) {
|
|
||||||
long durationMs = mediaMetadata.durationMs;
|
|
||||||
vb.playProgress.setMax((int) durationMs);
|
|
||||||
vb.progressBarBuffer.setMax((int) durationMs);
|
|
||||||
}
|
|
||||||
if (vb.layoutPlayList.linearLayout.getVisibility() == View.VISIBLE) {
|
|
||||||
updatePlayListUi();
|
|
||||||
}
|
|
||||||
|
|
||||||
//刷新当前歌曲的喜爱状态
|
|
||||||
boolean isLike = ObjectBoxManager.queryIsLike(mediaItem.mediaId);
|
|
||||||
vb.imLike.setSelected(isLike);
|
|
||||||
|
|
||||||
//刷新当前歌曲的下载状态
|
|
||||||
String mediaId = mediaItem.mediaId;
|
|
||||||
MyDownloadService.queryIsDownload(mediaId, new onCheckDownload() {
|
|
||||||
@Override
|
|
||||||
public void onHasDownload(CustomerDownload customerDownload) {
|
|
||||||
vb.imDownload.setSelected(customerDownload.isDownload());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadCovert(String url) {
|
|
||||||
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
.load(url)
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
CommonUtils.LogMsg(e.getMessage());
|
|
||||||
// netError = 2;
|
|
||||||
// vb.tvErrorMsg.setText(getString(R.string.image_loading_failed));
|
|
||||||
// vb.linearRetry.setVisibility(View.VISIBLE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
vb.imCovert.setImageDrawable(resource);
|
|
||||||
CommonUtils.getMainColor(resource, new onImageColorListener() {
|
|
||||||
@Override
|
|
||||||
public void onImageColor(int color) {
|
|
||||||
if (color == -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lighterColor = CommonUtils.adjustBrightness(color, 0.8f); // 比原始颜色亮 20%
|
|
||||||
darkerColor = CommonUtils.adjustBrightness(color, 0.6f); // 比原始颜色暗 20%
|
|
||||||
gradientDrawable = new GradientDrawable(
|
|
||||||
GradientDrawable.Orientation.TOP_BOTTOM,
|
|
||||||
new int[]{lighterColor, darkerColor} // 浅到深渐变
|
|
||||||
);
|
|
||||||
vb.rootLayout.setBackground(gradientDrawable);
|
|
||||||
|
|
||||||
if (vb.layoutPlayList.linearLayout.getVisibility() == View.VISIBLE) {
|
|
||||||
updatePlayListColor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.preload();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void initProgressHandler() {
|
|
||||||
mHandler = new Handler();
|
|
||||||
mRunnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
updatePlaybackProgress();
|
|
||||||
mHandler.postDelayed(this, 1000);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFullScreen() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean statusBarLight() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showPanel() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (v.equals(vb.btnPlay)) {
|
|
||||||
vb.btnPlay.setSelected(!vb.btnPlay.isSelected());
|
|
||||||
if (vb.btnPlay.isSelected()) {
|
|
||||||
mediaControllerManager.play();
|
|
||||||
} else {
|
|
||||||
mediaControllerManager.pause();
|
|
||||||
}
|
|
||||||
} else if (v.equals(vb.btnNext)) {
|
|
||||||
mediaControllerManager.playNext(new onPlayNextListener() {
|
|
||||||
@Override
|
|
||||||
public void onPlayNext(boolean hasNext) {
|
|
||||||
if (!hasNext) {
|
|
||||||
Toast.makeText(PlayActivity.this, getString(R.string.no_next_song_yet), Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} else if (v.equals(vb.btnPrevious)) {
|
|
||||||
mediaControllerManager.playPrevious();
|
|
||||||
} else if (v.equals(vb.imBack)) {
|
|
||||||
finish();
|
|
||||||
} else if (v.equals(vb.btnMusicList)) {
|
|
||||||
initShowPlayList(true);
|
|
||||||
} else if (v.equals(vb.layoutPlayList.imPlay)) {
|
|
||||||
vb.layoutPlayList.imPlay.setSelected(!vb.layoutPlayList.imPlay.isSelected());
|
|
||||||
if (vb.layoutPlayList.imPlay.isSelected()) {
|
|
||||||
mediaControllerManager.play();
|
|
||||||
} else {
|
|
||||||
mediaControllerManager.pause();
|
|
||||||
}
|
|
||||||
if (adapterPlayList != null) {
|
|
||||||
adapterPlayList.updateCurMusicAnimation();
|
|
||||||
}
|
|
||||||
} else if (v.equals(vb.layoutError.tvRetry)) {
|
|
||||||
//重试按钮
|
|
||||||
updateErrorLayout(null, false);
|
|
||||||
switch (netError) {
|
|
||||||
case 0:
|
|
||||||
switch (mEnterType) {
|
|
||||||
case MyValue.TYPE_ENTER_SOURCE_SINGLE:
|
|
||||||
vmPlay.getPlayMusicList(playlistId, videoId, params, musicVideoType);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
vb.progressBarLoading.setVisibility(View.VISIBLE);
|
|
||||||
int curIndex = mediaControllerManager.getCurIndex();
|
|
||||||
|
|
||||||
String curVideoId = mediaControllerManager.getCurVideoId();
|
|
||||||
|
|
||||||
String videoId1 = mCustomerUrlInfo.getVideoId();
|
|
||||||
int playMusicIndex = mCustomerUrlInfo.getPlayMusicIndex();
|
|
||||||
|
|
||||||
CommonUtils.LogMsg("-------重试 curIndex=" + curIndex + "----curVideoId=" + curVideoId + "---videoId1=" + videoId1 + "---playMusicIndex=" + playMusicIndex);
|
|
||||||
|
|
||||||
vmPlay.getPlayUrl(mCustomerUrlInfo.getVideoId(), mCustomerUrlInfo.getPlayMusicIndex(), true);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
MediaItem curMediaItem = mediaControllerManager.getCurMediaItem();
|
|
||||||
MediaMetadata mediaMetadata = curMediaItem.mediaMetadata;
|
|
||||||
if (mediaMetadata.artworkUri != null) {
|
|
||||||
loadCovert(mediaMetadata.artworkUri.toString());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (v.equals(vb.btnLoop)) {
|
|
||||||
currentMode = (currentMode + 1) % imageStates.length;
|
|
||||||
vb.btnLoop.setImageResource(imageStates[currentMode]);
|
|
||||||
CommonUtils.LogMsg("----currentMode=" + currentMode);
|
|
||||||
mediaControllerManager.setMode(currentMode);
|
|
||||||
} else if (v.equals(vb.layoutLike)) {
|
|
||||||
boolean selected = vb.imLike.isSelected();
|
|
||||||
vb.imLike.setSelected(!selected);
|
|
||||||
boolean newSelect = vb.imLike.isSelected();
|
|
||||||
MediaItem curMediaItem = mediaControllerManager.getCurMediaItem();
|
|
||||||
MediaMetadata mediaMetadata = curMediaItem.mediaMetadata;
|
|
||||||
if (mediaMetadata.title != null && mediaMetadata.artist != null && mediaMetadata.durationMs != null && mediaMetadata.description != null) {
|
|
||||||
BoxLikeSong boxLikeSong = new BoxLikeSong(mediaMetadata.title.toString(),
|
|
||||||
mediaMetadata.artist.toString(),
|
|
||||||
curMediaItem.mediaId,
|
|
||||||
String.valueOf(mediaMetadata.artworkUri),
|
|
||||||
mediaMetadata.durationMs, mediaMetadata.description.toString());
|
|
||||||
if (newSelect) {
|
|
||||||
ObjectBoxManager.insertOrUpdateLike(boxLikeSong);
|
|
||||||
} else {
|
|
||||||
ObjectBoxManager.deleteLike(boxLikeSong);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} else if (v.equals(vb.layoutDownload)) {
|
|
||||||
if (vb.imDownload.isSelected()) {
|
|
||||||
//已经下载
|
|
||||||
Toast.makeText(this,getText(R.string.text_has_downloaded),Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
vb.downloadPb.setVisibility(View.VISIBLE);
|
|
||||||
vb.imDownload.setVisibility(View.INVISIBLE);
|
|
||||||
BoxDownloadSong curMediaItemInfo = getCurMediaItemInfo();
|
|
||||||
if (curMediaItemInfo != null) {
|
|
||||||
Gson gson = new Gson();
|
|
||||||
String info = gson.toJson(curMediaItemInfo);
|
|
||||||
byte[] data = info.getBytes(StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
String videoId1 = curMediaItemInfo.getVideoId();
|
|
||||||
CommonUtils.LogMsg("----------------开始下载 id=" + videoId1);
|
|
||||||
DownloadRequest downloadRequest = new DownloadRequest.Builder(videoId1, Uri.parse(curMediaItemInfo.getVideoUrl()))
|
|
||||||
.setMimeType("video/mp4")
|
|
||||||
.setData(data)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// 启动 DownloadService 进行下载
|
|
||||||
DownloadService.sendAddDownload(
|
|
||||||
this,
|
|
||||||
MyDownloadService.class, // 上面定义的下载服务类
|
|
||||||
downloadRequest,
|
|
||||||
true // 是否在前台运行
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
private BoxDownloadSong getCurMediaItemInfo() {
|
|
||||||
MediaItem curMediaItem = mediaControllerManager.getCurMediaItem();
|
|
||||||
if (curMediaItem == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
MediaMetadata mediaMetadata = curMediaItem.mediaMetadata;
|
|
||||||
if (mediaMetadata.title == null || mediaMetadata.artist == null || mediaMetadata.description == null
|
|
||||||
|| mediaMetadata.durationMs == null || curMediaItem.localConfiguration == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
BoxDownloadSong boxDownloadSong = new BoxDownloadSong();
|
|
||||||
boxDownloadSong.setVideoId(curMediaItem.mediaId);
|
|
||||||
boxDownloadSong.setCovert(String.valueOf(mediaMetadata.artworkUri));
|
|
||||||
boxDownloadSong.setSongName((String) mediaMetadata.title);
|
|
||||||
boxDownloadSong.setSingerName((String) mediaMetadata.artist);
|
|
||||||
boxDownloadSong.setDuration((String) mediaMetadata.description);
|
|
||||||
boxDownloadSong.setDurationMs(mediaMetadata.durationMs);
|
|
||||||
boxDownloadSong.setVideoUrl(String.valueOf(curMediaItem.localConfiguration.uri));
|
|
||||||
|
|
||||||
return boxDownloadSong;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 控制播放列表的显示
|
|
||||||
*
|
|
||||||
* @param show
|
|
||||||
*/
|
|
||||||
private void initShowPlayList(boolean show) {
|
|
||||||
if (show) {
|
|
||||||
Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_up);
|
|
||||||
vb.layoutPlayList.linearLayout.startAnimation(animation);
|
|
||||||
vb.layoutPlayList.linearLayout.setVisibility(View.VISIBLE);
|
|
||||||
vb.contentLayout.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
if (!initPlayList) {
|
|
||||||
List<ResponsePlayListInfo> playList;
|
|
||||||
if (mEnterType == MyValue.TYPE_ENTER_DOWNLOAD){
|
|
||||||
playList = new ArrayList<>();
|
|
||||||
for(BoxDownloadSong data:downloadSongList){
|
|
||||||
ResponsePlayListInfo playListInfo = new ResponsePlayListInfo();
|
|
||||||
playListInfo.setSongTitle(data.getSongName());
|
|
||||||
playListInfo.setSingerName(data.getSingerName());
|
|
||||||
playListInfo.setCovert(data.getCovert());
|
|
||||||
playListInfo.setSmallCovert(data.getCovert());
|
|
||||||
playListInfo.setVideoId(data.getVideoId());
|
|
||||||
playListInfo.setDuration(data.getDuration());
|
|
||||||
playListInfo.setDurationMs(data.getDurationMs());
|
|
||||||
playList.add(playListInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
}else {
|
|
||||||
playList = mediaControllerManager.getPlayList();
|
|
||||||
}
|
|
||||||
adapterPlayList = new AdapterPlayList();
|
|
||||||
vb.layoutPlayList.recyclerList.setLayoutManager(new LinearLayoutManager(MusicApplication.myApplication));
|
|
||||||
adapterPlayList.setData(playList);
|
|
||||||
// TODO: 2024/10/16 播放列表显示
|
|
||||||
vb.layoutPlayList.recyclerList.setAdapter(adapterPlayList);
|
|
||||||
vb.layoutPlayList.imPlay.setOnClickListener(this);
|
|
||||||
initPlayList = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
updatePlayListUi();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
vb.rootLayout.setBackground(gradientDrawable);
|
|
||||||
vb.contentLayout.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_down);
|
|
||||||
vb.layoutPlayList.linearLayout.startAnimation(animation);
|
|
||||||
vb.layoutPlayList.linearLayout.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新播放列表的显示
|
|
||||||
*/
|
|
||||||
private void updatePlayListUi() {
|
|
||||||
CommonUtils.LogMsg("----------更新播放列表的显示");
|
|
||||||
|
|
||||||
MediaItem currentMediaItem = mediaControllerManager.getCurMediaItem();
|
|
||||||
if (currentMediaItem != null) {
|
|
||||||
if (adapterPlayList != null) {
|
|
||||||
adapterPlayList.setCurVideId(currentMediaItem.mediaId);
|
|
||||||
}
|
|
||||||
Uri artworkUri = currentMediaItem.mediaMetadata.artworkUri;
|
|
||||||
vb.layoutPlayList.topSongName.setText(currentMediaItem.mediaMetadata.title);
|
|
||||||
vb.layoutPlayList.topSingerName.setText(currentMediaItem.mediaMetadata.artist);
|
|
||||||
updatePlayListColor();
|
|
||||||
Glide.with(MusicApplication.myApplication)
|
|
||||||
.asDrawable()
|
|
||||||
// .apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(10))))
|
|
||||||
.load(artworkUri)
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
CommonUtils.LogMsg(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(vb.layoutPlayList.topIm);
|
|
||||||
}
|
|
||||||
vb.layoutPlayList.imPlay.setSelected(mediaControllerManager.getIsPlaying());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updatePlayListColor() {
|
|
||||||
vb.layoutPlayList.topLayout.setBackgroundColor(darkerColor);
|
|
||||||
GradientDrawable gradientDrawable = new GradientDrawable(
|
|
||||||
GradientDrawable.Orientation.TOP_BOTTOM,
|
|
||||||
new int[]{darkerColor, darkerColor}
|
|
||||||
);
|
|
||||||
vb.rootLayout.setBackground(gradientDrawable);
|
|
||||||
Drawable newDrawable = CommonUtils.getNewDrawable(lighterColor, 24f, 24f, 0, 0);
|
|
||||||
vb.layoutPlayList.listLayout.setBackground(newDrawable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
if (mHandler != null && mRunnable != null)
|
|
||||||
mHandler.removeCallbacks(mRunnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBackPressed() {
|
|
||||||
if (vb.layoutPlayList.linearLayout.getVisibility() == View.VISIBLE) {
|
|
||||||
initShowPlayList(false);
|
|
||||||
} else {
|
|
||||||
super.onBackPressed(); // 调用系统默认的返回行为
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
|
||||||
if (fromUser) {
|
|
||||||
mediaControllerManager.getMediaController().seekTo(progress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
private void addDownloadListener() {
|
|
||||||
MyDownloadService.addDownloadListener(vmApplication);
|
|
||||||
vmApplication.downloadData.observe(this, new Observer<List<Download>>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(List<Download> downloads) {
|
|
||||||
if (downloads == null || downloads.size() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String id = downloads.get(downloads.size() - 1).request.id;
|
|
||||||
|
|
||||||
MediaItem curMediaItem = mediaControllerManager.getCurMediaItem();
|
|
||||||
if (curMediaItem != null) {
|
|
||||||
String mediaId = mediaControllerManager.getCurMediaItem().mediaId;
|
|
||||||
if (mediaId.equals(id)) {
|
|
||||||
vb.downloadPb.setVisibility(View.GONE);
|
|
||||||
vb.imDownload.setVisibility(View.VISIBLE);
|
|
||||||
vb.imDownload.setSelected(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CommonUtils.LogMsg("-------onChanged id=" + id);
|
|
||||||
if (mEnterType == MyValue.TYPE_ENTER_DOWNLOAD) {
|
|
||||||
//下载进入播放,这里进行重置播放列表并播放
|
|
||||||
mediaControllerManager.resetPlayList();
|
|
||||||
for (Download data : downloads) {
|
|
||||||
BoxDownloadSong boxDownloadSong = CommonUtils.downloadToBean(data);
|
|
||||||
downloadSongList.add(boxDownloadSong);
|
|
||||||
MediaItem mediaItem = CommonUtils.downloadToMediaItem(data);
|
|
||||||
mediaControllerManager.addMusicPlayList(mediaItem);
|
|
||||||
}
|
|
||||||
mediaControllerManager.playPositionMusic(mDefaultPlayStartIndex);
|
|
||||||
mediaControllerManager.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,169 +0,0 @@
|
|||||||
package com.hi.music.player.ui.activity;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.lifecycle.Observer;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.adapter.AdapterResult;
|
|
||||||
import com.hi.music.player.api.HomeItemClickListener;
|
|
||||||
import com.hi.music.player.databinding.ActivityResultListBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseResult;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseResultListChild;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
import com.hi.music.player.ui.fragmnt.viewmodel.VMCategoryList;
|
|
||||||
import com.hi.music.player.ui.fragmnt.viewmodel.VMResultList;
|
|
||||||
|
|
||||||
public class ResultListActivity extends BaseActivity<ActivityResultListBinding> implements HomeItemClickListener {
|
|
||||||
private VMResultList vm;
|
|
||||||
private String key;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ActivityResultListBinding getViewBinding() {
|
|
||||||
return ActivityResultListBinding.inflate(getLayoutInflater());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreateInit() {
|
|
||||||
vm = getActivityScopeViewModel(VMResultList.class);
|
|
||||||
key = getIntent().getStringExtra(MyValue.KEY_SEARCH_RESULT_BROWSER_ID);
|
|
||||||
vm.getList(key);
|
|
||||||
|
|
||||||
vm.data.observe(this, new Observer<ResponseResult>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(ResponseResult responseResult) {
|
|
||||||
vb.pbLoading.setVisibility(View.GONE);
|
|
||||||
if (responseResult == null) {
|
|
||||||
vb.layoutError.linearRetry.setVisibility(View.VISIBLE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
vb.pbLoading.setVisibility(View.GONE);
|
|
||||||
loadInfo(responseResult);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadInfo(ResponseResult result) {
|
|
||||||
Glide.with(this)
|
|
||||||
.asDrawable()
|
|
||||||
.load(result.getMainCovert())
|
|
||||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(CommonUtils.dpToPx(4))))
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
CommonUtils.LogMsg(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into(vb.covert);
|
|
||||||
vb.mainTitle.setText(result.getMainTitle());
|
|
||||||
AdapterResult adapterResult = new AdapterResult(this);
|
|
||||||
adapterResult.setHomeItemClickListener(this);
|
|
||||||
adapterResult.setData(result.getList());
|
|
||||||
vb.listRecycler.setAdapter(adapterResult);
|
|
||||||
vb.listRecycler.setLayoutManager(new LinearLayoutManager(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onInitClick() {
|
|
||||||
vb.imBack.setOnClickListener(this);
|
|
||||||
vb.layoutError.tvRetry.setOnClickListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFullScreen() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean statusBarLight() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean showPanel() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (v.equals(vb.imBack)) {
|
|
||||||
finish();
|
|
||||||
} else if (v.equals(vb.layoutError.tvRetry)) {
|
|
||||||
vm.getList(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClickResultSong(ResponseResultListChild child, int index) {
|
|
||||||
String videoId = child.getVideoId();
|
|
||||||
String playListId = child.getPlayListId();
|
|
||||||
String browserId = child.getBrowserId();
|
|
||||||
String pageType = child.getPageType();
|
|
||||||
String thumbnail = child.getThumbnail();
|
|
||||||
String songName = child.getSongName();
|
|
||||||
String subTitle = child.getSubTitle();
|
|
||||||
|
|
||||||
if (videoId != null && !videoId.isEmpty()) {
|
|
||||||
ResponseSingle responseSingle = new ResponseSingle();
|
|
||||||
responseSingle.setSongTitle(songName);
|
|
||||||
responseSingle.setSingerHead(thumbnail);
|
|
||||||
responseSingle.setVideoId(videoId);
|
|
||||||
responseSingle.setPlaylistId(playListId);
|
|
||||||
Intent intent = new Intent(this, PlayActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, responseSingle);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_CATEGORY_LIST_INDEX, index);
|
|
||||||
CommonUtils.LogMsg("-------------index=" + index);
|
|
||||||
startActivity(intent);
|
|
||||||
} else {
|
|
||||||
switch (pageType) {
|
|
||||||
case "MUSIC_PAGE_TYPE_ALBUM":
|
|
||||||
//专辑
|
|
||||||
CommonUtils.LogMsg("------------专辑-index=" + index + "--subTitle=" + subTitle);
|
|
||||||
case "MUSIC_PAGE_TYPE_PLAYLIST":
|
|
||||||
//精选
|
|
||||||
Intent intent1 = new Intent(this, CategoryListActivity.class);
|
|
||||||
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_TYPE, pageType);
|
|
||||||
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_SINGER_NAME, subTitle);
|
|
||||||
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_BROWSER_ID, browserId);
|
|
||||||
startActivity(intent1);
|
|
||||||
break;
|
|
||||||
case "MUSIC_PAGE_TYPE_ARTIST":
|
|
||||||
//粉丝可能还喜欢
|
|
||||||
Intent intent = new Intent(this, ResultListActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_SEARCH_RESULT_BROWSER_ID, browserId);
|
|
||||||
startActivity(intent);
|
|
||||||
finish();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,76 +0,0 @@
|
|||||||
package com.hi.music.player.ui.activity.viewmodel;
|
|
||||||
|
|
||||||
import android.util.Pair;
|
|
||||||
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.lifecycle.MutableLiveData;
|
|
||||||
import androidx.lifecycle.ViewModel;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.exoplayer.offline.Download;
|
|
||||||
import androidx.media3.exoplayer.offline.DownloadCursor;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.hi.music.player.api.RequestListener;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.BoxDownloadSong;
|
|
||||||
import com.hi.music.player.javabean.CustomerUrlInfo;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
import com.hi.music.player.media3.MyMediaControllerManager;
|
|
||||||
import com.hi.music.player.network.JsonHelper;
|
|
||||||
import com.hi.music.player.network.RetrofitManager;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
public class VMApplication extends ViewModel {
|
|
||||||
|
|
||||||
|
|
||||||
private MutableLiveData<List<ResponsePlayListInfo>> _playList = new MutableLiveData<List<ResponsePlayListInfo>>();
|
|
||||||
public LiveData<List<ResponsePlayListInfo>> playList = _playList;
|
|
||||||
|
|
||||||
|
|
||||||
private MutableLiveData<Integer> _playStatus = new MutableLiveData<Integer>();
|
|
||||||
public LiveData<Integer> playStatus = _playStatus;
|
|
||||||
|
|
||||||
|
|
||||||
private MutableLiveData<List<Download>> _downloadData = new MutableLiveData<>();
|
|
||||||
public LiveData<List<Download>> downloadData = _downloadData;
|
|
||||||
|
|
||||||
|
|
||||||
private MutableLiveData<Pair<Boolean,Download>> _downloadChange = new MutableLiveData<>();
|
|
||||||
public LiveData<Pair<Boolean,Download>> downloadChange = _downloadChange;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重置播放列表
|
|
||||||
*
|
|
||||||
* @param list
|
|
||||||
*/
|
|
||||||
public void reSetPlayList(List<ResponsePlayListInfo> list) {
|
|
||||||
_playList.setValue(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlayStatus(int status) {
|
|
||||||
_playStatus.setValue(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
public void setDownloadData(List<Download> downloadList) {
|
|
||||||
|
|
||||||
_downloadData.setValue(downloadList);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
public void setDownloadChange(Pair<Boolean,Download> download) {
|
|
||||||
_downloadChange.setValue(download);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
package com.hi.music.player.ui.activity.viewmodel;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.lifecycle.MutableLiveData;
|
|
||||||
import androidx.lifecycle.ViewModel;
|
|
||||||
|
|
||||||
import com.hi.music.player.api.RequestListener;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.CustomerUrlInfo;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayListInfo;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
import com.hi.music.player.media3.MyMediaControllerManager;
|
|
||||||
import com.hi.music.player.network.JsonHelper;
|
|
||||||
import com.hi.music.player.network.RetrofitManager;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
public class VMPlay extends ViewModel {
|
|
||||||
|
|
||||||
|
|
||||||
private MutableLiveData<List<ResponsePlayListInfo>> _playList = new MutableLiveData<List<ResponsePlayListInfo>>();
|
|
||||||
public LiveData<List<ResponsePlayListInfo>> playList = _playList;
|
|
||||||
|
|
||||||
|
|
||||||
private MutableLiveData<CustomerUrlInfo> _playUrlMutableLiveData = new MutableLiveData<CustomerUrlInfo>();
|
|
||||||
public LiveData<CustomerUrlInfo> playUrlLiveData = _playUrlMutableLiveData;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void getPlayMusicList(String playlistId, String videoId, String params, String musicVideoType) {
|
|
||||||
RetrofitManager.getInstance().getPlayList(params, playlistId, videoId, musicVideoType, new RequestListener<ResponseBody>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFail(String errorMsg) {
|
|
||||||
// TODO: 2024/10/8 播放列表拉取失败
|
|
||||||
_playList.setValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess(JSONObject data) {
|
|
||||||
// JSONObject jsonObject = CommonUtils.toJsonObject(data);
|
|
||||||
if (data != null) {
|
|
||||||
List<ResponsePlayListInfo> responsePlayListInfos = JsonHelper.ResolvePlayListJson(data);
|
|
||||||
_playList.setValue(responsePlayListInfos);
|
|
||||||
} else {
|
|
||||||
_playList.setValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getPlayUrl(String videoId, int playListIndex,boolean playNow) {
|
|
||||||
CustomerUrlInfo customerUrlInfo = new CustomerUrlInfo();
|
|
||||||
customerUrlInfo.setNeedPlayNow(playNow);
|
|
||||||
customerUrlInfo.setVideoId(videoId);
|
|
||||||
customerUrlInfo.setPlayMusicIndex(playListIndex);
|
|
||||||
RetrofitManager.getInstance().getPlayUrl(videoId, new RequestListener<ResponseBody>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFail(String errorMsg) {
|
|
||||||
CommonUtils.LogMsg("-------------此次网络请求失败 playNow="+playNow +"--playListIndex="+playListIndex);
|
|
||||||
_playUrlMutableLiveData.setValue(customerUrlInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess(JSONObject data) {
|
|
||||||
// JSONObject jsonObject = CommonUtils.toJsonObject(data);
|
|
||||||
if (data != null) {
|
|
||||||
ResponsePlayUrl responsePlayUrl = JsonHelper.ResolvePlayUrlJson(data);
|
|
||||||
if(responsePlayUrl == null){
|
|
||||||
// TODO: 2024/9/27
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MyMediaControllerManager.getInstance().UpdateAudioUrl(responsePlayUrl,playListIndex);
|
|
||||||
customerUrlInfo.setPlayUrl(responsePlayUrl);
|
|
||||||
|
|
||||||
}
|
|
||||||
_playUrlMutableLiveData.setValue(customerUrlInfo);
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -12,16 +12,13 @@ import androidx.fragment.app.Fragment;
|
|||||||
import androidx.lifecycle.ViewModel;
|
import androidx.lifecycle.ViewModel;
|
||||||
import androidx.viewbinding.ViewBinding;
|
import androidx.viewbinding.ViewBinding;
|
||||||
|
|
||||||
import com.hi.music.player.helper.ViewModelScope;
|
|
||||||
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class BaseFragment<T extends ViewBinding> extends Fragment {
|
public abstract class BaseFragment<T extends ViewBinding> extends Fragment {
|
||||||
private final ViewModelScope mViewModelScope = new ViewModelScope();
|
// private final ViewModelScope mViewModelScope = new ViewModelScope();
|
||||||
protected T Vb;
|
protected T Vb;
|
||||||
|
|
||||||
protected AppCompatActivity mActivity;
|
protected AppCompatActivity mActivity;
|
||||||
protected VMApplication vmApplication;
|
// protected VMApplication vmApplication;
|
||||||
public BaseFragment() {
|
public BaseFragment() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -34,7 +31,7 @@ public abstract class BaseFragment<T extends ViewBinding> extends Fragment {
|
|||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
Vb = getFragmentVb();
|
Vb = getFragmentVb();
|
||||||
vmApplication = getApplicationScopeViewModel(VMApplication.class);
|
// vmApplication = getApplicationScopeViewModel(VMApplication.class);
|
||||||
initView();
|
initView();
|
||||||
return Vb.getRoot();
|
return Vb.getRoot();
|
||||||
}
|
}
|
||||||
@ -42,14 +39,14 @@ public abstract class BaseFragment<T extends ViewBinding> extends Fragment {
|
|||||||
protected abstract T getFragmentVb();
|
protected abstract T getFragmentVb();
|
||||||
protected abstract void initView();
|
protected abstract void initView();
|
||||||
|
|
||||||
protected <K extends ViewModel> K getFragmentScopeViewModel(@NonNull Class<K> modelClass) {
|
// protected <K extends ViewModel> K getFragmentScopeViewModel(@NonNull Class<K> modelClass) {
|
||||||
return mViewModelScope.getFragmentScopeViewModel(this, modelClass);
|
// return mViewModelScope.getFragmentScopeViewModel(this, modelClass);
|
||||||
}
|
// }
|
||||||
protected <K extends ViewModel> K getActivityScopeViewModel(@NonNull Class<K> modelClass) {
|
// protected <K extends ViewModel> K getActivityScopeViewModel(@NonNull Class<K> modelClass) {
|
||||||
return mViewModelScope.getActivityScopeViewModel(mActivity, modelClass);
|
// return mViewModelScope.getActivityScopeViewModel(mActivity, modelClass);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected <K extends ViewModel> K getApplicationScopeViewModel(@NonNull Class<K> modelClass) {
|
// protected <K extends ViewModel> K getApplicationScopeViewModel(@NonNull Class<K> modelClass) {
|
||||||
return mViewModelScope.getApplicationScopeViewModel(modelClass);
|
// return mViewModelScope.getApplicationScopeViewModel(modelClass);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
@ -1,180 +0,0 @@
|
|||||||
package com.hi.music.player.ui.fragmnt;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.RestrictionsManager;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
|
||||||
import androidx.lifecycle.Observer;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.adapter.AdapterHome;
|
|
||||||
import com.hi.music.player.api.HomeItemClickListener;
|
|
||||||
import com.hi.music.player.api.OnHasUrlAction;
|
|
||||||
import com.hi.music.player.databinding.FragmentHomeBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseHome;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseCategory;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseHomeChild;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
import com.hi.music.player.network.RetrofitManager;
|
|
||||||
import com.hi.music.player.ui.activity.CategoryListActivity;
|
|
||||||
import com.hi.music.player.ui.activity.PlayActivity;
|
|
||||||
import com.hi.music.player.ui.fragmnt.viewmodel.VMHome;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
public class HomeFragment extends BaseFragment<FragmentHomeBinding> implements HomeItemClickListener {
|
|
||||||
|
|
||||||
|
|
||||||
private VMHome vmHome;
|
|
||||||
|
|
||||||
|
|
||||||
private int requestCount = 1;
|
|
||||||
|
|
||||||
private int totalPage = 3;
|
|
||||||
|
|
||||||
|
|
||||||
private List<ResponseHomeChild> childList = new ArrayList<>();
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected FragmentHomeBinding getFragmentVb() {
|
|
||||||
// 返回正确的 ViewBinding 实例
|
|
||||||
return FragmentHomeBinding.inflate(getLayoutInflater());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initView() {
|
|
||||||
|
|
||||||
// //标题导航栏颜色设置
|
|
||||||
// Vb.toolbar.setTitleTextColor(getResources().getColor(R.color.white));
|
|
||||||
AdapterHome adapterHome = new AdapterHome();
|
|
||||||
adapterHome.setHomeItemClickListener(this);
|
|
||||||
|
|
||||||
|
|
||||||
vmHome = getFragmentScopeViewModel(VMHome.class);
|
|
||||||
adapterHome.addLoadingFooter();
|
|
||||||
vmHome.getHome();
|
|
||||||
|
|
||||||
|
|
||||||
vmHome.data.observe(getViewLifecycleOwner(), new Observer<ResponseHome>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(ResponseHome responseHome) {
|
|
||||||
if (responseHome == null) {
|
|
||||||
adapterHome.removeLoadingFooter();
|
|
||||||
requestCount--;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Glide.with(requireContext())
|
|
||||||
.asDrawable()
|
|
||||||
.load(responseHome.getBackgroundUrl())
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.error(R.drawable.placeholder)
|
|
||||||
.listener(new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
|
||||||
// Vb.linearLayout.setBackground(resource);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.preload();
|
|
||||||
List<ResponseHomeChild> childList1 = responseHome.getChildList();
|
|
||||||
if (childList1 == null) return;
|
|
||||||
childList.addAll(childList1);
|
|
||||||
adapterHome.removeLoadingFooter();
|
|
||||||
adapterHome.addData(childList1);
|
|
||||||
if (requestCount == 1) {
|
|
||||||
adapterHome.addLoadingFooter();
|
|
||||||
vmHome.getHomeMore();
|
|
||||||
requestCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Vb.recyclerSongOfTheDay.setLayoutManager(new LinearLayoutManager(requireContext()));
|
|
||||||
Vb.recyclerSongOfTheDay.setAdapter(adapterHome);
|
|
||||||
Vb.recyclerSongOfTheDay.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
|
||||||
@Override
|
|
||||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
|
|
||||||
super.onScrolled(recyclerView, dx, dy);
|
|
||||||
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
|
|
||||||
if (layoutManager != null && layoutManager.findLastVisibleItemPosition() == childList.size() - 1) {
|
|
||||||
if (requestCount < totalPage && !adapterHome.isLoadingAdded()) {
|
|
||||||
CommonUtils.LogMsg("------loadmore--");
|
|
||||||
adapterHome.addLoadingFooter();
|
|
||||||
vmHome.getHomeMore();
|
|
||||||
requestCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClickItemSinger(ResponseSingle data) {
|
|
||||||
FragmentActivity activity = getActivity();
|
|
||||||
if (activity != null) {
|
|
||||||
Intent intent = new Intent(activity, PlayActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, data);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClickItemCategory(ResponseCategory data) {
|
|
||||||
FragmentActivity activity = getActivity();
|
|
||||||
if (activity != null) {
|
|
||||||
String pageType = data.getPageType();
|
|
||||||
String browseId = data.getBrowseId();
|
|
||||||
String twoSubtitle = data.getTwoSubtitle();
|
|
||||||
if (pageType.equals(MyValue.PAGE_TYPE_MV)||pageType.equals(MyValue.PAGE_TYPE_MV_LIST)) {
|
|
||||||
Intent intent = new Intent(activity, PlayActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_MV, data);
|
|
||||||
intent.putExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_SOURCE_MV);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
// else if (pageType.equals(MyValue.PAGE_TYPE_ALBUM)) {
|
|
||||||
// Intent intent = new Intent(activity, CategoryListActivity.class);
|
|
||||||
// intent.putExtra(MyValue.KEY_CATEGORY_LIST_TYPE, pageType);
|
|
||||||
// intent.putExtra(MyValue.KEY_CATEGORY_LIST_SINGER_NAME, twoSubtitle);
|
|
||||||
// intent.putExtra(MyValue.KEY_CATEGORY_LIST_BROWSER_ID, browseId);
|
|
||||||
// startActivity(intent);
|
|
||||||
// }
|
|
||||||
else {
|
|
||||||
Intent intent = new Intent(activity, CategoryListActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_CATEGORY_LIST_TYPE, pageType);
|
|
||||||
intent.putExtra(MyValue.KEY_CATEGORY_LIST_SINGER_NAME, twoSubtitle);
|
|
||||||
intent.putExtra(MyValue.KEY_CATEGORY_LIST_BROWSER_ID, browseId);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,143 +0,0 @@
|
|||||||
package com.hi.music.player.ui.fragmnt;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.util.Pair;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import androidx.annotation.OptIn;
|
|
||||||
import androidx.lifecycle.Observer;
|
|
||||||
import androidx.media3.common.util.UnstableApi;
|
|
||||||
import androidx.media3.exoplayer.offline.Download;
|
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.hi.music.player.R;
|
|
||||||
import com.hi.music.player.api.LikeSongListener;
|
|
||||||
import com.hi.music.player.databinding.FragmentProfileBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.BoxDownloadSong;
|
|
||||||
import com.hi.music.player.javabean.BoxLikeSong;
|
|
||||||
import com.hi.music.player.media3.MyDownloadService;
|
|
||||||
import com.hi.music.player.objectbox.ObjectBoxManager;
|
|
||||||
import com.hi.music.player.ui.activity.LikeSongActivity;
|
|
||||||
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import io.objectbox.reactive.DataSubscription;
|
|
||||||
|
|
||||||
|
|
||||||
public class ProfileFragment extends BaseFragment<FragmentProfileBinding> implements View.OnClickListener {
|
|
||||||
|
|
||||||
|
|
||||||
private DataSubscription dataSubscription;
|
|
||||||
|
|
||||||
private int likeSongCount = 0;
|
|
||||||
private int downloadSongCount = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected FragmentProfileBinding getFragmentVb() {
|
|
||||||
return FragmentProfileBinding.inflate(getLayoutInflater());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@OptIn(markerClass = UnstableApi.class)
|
|
||||||
@Override
|
|
||||||
protected void initView() {
|
|
||||||
|
|
||||||
dataSubscription = ObjectBoxManager.setLikeDataListener(new LikeSongListener() {
|
|
||||||
@Override
|
|
||||||
public void onLikeSongChange(List<BoxLikeSong> data) {
|
|
||||||
CommonUtils.LogMsg("------onLikeSongChange data=" + data.size());
|
|
||||||
int size = data.size();
|
|
||||||
likeSongCount = size;
|
|
||||||
Vb.tvLikeSize.setText(String.format(getString(R.string.like_song), size));
|
|
||||||
if (size == 0) {
|
|
||||||
Vb.likeCovert.setVisibility(View.GONE);
|
|
||||||
Vb.likeDefault.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
Vb.likeCovert.setVisibility(View.VISIBLE);
|
|
||||||
Vb.likeDefault.setVisibility(View.GONE);
|
|
||||||
BoxLikeSong boxLikeSong = data.get(size - 1);
|
|
||||||
Glide.with(requireContext())
|
|
||||||
.asDrawable()
|
|
||||||
.load(boxLikeSong.getCovert())
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.error(R.drawable.placeholder)
|
|
||||||
.into(Vb.likeCovert);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
MyDownloadService.updateDownloadUi(vmApplication);
|
|
||||||
|
|
||||||
vmApplication.downloadData.observe(getViewLifecycleOwner(), new Observer<List<Download>>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(List<Download> downloads) {
|
|
||||||
int size = downloads.size();
|
|
||||||
Vb.tvDownloadSize.setText(String.format(getString(R.string.download_song), size));
|
|
||||||
downloadSongCount = size;
|
|
||||||
if (size > 0) {
|
|
||||||
Download download = downloads.get(downloads.size() - 1);
|
|
||||||
BoxDownloadSong boxDownloadSong = CommonUtils.downloadToBean(download);
|
|
||||||
|
|
||||||
Vb.downloadCovert.setVisibility(View.VISIBLE);
|
|
||||||
Vb.downloadDefault.setVisibility(View.GONE);
|
|
||||||
Glide.with(requireContext())
|
|
||||||
.asDrawable()
|
|
||||||
.load(boxDownloadSong.getCovert())
|
|
||||||
.placeholder(R.drawable.placeholder)
|
|
||||||
.error(R.drawable.placeholder)
|
|
||||||
.into(Vb.downloadCovert);
|
|
||||||
} else {
|
|
||||||
Vb.downloadCovert.setVisibility(View.GONE);
|
|
||||||
Vb.downloadDefault.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Vb.relayoutLike.setOnClickListener(this);
|
|
||||||
Vb.relayoutDownload.setOnClickListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
CommonUtils.LogMsg("------ProfileFragment-onStart");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroyView() {
|
|
||||||
super.onDestroyView();
|
|
||||||
if (dataSubscription != null) {
|
|
||||||
dataSubscription.cancel();
|
|
||||||
}
|
|
||||||
CommonUtils.LogMsg("------ProfileFragment-onDestroyView");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
CommonUtils.LogMsg("------ProfileFragment-onDestroy");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (v.equals(Vb.relayoutLike)) {
|
|
||||||
if (likeSongCount > 0) {
|
|
||||||
Intent intent = new Intent(requireActivity(), LikeSongActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_ENTER_LIKE_ACTIVITY_TYPE, MyValue.KEY_ENTER_LIKE_ACTIVITY_TYPE_LIKE);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
} else if (v.equals(Vb.relayoutDownload)) {
|
|
||||||
if (downloadSongCount > 0) {
|
|
||||||
Intent intent = new Intent(requireActivity(), LikeSongActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_ENTER_LIKE_ACTIVITY_TYPE, MyValue.KEY_ENTER_LIKE_ACTIVITY_TYPE_DOWNLOAD);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,224 +0,0 @@
|
|||||||
package com.hi.music.player.ui.fragmnt;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.text.Editable;
|
|
||||||
import android.text.TextWatcher;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.inputmethod.EditorInfo;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.lifecycle.Observer;
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
||||||
|
|
||||||
import com.hi.music.player.adapter.AdapterSearch;
|
|
||||||
import com.hi.music.player.adapter.AdapterSuggestion;
|
|
||||||
import com.hi.music.player.api.HomeItemClickListener;
|
|
||||||
import com.hi.music.player.databinding.FragmentSearchBinding;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseSearch;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSearchChild;
|
|
||||||
import com.hi.music.player.javabean.response.child.ResponseSingle;
|
|
||||||
import com.hi.music.player.ui.activity.CategoryListActivity;
|
|
||||||
import com.hi.music.player.ui.activity.PlayActivity;
|
|
||||||
import com.hi.music.player.ui.activity.ResultListActivity;
|
|
||||||
import com.hi.music.player.ui.fragmnt.viewmodel.VMSearch;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
public class SearchFragment extends BaseFragment<FragmentSearchBinding> implements HomeItemClickListener, View.OnClickListener {
|
|
||||||
|
|
||||||
|
|
||||||
private VMSearch vmSearch;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected FragmentSearchBinding getFragmentVb() {
|
|
||||||
return FragmentSearchBinding.inflate(getLayoutInflater());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initView() {
|
|
||||||
// Vb.etSearch.requestFocus();
|
|
||||||
vmSearch = getFragmentScopeViewModel(VMSearch.class);
|
|
||||||
|
|
||||||
Vb.etSearch.addTextChangedListener(new TextWatcher() {
|
|
||||||
@Override
|
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterTextChanged(Editable s) {
|
|
||||||
String input = s.toString();
|
|
||||||
if (!input.isEmpty()) {
|
|
||||||
vmSearch.getSuggestion(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Vb.etSearch.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
|
||||||
@Override
|
|
||||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
|
||||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
|
||||||
String s = v.getText().toString();
|
|
||||||
CommonUtils.LogMsg("------------v=" + s);
|
|
||||||
startQuery(s);
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
initSuggestionRecycler();
|
|
||||||
initResultRecycler();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initSuggestionRecycler() {
|
|
||||||
AdapterSuggestion adapterSuggestion = new AdapterSuggestion();
|
|
||||||
Vb.recyclerSuggestion.setLayoutManager(new LinearLayoutManager(requireContext()));
|
|
||||||
Vb.recyclerSuggestion.setAdapter(adapterSuggestion);
|
|
||||||
adapterSuggestion.setHomeItemClickListener(this);
|
|
||||||
Vb.imCancel.setOnClickListener(this);
|
|
||||||
vmSearch.suggestion.observe(getViewLifecycleOwner(), new Observer<List<String>>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(List<String> strings) {
|
|
||||||
if (strings != null) {
|
|
||||||
adapterSuggestion.setData(strings);
|
|
||||||
CommonUtils.LogMsg("------------更新=");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void initResultRecycler(){
|
|
||||||
AdapterSearch adapterSearch = new AdapterSearch();
|
|
||||||
adapterSearch.setHomeItemClickListener(this);
|
|
||||||
Vb.recyclerResult.setLayoutManager(new LinearLayoutManager(requireContext()));
|
|
||||||
Vb.recyclerResult.setAdapter(adapterSearch);
|
|
||||||
vmSearch.result.observe(getViewLifecycleOwner(), new Observer<List<ResponseSearch>>() {
|
|
||||||
@Override
|
|
||||||
public void onChanged(List<ResponseSearch> responseSearches) {
|
|
||||||
if(responseSearches == null){
|
|
||||||
CommonUtils.LogMsg("------------更新结果 null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
adapterSearch.setData(responseSearches);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startQuery(String query){
|
|
||||||
Vb.recyclerSuggestion.setVisibility(View.GONE);
|
|
||||||
Vb.recyclerResult.setVisibility(View.VISIBLE);
|
|
||||||
vmSearch.getSearchResult(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClickItemSuggestion(boolean isSearch, String data) {
|
|
||||||
if (isSearch) {
|
|
||||||
startQuery(data);
|
|
||||||
} else {
|
|
||||||
Vb.etSearch.setText(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (v.equals(Vb.imCancel)) {
|
|
||||||
Vb.etSearch.setText("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//点击搜索结果的play按钮
|
|
||||||
@Override
|
|
||||||
public void onClickSearchResultBest(ResponseSearch responseSearch) {
|
|
||||||
String beastBrowserId = responseSearch.getBeastBrowserId();
|
|
||||||
String beastVideoId = responseSearch.getBeastVideoId();
|
|
||||||
String beastSongTitle = responseSearch.getBeastSongTitle();
|
|
||||||
String beastSongTCovert = responseSearch.getBeastSongTCovert();
|
|
||||||
String pageType = responseSearch.getPageType();
|
|
||||||
|
|
||||||
if(beastVideoId!= null&&!beastVideoId.isEmpty()){
|
|
||||||
CommonUtils.LogMsg("---------击搜索结果的play按钮--beastVideoId="+beastVideoId);
|
|
||||||
|
|
||||||
ResponseSingle responseSingle = new ResponseSingle();
|
|
||||||
responseSingle.setSongTitle(beastSongTitle);
|
|
||||||
responseSingle.setSingerHead(beastSongTCovert);
|
|
||||||
responseSingle.setVideoId(beastVideoId);
|
|
||||||
responseSingle.setPlaylistId("");
|
|
||||||
Intent intent = new Intent(requireActivity(), PlayActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, responseSingle);
|
|
||||||
startActivity(intent);
|
|
||||||
}else if(beastBrowserId!= null&&!beastBrowserId.isEmpty()){
|
|
||||||
CommonUtils.LogMsg("---------击搜索结果的play按钮--pageType="+pageType);
|
|
||||||
switch (pageType){
|
|
||||||
case "MUSIC_PAGE_TYPE_PLAYLIST":
|
|
||||||
case "MUSIC_PAGE_TYPE_ALBUM":
|
|
||||||
Intent intent1 = new Intent(requireActivity(), CategoryListActivity.class);
|
|
||||||
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_TYPE, pageType);
|
|
||||||
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_SINGER_NAME, responseSearch.getBeastSongDescribe());
|
|
||||||
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_BROWSER_ID, beastBrowserId);
|
|
||||||
startActivity(intent1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Intent intent = new Intent(requireActivity(), ResultListActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_SEARCH_RESULT_BROWSER_ID, beastBrowserId);
|
|
||||||
startActivity(intent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//点击搜索结果普通项
|
|
||||||
@Override
|
|
||||||
public void onClickSearchResult(ResponseSearchChild responseSearchChild) {
|
|
||||||
String browserId = responseSearchChild.getBrowserId();
|
|
||||||
String songVideoId = responseSearchChild.getSongVideoId();
|
|
||||||
String songCovert = responseSearchChild.getSongCovert();
|
|
||||||
String songTitle = responseSearchChild.getSongTitle();
|
|
||||||
String songDescribe = responseSearchChild.getSongDescribe();
|
|
||||||
|
|
||||||
if(browserId!= null&&!browserId.isEmpty()){
|
|
||||||
String pageType = responseSearchChild.getPageType();
|
|
||||||
CommonUtils.LogMsg("---------点击搜索结果--pageType="+pageType);
|
|
||||||
switch (pageType){
|
|
||||||
case "MUSIC_PAGE_TYPE_ARTIST":
|
|
||||||
Intent intent = new Intent(requireActivity(), ResultListActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_SEARCH_RESULT_BROWSER_ID, browserId);
|
|
||||||
startActivity(intent);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Intent intent1 = new Intent(requireActivity(), CategoryListActivity.class);
|
|
||||||
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_TYPE, pageType);
|
|
||||||
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_SINGER_NAME, songDescribe);
|
|
||||||
intent1.putExtra(MyValue.KEY_CATEGORY_LIST_BROWSER_ID, browserId);
|
|
||||||
startActivity(intent1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}else {
|
|
||||||
CommonUtils.LogMsg("---------点击搜索结果--VideoId="+songVideoId);
|
|
||||||
|
|
||||||
ResponseSingle responseSingle = new ResponseSingle();
|
|
||||||
responseSingle.setSongTitle(songTitle);
|
|
||||||
responseSingle.setSingerHead(songCovert);
|
|
||||||
responseSingle.setVideoId(songVideoId);
|
|
||||||
responseSingle.setPlaylistId("");
|
|
||||||
Intent intent = new Intent(requireActivity(), PlayActivity.class);
|
|
||||||
intent.putExtra(MyValue.KEY_PLAY_ACTIVITY_SINGER, responseSingle);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package com.hi.music.player.ui.fragmnt.viewmodel;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.lifecycle.MutableLiveData;
|
|
||||||
import androidx.lifecycle.ViewModel;
|
|
||||||
|
|
||||||
import com.hi.music.player.api.RequestListener;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseCategoryList;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseHome;
|
|
||||||
import com.hi.music.player.javabean.response.ResponsePlayUrl;
|
|
||||||
import com.hi.music.player.network.JsonHelper;
|
|
||||||
import com.hi.music.player.network.RetrofitManager;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
public class VMCategoryList extends ViewModel {
|
|
||||||
private MutableLiveData<ResponseCategoryList> _data = new MutableLiveData<>();
|
|
||||||
public LiveData<ResponseCategoryList> data = _data;
|
|
||||||
|
|
||||||
|
|
||||||
public void getList(String browseId) {
|
|
||||||
|
|
||||||
RetrofitManager.getInstance().getCategoryList(browseId, new RequestListener<ResponseBody>() {
|
|
||||||
@Override
|
|
||||||
public void onFail(String errorMsg) {
|
|
||||||
_data.setValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess(JSONObject data) {
|
|
||||||
if (data != null) {
|
|
||||||
ResponseCategoryList responseCategoryList = JsonHelper.ResolveCategoryList(data,browseId);
|
|
||||||
_data.setValue(responseCategoryList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
package com.hi.music.player.ui.fragmnt.viewmodel;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.lifecycle.MutableLiveData;
|
|
||||||
import androidx.lifecycle.ViewModel;
|
|
||||||
|
|
||||||
import com.hi.music.player.MusicApplication;
|
|
||||||
import com.hi.music.player.api.RequestListener;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.helper.MyValue;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseHome;
|
|
||||||
import com.hi.music.player.network.JsonHelper;
|
|
||||||
import com.hi.music.player.network.RetrofitManager;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
public class VMHome extends ViewModel {
|
|
||||||
|
|
||||||
|
|
||||||
private MutableLiveData<ResponseHome> _data = new MutableLiveData<ResponseHome>();
|
|
||||||
public LiveData<ResponseHome> data = _data;
|
|
||||||
|
|
||||||
private String continuation, clickTrackingParams, visitorData;
|
|
||||||
|
|
||||||
public void getHome() {
|
|
||||||
RetrofitManager.getInstance().getHomeData(new RequestListener<ResponseBody>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFail(String errorMsg) {
|
|
||||||
_data.setValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess(JSONObject data) {
|
|
||||||
// JSONObject jsonObject = CommonUtils.toJsonObject(data);
|
|
||||||
if (data != null) {
|
|
||||||
ResponseHome responseHome = JsonHelper.ResolveHomeJson(data);
|
|
||||||
|
|
||||||
continuation = responseHome.getContinuation();
|
|
||||||
clickTrackingParams = responseHome.getClickTrackingParams();
|
|
||||||
visitorData = responseHome.getVisitorData();
|
|
||||||
MusicApplication.setVisitorData(visitorData);
|
|
||||||
_data.setValue(responseHome);
|
|
||||||
} else {
|
|
||||||
_data.setValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void getHomeMore() {
|
|
||||||
RetrofitManager.getInstance().getHomeMoreData(continuation, clickTrackingParams, visitorData, new RequestListener<ResponseBody>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFail(String errorMsg) {
|
|
||||||
_data.setValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess(JSONObject data) {
|
|
||||||
// JSONObject jsonObject = CommonUtils.toJsonObject(data);
|
|
||||||
if (data != null) {
|
|
||||||
ResponseHome responseHome = JsonHelper.ResolveHomeMoreJson(data);
|
|
||||||
|
|
||||||
continuation = responseHome.getContinuation();
|
|
||||||
clickTrackingParams = responseHome.getClickTrackingParams();
|
|
||||||
|
|
||||||
_data.setValue(responseHome);
|
|
||||||
} else {
|
|
||||||
_data.setValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
package com.hi.music.player.ui.fragmnt.viewmodel;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.lifecycle.MutableLiveData;
|
|
||||||
import androidx.lifecycle.ViewModel;
|
|
||||||
|
|
||||||
import com.hi.music.player.api.RequestListener;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseCategoryList;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseResult;
|
|
||||||
import com.hi.music.player.network.JsonHelper;
|
|
||||||
import com.hi.music.player.network.RetrofitManager;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
public class VMResultList extends ViewModel {
|
|
||||||
private MutableLiveData<ResponseResult> _data = new MutableLiveData<>();
|
|
||||||
public LiveData<ResponseResult> data = _data;
|
|
||||||
|
|
||||||
|
|
||||||
public void getList(String browseId) {
|
|
||||||
|
|
||||||
RetrofitManager.getInstance().getCategoryList(browseId, new RequestListener<ResponseBody>() {
|
|
||||||
@Override
|
|
||||||
public void onFail(String errorMsg) {
|
|
||||||
_data.setValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess(JSONObject data) {
|
|
||||||
if (data != null) {
|
|
||||||
ResponseResult responseResult = JsonHelper.ResolveSearchResultList(data);
|
|
||||||
_data.setValue(responseResult);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
package com.hi.music.player.ui.fragmnt.viewmodel;
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.lifecycle.MutableLiveData;
|
|
||||||
import androidx.lifecycle.ViewModel;
|
|
||||||
|
|
||||||
import com.hi.music.player.api.RequestListener;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseHome;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseSearch;
|
|
||||||
import com.hi.music.player.network.JsonHelper;
|
|
||||||
import com.hi.music.player.network.RetrofitManager;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
public class VMSearch extends ViewModel {
|
|
||||||
private MutableLiveData<List<String>> _suggestion = new MutableLiveData<List<String>>();
|
|
||||||
public LiveData<List<String>> suggestion = _suggestion;
|
|
||||||
|
|
||||||
|
|
||||||
private MutableLiveData<List<ResponseSearch>> _result= new MutableLiveData<List<ResponseSearch>>();
|
|
||||||
public LiveData<List<ResponseSearch>> result = _result;
|
|
||||||
public void getSuggestion(String input) {
|
|
||||||
RetrofitManager.getInstance().getSearchSuggestion(input,new RequestListener<ResponseBody>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFail(String errorMsg) {
|
|
||||||
_suggestion.setValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess(JSONObject data) {
|
|
||||||
if (data != null) {
|
|
||||||
List<String> stringList = JsonHelper.ResolveSearchSuggestion(data);
|
|
||||||
CommonUtils.LogMsg("------------onSuccess= stringList="+stringList );
|
|
||||||
_suggestion.setValue(stringList);
|
|
||||||
} else {
|
|
||||||
_suggestion.setValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void getSearchResult(String query) {
|
|
||||||
RetrofitManager.getInstance().getSearch(query, new RequestListener<ResponseBody>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFail(String errorMsg) {
|
|
||||||
_result.setValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSuccess(JSONObject data) {
|
|
||||||
if (data != null) {
|
|
||||||
List<ResponseSearch> responseSearches = JsonHelper.ResolveSearchResult(data);
|
|
||||||
_result.setValue(responseSearches);
|
|
||||||
} else {
|
|
||||||
_result.setValue(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
package com.hi.music.player.ui.paging;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.paging.PagingSource;
|
|
||||||
import androidx.paging.PagingState;
|
|
||||||
|
|
||||||
import com.hi.music.player.api.RequestListener;
|
|
||||||
import com.hi.music.player.helper.CommonUtils;
|
|
||||||
import com.hi.music.player.javabean.response.ResponseHome;
|
|
||||||
import com.hi.music.player.network.JsonHelper;
|
|
||||||
import com.hi.music.player.network.RetrofitManager;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import io.reactivex.Single;
|
|
||||||
import kotlin.coroutines.Continuation;
|
|
||||||
import okhttp3.ResponseBody;
|
|
||||||
|
|
||||||
public class MyPagingSource extends PagingSource<Integer, ResponseHome> {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Integer getRefreshKey(@NonNull PagingState<Integer, ResponseHome> pagingState) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public Object load(@NonNull LoadParams<Integer> loadParams, @NonNull Continuation<? super PagingSource.LoadResult<Integer, ResponseHome>> continuation) {
|
|
||||||
int nextPage = 1;
|
|
||||||
Integer key = loadParams.getKey();
|
|
||||||
if (key != null) {
|
|
||||||
nextPage = key + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try {
|
|
||||||
// // 使用 Single 来处理异步请求
|
|
||||||
//
|
|
||||||
// List<ResponseHome> result = Single.<List<ResponseHome>>create(emitter -> {
|
|
||||||
// RetrofitManager.getInstance().getHomeData();
|
|
||||||
// })
|
|
||||||
// .blockingGet(); // 阻塞获取结果
|
|
||||||
//
|
|
||||||
// return new LoadResult.Page<>(
|
|
||||||
// result,
|
|
||||||
// page == 1 ? null : page - 1,
|
|
||||||
// result.isEmpty() ? null : page + 1
|
|
||||||
// );
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// return new LoadResult.Error<>(e);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,307 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="@color/black"
|
|
||||||
android:fillViewport="true"
|
|
||||||
android:id="@+id/root_layout"
|
|
||||||
android:layout_width="match_parent" >
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ui.activity.PlayActivity">
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="@drawable/black_gradient" />
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:id="@+id/content_layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/im_back"
|
|
||||||
android:layout_width="42dp"
|
|
||||||
android:layout_height="42dp"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="35dp"
|
|
||||||
android:padding="9dp"
|
|
||||||
android:src="@drawable/arrow_bottom"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
|
||||||
android:id="@+id/card_playerView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="300dp"
|
|
||||||
android:layout_marginStart="20dp"
|
|
||||||
android:layout_marginTop="30dp"
|
|
||||||
android:layout_marginEnd="20dp"
|
|
||||||
app:cardBackgroundColor="@color/black"
|
|
||||||
app:cardCornerRadius="8dp"
|
|
||||||
app:cardElevation="0dp"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/im_back">
|
|
||||||
|
|
||||||
<androidx.media3.ui.PlayerView
|
|
||||||
android:id="@+id/player_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:resize_mode="zoom"
|
|
||||||
app:show_buffering="when_playing"
|
|
||||||
app:show_shuffle_button="false"
|
|
||||||
app:use_controller="false" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/im_covert"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:src="@mipmap/ic_launcher"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/im_back" />
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/progressBarLoading"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:indeterminateTint="@color/white"
|
|
||||||
android:visibility="gone"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/card_playerView"
|
|
||||||
app:layout_constraintLeft_toLeftOf="@id/card_playerView"
|
|
||||||
app:layout_constraintRight_toRightOf="@id/card_playerView"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/card_playerView" />
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/layout_error"
|
|
||||||
layout="@layout/layout_error"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/card_playerView"
|
|
||||||
app:layout_constraintLeft_toLeftOf="@id/card_playerView"
|
|
||||||
app:layout_constraintRight_toRightOf="@id/card_playerView"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/card_playerView" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tv_song_name"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="10dp"
|
|
||||||
android:layout_marginTop="25dp"
|
|
||||||
android:text=""
|
|
||||||
android:textColor="@color/text_color_1"
|
|
||||||
android:textSize="19sp"
|
|
||||||
app:layout_constraintLeft_toLeftOf="@id/card_playerView"
|
|
||||||
app:layout_constraintRight_toRightOf="@id/card_playerView"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/card_playerView" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tv_singer_name"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="7dp"
|
|
||||||
android:text="9999999999999999999999999999999999999999999999"
|
|
||||||
android:textColor="@color/white_60_color"
|
|
||||||
android:textSize="15sp"
|
|
||||||
app:layout_constraintRight_toRightOf="@id/tv_song_name"
|
|
||||||
app:layout_constraintLeft_toLeftOf="@id/tv_song_name"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/tv_song_name" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/layout_like"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="34dp"
|
|
||||||
android:layout_marginTop="14dp"
|
|
||||||
android:background="@drawable/bg_like_layout"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingStart="22dp"
|
|
||||||
android:paddingEnd="22dp"
|
|
||||||
app:layout_constraintLeft_toLeftOf="@id/card_playerView"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/tv_singer_name">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/im_like"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:src="@drawable/selector_like" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:text="@string/like"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="14sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:id="@+id/layout_download"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="34dp"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:background="@drawable/bg_like_layout"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingStart="22dp"
|
|
||||||
android:paddingEnd="22dp"
|
|
||||||
app:layout_constraintLeft_toRightOf="@id/layout_like"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/layout_like">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/im_download"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:src="@drawable/selector_download" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/download_pb"
|
|
||||||
android:layout_width="24dp"
|
|
||||||
android:layout_height="24dp"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:indeterminateTint="@color/panel_bg"
|
|
||||||
android:progressBackgroundTint="@color/panel_bg"
|
|
||||||
android:progressTint="@color/panel_bg"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:layout_toEndOf="@id/im_download"
|
|
||||||
android:text="@string/download"
|
|
||||||
android:textColor="@color/white"
|
|
||||||
android:textSize="14sp" />
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<SeekBar
|
|
||||||
android:id="@+id/play_progress"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="25dp"
|
|
||||||
android:maxHeight="3dp"
|
|
||||||
android:paddingStart="5dp"
|
|
||||||
android:paddingLeft="0dp"
|
|
||||||
android:paddingEnd="5dp"
|
|
||||||
android:paddingRight="0dp"
|
|
||||||
android:progress="3"
|
|
||||||
android:progressDrawable="@drawable/seekbar_progress_drawable"
|
|
||||||
android:thumb="@drawable/seekbar_thumb"
|
|
||||||
app:layout_constraintLeft_toLeftOf="@id/card_playerView"
|
|
||||||
app:layout_constraintRight_toRightOf="@id/card_playerView"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/layout_like" />
|
|
||||||
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/progressBar_buffer"
|
|
||||||
style="?android:attr/progressBarStyleHorizontal"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="3dp"
|
|
||||||
android:paddingStart="5dp"
|
|
||||||
android:paddingEnd="5dp"
|
|
||||||
android:progress="10"
|
|
||||||
android:progressDrawable="@drawable/horizontal_progressbar"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/play_progress"
|
|
||||||
app:layout_constraintLeft_toLeftOf="@id/play_progress"
|
|
||||||
app:layout_constraintRight_toRightOf="@id/play_progress"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/play_progress" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tv_current"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
android:paddingStart="5dp"
|
|
||||||
android:text="0:00"
|
|
||||||
android:textColor="@color/white_60_color"
|
|
||||||
app:layout_constraintStart_toStartOf="@id/play_progress"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/play_progress" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tv_duration"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="5dp"
|
|
||||||
android:paddingEnd="5dp"
|
|
||||||
android:text="0:00"
|
|
||||||
android:textColor="@color/white_60_color"
|
|
||||||
app:layout_constraintEnd_toEndOf="@id/play_progress"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/play_progress" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/btn_play"
|
|
||||||
android:layout_width="66dp"
|
|
||||||
android:layout_height="66dp"
|
|
||||||
android:layout_marginTop="15dp"
|
|
||||||
android:src="@drawable/selector_icon_play"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/tv_duration" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/btn_previous"
|
|
||||||
android:layout_width="45dp"
|
|
||||||
android:layout_height="45dp"
|
|
||||||
android:layout_marginEnd="24dp"
|
|
||||||
android:padding="12dp"
|
|
||||||
android:src="@mipmap/icon_previous_true"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/btn_play"
|
|
||||||
app:layout_constraintEnd_toStartOf="@id/btn_play"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/btn_play" />
|
|
||||||
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/btn_next"
|
|
||||||
android:layout_width="45dp"
|
|
||||||
android:layout_height="45dp"
|
|
||||||
android:layout_marginStart="24dp"
|
|
||||||
android:padding="12dp"
|
|
||||||
android:src="@mipmap/icon_next_true"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/btn_play"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/btn_play"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/btn_play" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/btn_music_list"
|
|
||||||
android:layout_width="44dp"
|
|
||||||
android:layout_height="44dp"
|
|
||||||
android:padding="10dp"
|
|
||||||
android:src="@mipmap/icon_list"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/btn_play"
|
|
||||||
app:layout_constraintLeft_toRightOf="@id/btn_next"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/btn_play" />
|
|
||||||
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/btn_loop"
|
|
||||||
android:layout_width="44dp"
|
|
||||||
android:layout_height="44dp"
|
|
||||||
android:padding="10dp"
|
|
||||||
android:src="@drawable/icon_looper_no"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/btn_play"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toLeftOf="@id/btn_previous"
|
|
||||||
app:layout_constraintTop_toTopOf="@id/btn_play" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/layout_playList"
|
|
||||||
layout="@layout/dialog_play_list" />
|
|
||||||
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="70dp"
|
|
||||||
android:id="@+id/item_layout"
|
|
||||||
android:paddingStart="20dp">
|
|
||||||
|
|
||||||
<androidx.cardview.widget.CardView
|
|
||||||
android:id="@+id/card"
|
|
||||||
android:layout_width="60dp"
|
|
||||||
android:layout_height="60dp"
|
|
||||||
app:cardElevation="0dp"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
app:cardCornerRadius="6dp">
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/im_covert"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:adjustViewBounds="true"
|
|
||||||
android:src="@drawable/placeholder" />
|
|
||||||
</androidx.cardview.widget.CardView>
|
|
||||||
|
|
||||||
|
|
||||||
<com.hi.music.player.customerview.AnimaPlayingView
|
|
||||||
android:id="@+id/view_playing"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignStart="@id/card"
|
|
||||||
android:layout_alignTop="@id/card"
|
|
||||||
android:layout_alignEnd="@id/card"
|
|
||||||
android:layout_alignBottom="@id/card"
|
|
||||||
android:layout_marginBottom="10dp" />
|
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:paddingEnd="10dp"
|
|
||||||
android:layout_toEndOf="@id/card"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/song_name"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/app_name"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:ellipsize="end"
|
|
||||||
android:textColor="@color/text_color_1"
|
|
||||||
android:textSize="14sp" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/artist_name"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="2dp"
|
|
||||||
android:text="@string/app_name"
|
|
||||||
android:textColor="@color/white_60_color"
|
|
||||||
android:textSize="11sp" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
Loading…
Reference in New Issue
Block a user