增加下载列表
This commit is contained in:
parent
39020493e6
commit
64728f5096
@ -78,6 +78,7 @@ dependencies {
|
||||
implementation("androidx.media3:media3-exoplayer-dash:1.4.1")
|
||||
implementation("androidx.media3:media3-session:1.4.1")
|
||||
implementation("androidx.media3:media3-ui:1.4.1")
|
||||
implementation ("androidx.media3:media3-database:1.4.1")
|
||||
//----------media3
|
||||
|
||||
|
||||
|
||||
@ -46,9 +46,58 @@
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
},
|
||||
{
|
||||
"id": "2:2417298624721077393",
|
||||
"lastPropertyId": "8:376288481537034221",
|
||||
"name": "BoxDownloadSong",
|
||||
"properties": [
|
||||
{
|
||||
"id": "1:7539246810224330948",
|
||||
"name": "id",
|
||||
"type": 6,
|
||||
"flags": 1
|
||||
},
|
||||
{
|
||||
"id": "2:4996334478861162671",
|
||||
"name": "songName",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "3:7837922119072734767",
|
||||
"name": "singerName",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "4:102902831836074640",
|
||||
"name": "videoId",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "5:230178850883428921",
|
||||
"name": "covert",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "6:5148334492661309747",
|
||||
"name": "durationMs",
|
||||
"type": 6
|
||||
},
|
||||
{
|
||||
"id": "7:9082762505752465280",
|
||||
"name": "duration",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "8:376288481537034221",
|
||||
"name": "cachePath",
|
||||
"type": 9
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
}
|
||||
],
|
||||
"lastEntityId": "1:7260744904384376845",
|
||||
"lastEntityId": "2:2417298624721077393",
|
||||
"lastIndexId": "0:0",
|
||||
"lastRelationId": "0:0",
|
||||
"lastSequenceId": "0:0",
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||
<uses-permission
|
||||
@ -66,6 +67,17 @@
|
||||
<action android:name="androidx.media3.session.MediaSessionService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name=".media3.MyDownloadService"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="dataSync"
|
||||
tools:ignore="ForegroundServicePermission">
|
||||
<intent-filter>
|
||||
<action android:name="androidx.media3.exoplayer.downloadService.action.RESTART" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service
|
||||
android:name=".service.MusicPlayerForegroundService"
|
||||
android:enabled="true"
|
||||
|
||||
@ -3,9 +3,13 @@ package com.hi.music.player;
|
||||
import android.app.Application;
|
||||
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.helper.CommonUtils;
|
||||
import com.hi.music.player.javabean.MyObjectBox;
|
||||
import com.hi.music.player.media3.MyDownloadService;
|
||||
import com.hi.music.player.media3.MyMediaControllerManager;
|
||||
import com.hi.music.player.objectbox.ObjectBoxManager;
|
||||
|
||||
@ -30,11 +34,13 @@ public class MusicApplication extends Application {
|
||||
return visitorData;
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
myApplication = this;
|
||||
ObjectBoxManager.init(this);
|
||||
MyDownloadService.init(this);
|
||||
MyMediaControllerManager.getInstance().init(new MediaControllerStatusListener() {
|
||||
@Override
|
||||
public void onMediaControllerComplete(boolean isOk) {
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
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);
|
||||
|
||||
|
||||
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,5 +1,7 @@
|
||||
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;
|
||||
@ -68,8 +70,22 @@ public interface HomeItemClickListener {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 点击喜爱歌曲列表的某一首歌曲
|
||||
* @param boxLikeSong
|
||||
* @param index
|
||||
*/
|
||||
default void onClickLikeSong(BoxLikeSong boxLikeSong, int index){
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 点击下载歌曲列表的某一首歌曲
|
||||
* @param index
|
||||
*/
|
||||
default void onClickDownloadSong(Download download, int index){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -13,17 +13,23 @@ 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.util.UnstableApi;
|
||||
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.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -84,18 +90,18 @@ public class CommonUtils {
|
||||
//time 3:45 转换成毫秒
|
||||
public static long convertToMilliseconds(String time) {
|
||||
String[] parts = time.split(":");
|
||||
if(parts.length == 2){
|
||||
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{
|
||||
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;
|
||||
return (hours * 60L * 60L + minutes * 60L + seconds) * 1000 - 1000;
|
||||
}
|
||||
|
||||
|
||||
@ -111,9 +117,9 @@ public class CommonUtils {
|
||||
|
||||
// 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 {
|
||||
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
|
||||
}
|
||||
|
||||
@ -174,7 +180,7 @@ public class CommonUtils {
|
||||
}
|
||||
|
||||
|
||||
public static void getMainColor(Drawable imDraw, onImageColorListener listener){
|
||||
public static void getMainColor(Drawable imDraw, onImageColorListener listener) {
|
||||
|
||||
BitmapDrawable drawable = (BitmapDrawable) imDraw;
|
||||
// 使用 Palette 提取颜色
|
||||
@ -188,7 +194,7 @@ public class CommonUtils {
|
||||
if (dominantSwatch != null) {
|
||||
int dominantColor = dominantSwatch.getRgb(); // 获取 RGB 颜色
|
||||
listener.onImageColor(dominantColor);
|
||||
}else {
|
||||
} else {
|
||||
listener.onImageColor(-1);
|
||||
}
|
||||
}
|
||||
@ -217,6 +223,7 @@ public class CommonUtils {
|
||||
drawable.setCornerRadii(radii);
|
||||
return drawable;
|
||||
}
|
||||
|
||||
public static void extractColorsFromImage(Drawable drawable, View view) {
|
||||
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
|
||||
|
||||
@ -227,34 +234,33 @@ public class CommonUtils {
|
||||
int mutedColor = palette.getMutedColor(0);
|
||||
|
||||
// 创建左右渐变色
|
||||
createGradientBackground(vibrantColor, mutedColor,view);
|
||||
createGradientBackground(vibrantColor, mutedColor, view);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void createGradientBackground(int leftColor, int rightColor, View view) {
|
||||
GradientDrawable gradientDrawable = new android.graphics.drawable.GradientDrawable(
|
||||
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)){
|
||||
if (localConfiguration != null) {
|
||||
if (CommonUtils.isUriFormat(localConfiguration.uri)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -268,9 +274,18 @@ public class CommonUtils {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogMsg( "URI parsing failed: " + e.getMessage());
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,10 +18,11 @@ public class MyValue {
|
||||
//专辑
|
||||
public static final String PAGE_TYPE_ALBUM="MUSIC_PAGE_TYPE_ALBUM";
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------PlayActivity
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 歌手单曲进入的数据key
|
||||
*/
|
||||
@ -91,7 +92,6 @@ public class MyValue {
|
||||
public final static int TYPE_ENTER_LIKE= 4;
|
||||
|
||||
|
||||
//-----------------------------PlayActivity
|
||||
|
||||
|
||||
|
||||
@ -105,11 +105,23 @@ public class MyValue {
|
||||
public static String KEY_CATEGORY_LIST_BROWSER_ID= "browser_id";
|
||||
|
||||
|
||||
//-----------------------------CategoryListActivity
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------ResultListActivity
|
||||
public static String KEY_SEARCH_RESULT_BROWSER_ID= "search_result_browser_id";
|
||||
//-------------------------------------ResultListActivity
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------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;
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
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 ;
|
||||
|
||||
//下载的音视频文件存储路径
|
||||
private String cachePath ;
|
||||
|
||||
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 getCachePath() {
|
||||
return cachePath;
|
||||
}
|
||||
|
||||
public void setCachePath(String cachePath) {
|
||||
this.cachePath = cachePath;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
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 MyCacheManager {
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,210 @@
|
||||
package com.hi.music.player.media3;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
|
||||
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.google.gson.Gson;
|
||||
import com.hi.music.player.MusicApplication;
|
||||
import com.hi.music.player.R;
|
||||
import com.hi.music.player.helper.CommonUtils;
|
||||
import com.hi.music.player.javabean.BoxDownloadSong;
|
||||
import com.hi.music.player.ui.activity.viewmodel.VMApplication;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
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) {
|
||||
if (mDownloadManager == null) {
|
||||
StandaloneDatabaseProvider databaseProvider = new StandaloneDatabaseProvider(context);
|
||||
SimpleCache downloadCache = MyCacheManager.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) {
|
||||
// 下载完成
|
||||
CommonUtils.LogMsg("----------------下载完成 id=" + id + "--thread=" + Thread.currentThread().getName());
|
||||
updateDownloadUi(vmApplication);
|
||||
|
||||
} else if (download.state == Download.STATE_FAILED) {
|
||||
// 下载失败
|
||||
CommonUtils.LogMsg("----------------下载失败 id=" + id + "---finalException=" + finalException.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadRemoved(DownloadManager downloadManager, Download download) {
|
||||
String id = download.request.id;
|
||||
CommonUtils.LogMsg("----------------onDownloadRemoved id=" + id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@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() {
|
||||
// 初始化下载管理器
|
||||
// StandaloneDatabaseProvider databaseProvider = new StandaloneDatabaseProvider(this);
|
||||
// SimpleCache downloadCache = MyCacheManager.getMyCache(databaseProvider);
|
||||
// DefaultHttpDataSource.Factory factory = new DefaultHttpDataSource.Factory();
|
||||
// Executor downloadExecutor = Runnable::run;
|
||||
//
|
||||
// downloadManager = new DownloadManager(
|
||||
// this,
|
||||
// databaseProvider, // 数据库提供者
|
||||
// downloadCache,
|
||||
// factory, // 数据源工厂
|
||||
// downloadExecutor // 线程池
|
||||
// );
|
||||
//
|
||||
// downloadManager.setMaxParallelDownloads(3); // 设置最大并行下载数
|
||||
// downloadManager.addListener(new DownloadManager.Listener() {
|
||||
// @Override
|
||||
// public void onDownloadChanged(DownloadManager downloadManager, Download download, @Nullable Exception finalException) {
|
||||
// String id = download.request.id;
|
||||
// if (download.state == Download.STATE_COMPLETED) {
|
||||
// // 下载完成
|
||||
// CommonUtils.LogMsg("----------------下载完成 id="+id);
|
||||
// byte[] data = download.request.data;
|
||||
// String additionalData = new String(data, StandardCharsets.UTF_8);
|
||||
// Gson gson = new Gson();
|
||||
// BoxDownloadSong boxDownloadSong = gson.fromJson(additionalData, BoxDownloadSong.class);
|
||||
//
|
||||
//
|
||||
//
|
||||
// } else if (download.state == Download.STATE_FAILED) {
|
||||
// // 下载失败
|
||||
// CommonUtils.LogMsg("----------------下载失败 id="+id+"---finalException="+finalException.getMessage());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onDownloadRemoved(DownloadManager downloadManager, Download download) {
|
||||
// String id = download.request.id;
|
||||
// CommonUtils.LogMsg("----------------onDownloadRemoved id="+id);
|
||||
// }
|
||||
// });
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -48,7 +48,7 @@ public class PlaybackService extends MediaSessionService {
|
||||
long maxCacheSize = 100 * 1024 * 1024; // 缓存大小 100MB
|
||||
StandaloneDatabaseProvider databaseProvider = new StandaloneDatabaseProvider(this);
|
||||
SimpleCache cache = new SimpleCache(cacheDir, new LeastRecentlyUsedCacheEvictor(maxCacheSize), databaseProvider);
|
||||
|
||||
SimpleCache downloadCache = MyCacheManager.getMyCache(databaseProvider);
|
||||
|
||||
|
||||
DefaultHttpDataSource.Factory httpDataSourceFactory = new DefaultHttpDataSource.Factory().setAllowCrossProtocolRedirects(true);
|
||||
|
||||
@ -3,9 +3,15 @@ package com.hi.music.player.ui.activity;
|
||||
import android.content.Intent;
|
||||
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;
|
||||
@ -13,6 +19,7 @@ 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;
|
||||
@ -22,20 +29,48 @@ public class LikeSongActivity extends BaseActivity<ActivityLikeSongBinding> impl
|
||||
|
||||
|
||||
private List<BoxLikeSong> boxLikeSongs;
|
||||
private int mType;
|
||||
@Override
|
||||
protected ActivityLikeSongBinding getViewBinding() {
|
||||
return ActivityLikeSongBinding.inflate(getLayoutInflater());
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
@Override
|
||||
protected void onCreateInit() {
|
||||
boxLikeSongs = ObjectBoxManager.queryAllLike();
|
||||
AdapterLikeSong adapterLikeSong = new AdapterLikeSong();
|
||||
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()));
|
||||
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();
|
||||
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()));
|
||||
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
|
||||
@ -91,5 +126,11 @@ public class LikeSongActivity extends BaseActivity<ActivityLikeSongBinding> impl
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClickDownloadSong(Download download, int index) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -20,6 +20,10 @@ import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.MediaMetadata;
|
||||
import androidx.media3.common.Player;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
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;
|
||||
@ -29,6 +33,7 @@ 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.AdapterPlayList;
|
||||
@ -39,17 +44,20 @@ 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.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.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.List;
|
||||
|
||||
public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements SeekBar.OnSeekBarChangeListener {
|
||||
@ -114,7 +122,7 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
mEnterType = intent.getIntExtra(MyValue.KEY_ENTER_SOURCE, MyValue.TYPE_ENTER_SOURCE_SINGLE);
|
||||
initPlayerView();
|
||||
initProgressHandler();
|
||||
|
||||
addDownloadListener();
|
||||
|
||||
CommonUtils.LogMsg("--------mEnterType=" + mEnterType);
|
||||
switch (mEnterType) {
|
||||
@ -347,6 +355,7 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
vb.btnLoop.setOnClickListener(this);
|
||||
vb.layoutLike.setOnClickListener(this);
|
||||
vb.layoutDownload.setOnClickListener(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -597,11 +606,62 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
}
|
||||
|
||||
|
||||
}else if(v.equals(vb.layoutDownload)){
|
||||
vb.downloadPb.setVisibility(View.VISIBLE);
|
||||
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);
|
||||
String contentUri= "https://rr3---sn-tt1e7nlz.googlevideo.com/videoplayback?expire=1730203742&ei=_nsgZ4KrKsCW2_gP3vHpsQk&ip=146.19.167.8&id=o-AMLbkjliQ0-OoP2NcJ1EcdlaKQ7tyJP2QHMOIxrhiBKx&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&met=1730182142%2C&mh=HX&mm=31%2C29&mn=sn-tt1e7nlz%2Csn-vgqsrnzd&ms=au%2Crdu&mv=m&mvi=3&pl=24&rms=au%2Cau&gcr=us&initcwndbps=241250&svpuc=1&sabr=1&rqh=1&mt=1730181899&fvip=1&keepalive=yes&fexp=51312688%2C51326932&c=ANDROID&sparams=expire%2Cei%2Cip%2Cid%2Csource%2Crequiressl%2Cxpc%2Cgcr%2Csvpuc%2Csabr%2Crqh&sig=AJfQdSswRgIhAOxvUuLE3tfOLtuF9OP0zmy8tl4HQvm-6BlDjOnkhyGZAiEAjjL2jOFMqrjDgHMtwkWaQb9CNXz6lNqi1ShWWzGjtjY%3D&lsparams=met%2Cmh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Crms%2Cinitcwndbps&lsig=ACJ0pHgwRQIhAJ7XPfdAxtoFrNQ13TkFhqHiGYGaKaBfxC6gb9fbB369AiBfx8gshE7jEgx0wOHce2IVHrZ_4aQvYptrSh23tfZqqA%3D%3D";
|
||||
DownloadRequest downloadRequest = new DownloadRequest.Builder(videoId1, Uri.parse(contentUri))
|
||||
.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){
|
||||
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);
|
||||
|
||||
return boxDownloadSong;
|
||||
}
|
||||
|
||||
/**
|
||||
* 控制播放列表的显示
|
||||
*
|
||||
@ -721,4 +781,9 @@ public class PlayActivity extends BaseActivity<ActivityPlayBinding> implements S
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
private void addDownloadListener(){
|
||||
MyDownloadService.addDownloadListener(vmApplication);
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,19 @@
|
||||
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;
|
||||
@ -16,6 +24,7 @@ import com.hi.music.player.network.RetrofitManager;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.ResponseBody;
|
||||
@ -31,6 +40,10 @@ public class VMApplication extends ViewModel {
|
||||
public LiveData<Integer> playStatus = _playStatus;
|
||||
|
||||
|
||||
private MutableLiveData<List<Download>> _downloadData = new MutableLiveData<>();
|
||||
public LiveData<List<Download>> downloadData = _downloadData;
|
||||
|
||||
|
||||
/**
|
||||
* 重置播放列表
|
||||
* @param list
|
||||
@ -44,4 +57,17 @@ public class VMApplication extends ViewModel {
|
||||
}
|
||||
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
public void setDownloadData( List<Download> downloadList) {
|
||||
//
|
||||
// byte[] data = download.request.data;
|
||||
// String additionalData = new String(data, StandardCharsets.UTF_8);
|
||||
// Gson gson = new Gson();
|
||||
// BoxDownloadSong boxDownloadSong = gson.fromJson(additionalData, BoxDownloadSong.class);
|
||||
// String covert = boxDownloadSong.getCovert();
|
||||
// String count = String.valueOf(downloadCount);
|
||||
//
|
||||
// Pair<String, String> stringStringPair = new Pair(covert,count);
|
||||
_downloadData.setValue(downloadList);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,56 +1,58 @@
|
||||
package com.hi.music.player.ui.fragmnt;
|
||||
|
||||
import static com.hi.music.player.javabean.BoxLikeSong_.covert;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.Pair;
|
||||
import android.view.View;
|
||||
|
||||
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 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.MusicApplication;
|
||||
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{
|
||||
public class ProfileFragment extends BaseFragment<FragmentProfileBinding> implements View.OnClickListener {
|
||||
|
||||
|
||||
private DataSubscription dataSubscription;
|
||||
|
||||
private int likeSongSCount = 0;
|
||||
private int likeSongCount = 0;
|
||||
private int downloadSongCount = 0;
|
||||
|
||||
private VMApplication vmApplication;
|
||||
|
||||
@Override
|
||||
protected FragmentProfileBinding getFragmentVb() {
|
||||
return FragmentProfileBinding.inflate(getLayoutInflater());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
@Override
|
||||
protected void initView() {
|
||||
dataSubscription = ObjectBoxManager.setLikeDataListener(new LikeSongListener() {
|
||||
vmApplication = getApplicationScopeViewModel(VMApplication.class);
|
||||
dataSubscription = ObjectBoxManager.setLikeDataListener(new LikeSongListener() {
|
||||
@Override
|
||||
public void onLikeSongChange(List<BoxLikeSong> data) {
|
||||
CommonUtils.LogMsg("------onLikeSongChange data=" + data.size());
|
||||
int size = data.size();
|
||||
likeSongSCount = size;
|
||||
likeSongCount = size;
|
||||
Vb.tvLikeSize.setText(String.format(getString(R.string.like_song), size));
|
||||
if (size == 0) {
|
||||
Vb.likeCovert.setVisibility(View.GONE);
|
||||
@ -68,8 +70,34 @@ public class ProfileFragment extends BaseFragment<FragmentProfileBinding> implem
|
||||
}
|
||||
}
|
||||
});
|
||||
MyDownloadService.updateDownloadUi(vmApplication);
|
||||
|
||||
Vb.relayoutLike.setOnClickListener(this);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -83,7 +111,7 @@ public class ProfileFragment extends BaseFragment<FragmentProfileBinding> implem
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
if(dataSubscription!= null){
|
||||
if (dataSubscription != null) {
|
||||
dataSubscription.cancel();
|
||||
}
|
||||
CommonUtils.LogMsg("------ProfileFragment-onDestroyView");
|
||||
@ -97,9 +125,16 @@ public class ProfileFragment extends BaseFragment<FragmentProfileBinding> implem
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(v.equals(Vb.relayoutLike)){
|
||||
if(likeSongSCount>0){
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
android:text="@string/text_like_song"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="17sp"
|
||||
android:id="@+id/tv_title"
|
||||
app:layout_constraintBottom_toBottomOf="@id/im_back"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
|
||||
@ -209,7 +209,7 @@
|
||||
android:indeterminateTint="@color/panel_bg"
|
||||
android:progressBackgroundTint="@color/panel_bg"
|
||||
android:progressTint="@color/panel_bg"
|
||||
android:visibility="visible" />
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@ -37,4 +37,5 @@
|
||||
<string name="like_song">Songs %d</string>
|
||||
<string name="download_song">Offline %d</string>
|
||||
<string name="text_like_song">Favorite Songs</string>
|
||||
<string name="text_offline_song">Offline Songs</string>
|
||||
</resources>
|
||||
Loading…
Reference in New Issue
Block a user