feat(login): 优化登录流程并添加 IP 地址设置功能- 移除了无用的 Activity 声明和注释- 调整了 fragment_bflb_db 中布局参数的设置

- 新增了 DialogEditText 自定义对话框用于 IP 地址输入
- 优化了 HomeSteer 类中的登录逻辑,支持保存和读取 IP 地址- 更新了 main 类中的 API地址初始化方式
- 新增了 wl 类中的 getCookie静态方法用于获取 Cookie
This commit is contained in:
muqing 2025-02-13 15:51:35 +08:00
parent 4857237d8d
commit 4bfeec09e4
18 changed files with 268 additions and 125 deletions

View File

@ -1,20 +0,0 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.muqingbfq",
"variantName": "debug",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "2.6.0",
"outputFile": "Cloud_music-debug-v2.6.0.apk"
}
],
"elementType": "File"
}

View File

@ -20,7 +20,10 @@ import androidx.media3.session.MediaSessionService;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.muqingbfq.api.url; import com.muqingbfq.api.url;
import com.muqingbfq.mq.MediaItemAdapter;
import com.muqingbfq.mq.gj; import com.muqingbfq.mq.gj;
import com.muqingbfq.mq.wj; import com.muqingbfq.mq.wj;
@ -32,8 +35,6 @@ public class PlaybackService extends MediaSessionService {
public static MediaSession mediaSession = null; public static MediaSession mediaSession = null;
public static List<MP3> list = new ArrayList<>(); public static List<MP3> list = new ArrayList<>();
//历史记录
// public static final List<MediaItem> listHistory = new ArrayList<>();
public static void ListSave() { public static void ListSave() {
new Thread(() -> wj.xrwb(wj.filesdri + "list.json", new Gson().toJson(list))).start(); new Thread(() -> wj.xrwb(wj.filesdri + "list.json", new Gson().toJson(list))).start();
@ -54,7 +55,7 @@ public class PlaybackService extends MediaSessionService {
Player player = mediaSession.getPlayer(); Player player = mediaSession.getPlayer();
if (player.getCurrentMediaItemIndex() == player.getMediaItemCount() - 1) { if (player.getCurrentMediaItemIndex() == player.getMediaItemCount() - 1) {
// 如果是最后一项回到第一项并播放 // 如果是最后一项回到第一项并播放
player.seekTo(0,0); player.seekTo(0, 0);
player.play(); player.play();
} }
} }
@ -72,12 +73,30 @@ public class PlaybackService extends MediaSessionService {
// 输出当前的 MediaItem 信息 // 输出当前的 MediaItem 信息
String title = mediaItem.mediaMetadata.title != null ? mediaItem.mediaMetadata.title.toString() : "未知标题"; String title = mediaItem.mediaMetadata.title != null ? mediaItem.mediaMetadata.title.toString() : "未知标题";
String artist = mediaItem.mediaMetadata.artist != null ? mediaItem.mediaMetadata.artist.toString() : "未知艺术家"; String artist = mediaItem.mediaMetadata.artist != null ? mediaItem.mediaMetadata.artist.toString() : "未知艺术家";
// gj.sc(title + " - " + artist);
new Thread(() -> {
try {
String dqwb = wj.dqwb(wj.gd + "mp3_listHistory.json");
Gson gson = new GsonBuilder()
.registerTypeAdapter(MediaItem.class, new MediaItemAdapter()) // 绑定适配器
.create();
List<MediaItem> listHistory = gson.fromJson(dqwb, new TypeToken<List<MediaItem>>(){}.getType());
if (listHistory != null) {
listHistory.removeIf(mediaItem1 -> mediaItem1.mediaId.equals(mediaItem.mediaId));
listHistory.add(0, mediaItem);
}
String json = gson.toJson(listHistory);
wj.xrwb(wj.gd + "mp3_listHistory.json", json);
} catch (Exception e) {
gj.sc(e);
}
}).start();
// bfqkz.lishi_list.removeIf(mp3 -> mp3.id.equals(mediaItem.mediaId)); // bfqkz.lishi_list.removeIf(mp3 -> mp3.id.equals(mediaItem.mediaId));
// bfqkz.lishi_list.add(0, new MP3(mediaItem.mediaId, title, artist, mediaItem.mediaMetadata.artworkUri.toString())); // bfqkz.lishi_list.add(0, new MP3(mediaItem.mediaId, title, artist, mediaItem.mediaMetadata.artworkUri.toString()));
// new Thread(() -> wj.xrwb(wj.gd + "mp3_hc.json", new Gson().toJson(bfqkz.lishi_list))).start(); // new Thread(() -> wj.xrwb(wj.gd + "mp3_hc.json", new Gson().toJson(bfqkz.lishi_list))).start();
} }
} }
@Override @Override
public void onTracksChanged(@Nullable Tracks tracks) { public void onTracksChanged(@Nullable Tracks tracks) {
gj.sc(tracks); gj.sc(tracks);
@ -139,7 +158,6 @@ public class PlaybackService extends MediaSessionService {
this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
mediaSession.setSessionActivity(pendingIntent); mediaSession.setSessionActivity(pendingIntent);
// 添加 ExoPlayer 监听器 // 添加 ExoPlayer 监听器
player.addListener(PlayerListener);
String nickname = wj.dqwb(wj.filesdri + "list.json"); String nickname = wj.dqwb(wj.filesdri + "list.json");
@ -157,6 +175,25 @@ public class PlaybackService extends MediaSessionService {
} }
} }
// String mp3_listHistory = wj.dqwb(wj.gd + "mp3_listHistory.json");
// if (!Strings.isNullOrEmpty(mp3_listHistory)) {
// try {
// Gson gson = new GsonBuilder()
// .registerTypeAdapter(MediaItem.class, new MediaItemAdapter()) // 绑定适配器
// .create();
//// 序列化 List<MediaItem>转换成 JSON
//// String json = gson.toJson(listHistory);
//// System.out.println("JSON 数据: " + json);
//// 反序列化 JSON恢复 List<MediaItem>
// listHistory.addAll(gson.fromJson(mp3_listHistory, new com.google.gson.reflect.TypeToken<List<MediaItem>>() {
// }.getType()));
// gj.sc("listHistory:" + listHistory.size());
// } catch (Exception e) {
// gj.sc("listHistory:" + e);
// }
// }
player.addListener(PlayerListener);
} }
@Nullable @Nullable
@ -182,7 +219,6 @@ public class PlaybackService extends MediaSessionService {
.setArtworkUri(Uri.parse(mp3.picurl)) // 图片URL .setArtworkUri(Uri.parse(mp3.picurl)) // 图片URL
.build(); .build();
// 创建带有元数据的 MediaItem // 创建带有元数据的 MediaItem
return new MediaItem.Builder() return new MediaItem.Builder()
.setMediaId(mp3.id) // 设置媒体的唯一ID .setMediaId(mp3.id) // 设置媒体的唯一ID
.setUri(Strings.isNullOrEmpty(mp3.url) ? "" : mp3.url) .setUri(Strings.isNullOrEmpty(mp3.url) ? "" : mp3.url)

View File

@ -56,6 +56,8 @@ import com.muqingbfq.mq.AppCompatActivity;
import com.muqingbfq.mq.MusicViewModel; import com.muqingbfq.mq.MusicViewModel;
import com.muqingbfq.mq.gj; import com.muqingbfq.mq.gj;
import java.util.Objects;
public class Music extends AppCompatActivity<ActivityMusicBinding> implements GestureDetector.OnGestureListener { public class Music extends AppCompatActivity<ActivityMusicBinding> implements GestureDetector.OnGestureListener {
@ -239,6 +241,34 @@ public class Music extends AppCompatActivity<ActivityMusicBinding> implements Ge
//播放列表 //播放列表
binding.bfqListMp3.setOnClickListener(v -> com.muqingbfq.fragment.bflb_db.start(v.getContext())); binding.bfqListMp3.setOnClickListener(v -> com.muqingbfq.fragment.bflb_db.start(v.getContext()));
binding.like.setOnClickListener(v -> {
MediaItem currentMediaItem = player.getCurrentMediaItem();
boolean islike = bfq_an.islike(Objects.requireNonNull(currentMediaItem).mediaId);
gj.sc(islike);
if (islike) {
if (bfq_an.DelLike(currentMediaItem)) {
binding.like.setImageResource(R.drawable.like);
}
}else{
if (bfq_an.AddLike(currentMediaItem)) {
binding.like.setImageResource(R.drawable.like_yes);
}
}
});
binding.image2.setOnClickListener(v -> {
MediaItem currentMediaItem = player.getCurrentMediaItem();
if (currentMediaItem != null){
String stringBuilder = "标题:" + currentMediaItem.mediaMetadata.title + System.lineSeparator() +
"歌手:" + currentMediaItem.mediaMetadata.artist + System.lineSeparator() +
"歌曲链接:" + "https://music.163.com/#/song?id=" + currentMediaItem.mediaId;
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, stringBuilder);
startActivity(Intent.createChooser(intent, "分享到"));
}
});
} }
//是否拖动 //是否拖动
@ -276,7 +306,7 @@ public class Music extends AppCompatActivity<ActivityMusicBinding> implements Ge
player.removeListener(Listener); player.removeListener(Listener);
} }
private Player.Listener Listener = new Player.Listener() { private final Player.Listener Listener = new Player.Listener() {
@Override @Override
public void onEvents(@NonNull Player player, @NonNull Player.Events events) { public void onEvents(@NonNull Player player, @NonNull Player.Events events) {
// 监听播放状态变化 // 监听播放状态变化
@ -311,7 +341,9 @@ public class Music extends AppCompatActivity<ActivityMusicBinding> implements Ge
if (player.getPlayWhenReady()) { if (player.getPlayWhenReady()) {
if (bfqkz.lrc != null) { if (bfqkz.lrc != null) {
String[] strings = Media.loadLyric(); String[] strings = Media.loadLyric();
binding.lrcView.loadLyric(strings[0], strings[1]); if (strings != null) {
binding.lrcView.loadLyric(strings[0], strings[1]);
}
} }
gj.sc("播放开始"); gj.sc("播放开始");
@ -362,7 +394,12 @@ public class Music extends AppCompatActivity<ActivityMusicBinding> implements Ge
binding.zz.setText(artist); binding.zz.setText(artist);
SetBackGround(metadata.artworkUri); SetBackGround(metadata.artworkUri);
} }
boolean islike = bfq_an.islike(Objects.requireNonNull(player.getCurrentMediaItem()).mediaId);
if (islike) {
binding.like.setImageResource(R.drawable.like_yes);
} else {
binding.like.setImageResource(R.drawable.like);
}
} }
@ -400,7 +437,7 @@ public class Music extends AppCompatActivity<ActivityMusicBinding> implements Ge
Palette.Builder builder = new Palette.Builder(bitmap); Palette.Builder builder = new Palette.Builder(bitmap);
builder.generate(palette -> { builder.generate(palette -> {
// 获取图片中柔和的亮色 // 获取图片中柔和的亮色
int lightMutedColor = palette.getLightMutedColor(Color.GRAY); int lightMutedColor = Objects.requireNonNull(palette).getLightMutedColor(Color.GRAY);
Palette.Swatch vibrantSwatch = palette.getLightVibrantSwatch(); Palette.Swatch vibrantSwatch = palette.getLightVibrantSwatch();
if (vibrantSwatch != null) { if (vibrantSwatch != null) {
int bodyTextColor = vibrantSwatch.getBodyTextColor(); int bodyTextColor = vibrantSwatch.getBodyTextColor();

View File

@ -1,13 +1,20 @@
package com.muqingbfq.api; package com.muqingbfq.api;
import static com.muqingbfq.mq.MediaItemAdapter.type;
import android.app.Activity; import android.app.Activity;
import android.os.Environment; import android.os.Environment;
import androidx.media3.common.MediaItem;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.mpatric.mp3agic.ID3v2; import com.mpatric.mp3agic.ID3v2;
import com.mpatric.mp3agic.Mp3File; import com.mpatric.mp3agic.Mp3File;
import com.muqingbfq.MP3; import com.muqingbfq.MP3;
import com.muqingbfq.PlaybackService;
import com.muqingbfq.mq.MediaItemAdapter;
import com.muqingbfq.mq.gj; import com.muqingbfq.mq.gj;
import com.muqingbfq.mq.wj; import com.muqingbfq.mq.wj;
import com.muqingbfq.mq.wl; import com.muqingbfq.mq.wl;
@ -38,8 +45,6 @@ public class playlist extends Thread {
return playlist.hq_xz(list); return playlist.hq_xz(list);
case "mp3_like.json": case "mp3_like.json":
return playlist.hq_like(list); return playlist.hq_like(list);
case "mp3_hc.json":
return hq_hc(list);
} }
list.clear(); list.clear();
try { try {
@ -129,11 +134,16 @@ public class playlist extends Thread {
if (dqwb == null) { if (dqwb == null) {
return false; return false;
} }
Type type = new TypeToken<List<MP3>>() { Gson gson = new GsonBuilder().registerTypeAdapter(MediaItem.class, new MediaItemAdapter())
}.getType(); .create();
Gson gson = new Gson(); List<MediaItem> o = gson.fromJson(dqwb, type);
list.clear(); for (MediaItem mediaItem : o) {
list.addAll(gson.fromJson(dqwb, type)); if (mediaItem.mediaMetadata.title != null && mediaItem.mediaMetadata.artist != null && mediaItem.mediaMetadata.artworkUri != null) {
list.add(new MP3(mediaItem.mediaId, mediaItem.mediaMetadata.title.toString(),
mediaItem.mediaMetadata.artist.toString(),
mediaItem.mediaMetadata.artworkUri.toString()));
}
}
return true; return true;
} catch (Exception e) { } catch (Exception e) {
gj.sc("失败的错误 " + e); gj.sc("失败的错误 " + e);
@ -160,23 +170,27 @@ public class playlist extends Thread {
return false; return false;
} }
public static boolean hq_hc(List<MP3> list) { public static void hq_listHistory(List<MP3> list) {
try { try {
String dqwb = wj.dqwb(wj.gd + "mp3_hc.json"); String dqwb = wj.dqwb(wj.gd + "mp3_listHistory.json");
if (dqwb == null) { Gson gson = new GsonBuilder()
return false; .registerTypeAdapter(MediaItem.class, new MediaItemAdapter()) // 绑定适配器
.create();
List<MediaItem> listHistory = gson.fromJson(dqwb, type);
if (listHistory != null) {
int size = listHistory.size();
for (int i = 0; i < size; i++) {
MediaItem mediaItem = listHistory.get(i);
if (mediaItem.mediaMetadata.title != null && mediaItem.mediaMetadata.artist != null && mediaItem.mediaMetadata.artworkUri != null) {
list.add(new MP3(mediaItem.mediaId, mediaItem.mediaMetadata.title.toString(),
mediaItem.mediaMetadata.artist.toString(),
mediaItem.mediaMetadata.artworkUri.toString()));
}
}
} }
Type type = new TypeToken<List<MP3>>() {
}.getType();
Gson gson = new Gson();
list.clear();
list.addAll(gson.fromJson(dqwb, type));
return true;
} catch (Exception e) { } catch (Exception e) {
gj.sc("失败的错误 " + e); gj.sc(e);
wj.sc(wj.gd + "mp3_hc.json");
} }
return false;
} }

View File

@ -3,9 +3,13 @@ package com.muqingbfq;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import androidx.media3.common.MediaItem;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.muqingbfq.api.url; import com.muqingbfq.api.url;
import com.muqingbfq.mq.MediaItemAdapter;
import com.muqingbfq.mq.gj; import com.muqingbfq.mq.gj;
import com.muqingbfq.mq.wj; import com.muqingbfq.mq.wj;
@ -18,43 +22,51 @@ import java.util.Locale;
public class bfq_an { public class bfq_an {
static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss", Locale.CHINA); static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss", Locale.CHINA);
public static String getTime(long time) { public static String getTime(long time) {
return simpleDateFormat.format(new Date(time)); return simpleDateFormat.format(new Date(time));
} }
public static boolean islike() { public static boolean islike(String id) {
boolean contains = false;
String dqwb = wj.dqwb(wj.gd + "mp3_like.json"); String dqwb = wj.dqwb(wj.gd + "mp3_like.json");
if (dqwb != null) { if (dqwb != null) {
try { try {
Type type = new TypeToken<List<MP3>>() { Gson gson = new GsonBuilder().registerTypeAdapter(MediaItem.class, new MediaItemAdapter())
}.getType(); .create();
List<MP3> o = new Gson().fromJson(dqwb, type); List<MediaItem> o = gson.fromJson(dqwb, MediaItemAdapter.type);
if (o != null) { if (o != null) {
contains = o.contains(bfqkz.xm); return o.stream().anyMatch(mediaItem -> mediaItem.mediaId.equals(id));
} }
} catch (Exception e) { } catch (Exception e) {
wj.sc(wj.gd + "mp3_like.json"); wj.sc(wj.gd + "mp3_like.json");
} }
} }
return bfqkz.like_bool = contains; return false;
} }
public static boolean getlike(MP3 xm) { public static boolean AddLike(MediaItem xm) {
boolean contains = false;
String dqwb = wj.dqwb(wj.gd + "mp3_like.json"); String dqwb = wj.dqwb(wj.gd + "mp3_like.json");
if (dqwb != null) { if (dqwb == null) {
try { dqwb = "[]";
Type type = new TypeToken<List<MP3>>() {
}.getType();
List<MP3> o = new Gson().fromJson(dqwb, type);
if (o != null) {
contains = o.contains(xm);
}
} catch (Exception e) {
wj.sc(wj.gd + "mp3_like.json");
}
} }
return contains; Gson gson = new GsonBuilder().registerTypeAdapter(MediaItem.class, new MediaItemAdapter())
.create();
List<MediaItem> o = gson.fromJson(dqwb, MediaItemAdapter.type);
boolean add = o.add(xm);
wj.xrwb(wj.gd + "mp3_like.json", gson.toJson(o));
return add;
}
public static boolean DelLike(MediaItem xm) {
String dqwb = wj.dqwb(wj.gd + "mp3_like.json");
if (dqwb == null) {
dqwb = "[]";
}
Gson gson = new GsonBuilder().registerTypeAdapter(MediaItem.class, new MediaItemAdapter())
.create();
List<MediaItem> o = gson.fromJson(dqwb, MediaItemAdapter.type);
boolean b = o.removeIf(mediaItem -> mediaItem.mediaId.equals(xm.mediaId));
wj.xrwb(wj.gd + "mp3_like.json", gson.toJson(o));
return b;
} }
} }

View File

@ -24,6 +24,7 @@ import com.muqingbfq.mq.wj;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
public class fragment_clean extends FragmentActivity<ActivityCleanBinding> { public class fragment_clean extends FragmentActivity<ActivityCleanBinding> {
List<String[]> list = new ArrayList<>(); List<String[]> list = new ArrayList<>();
@ -32,7 +33,6 @@ public class fragment_clean extends FragmentActivity<ActivityCleanBinding> {
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(); setContentView();
// setToolbar();
UI(); UI();
} }
@ -42,7 +42,7 @@ public class fragment_clean extends FragmentActivity<ActivityCleanBinding> {
list.add(new String[]{"下载的歌单",wj.gd}); list.add(new String[]{"下载的歌单",wj.gd});
list.add(new String[]{"缓存的音乐",wj.filesdri+"hc"}); list.add(new String[]{"缓存的音乐",wj.filesdri+"hc"});
list.add(new String[]{"内部缓存", getCacheDir().toString()}); list.add(new String[]{"内部缓存", getCacheDir().toString()});
String s = Glide.getPhotoCacheDir(this).toString(); String s = Objects.requireNonNull(Glide.getPhotoCacheDir(this)).toString();
list.add(new String[]{"Glide缓存", s}); list.add(new String[]{"Glide缓存", s});
binding.toolbar.setTitle("储存清理"); binding.toolbar.setTitle("储存清理");
binding.recyclerview.setAdapter(adapter); binding.recyclerview.setAdapter(adapter);

View File

@ -53,18 +53,6 @@ public class bflb_db extends BottomSheetDialog {
binding.lb.setAdapter(new spq(list)); binding.lb.setAdapter(new spq(list));
} }
@Override
public void onStart() {
super.onStart();
// 获取底部弹窗的根视图
View view = findViewById(com.google.android.material.R.id.design_bottom_sheet);
if (view != null) {
// 设置宽度
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = (int) (getContext().getResources().getDisplayMetrics().widthPixels * 0.6); // 占屏幕宽度的 60%
view.setLayoutParams(layoutParams);
}
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {

View File

@ -73,9 +73,7 @@ public class bfq_db extends Fragment<FragmentBfqDbBinding> implements GestureDet
} }
private void setUI(Player player) { private void setUI(Player player) {
binding.kg.setImageResource(player.isPlaying() ? R.drawable.bf : R.drawable.zt); binding.kg.setImageResource(player.isPlaying() ? R.drawable.bf : R.drawable.zt);
MediaItem currentMediaItem = player.getCurrentMediaItem(); MediaItem currentMediaItem = player.getCurrentMediaItem();
if (currentMediaItem != null) { if (currentMediaItem != null) {
MediaMetadata metadata = currentMediaItem.mediaMetadata; MediaMetadata metadata = currentMediaItem.mediaMetadata;
@ -170,7 +168,10 @@ public class bfq_db extends Fragment<FragmentBfqDbBinding> implements GestureDet
@Override @Override
public boolean onFling(@Nullable MotionEvent e1, public boolean onFling(@Nullable MotionEvent e1,
@NonNull MotionEvent e2, float v, float v1) { @NonNull MotionEvent e2, float v, float v1) {
float distance = e1.getX() - e2.getX(); float distance = 0;
if (e1 != null) {
distance = e1.getX() - e2.getX();
}
float threshold = getResources().getDisplayMetrics().widthPixels / 2.0f; float threshold = getResources().getDisplayMetrics().widthPixels / 2.0f;
if (PlaybackService.mediaSession == null) { if (PlaybackService.mediaSession == null) {

View File

@ -89,12 +89,9 @@ public class gd extends FragmentActivity<ActivityGdBinding> {
}); });
String id = intent.getStringExtra("id"); String id = intent.getStringExtra("id");
binding.fragmentDb.post(new Runnable() { binding.fragmentDb.post(() -> {
@Override int height = binding.fragmentDb.getHeight();
public void run() { binding.lb.setPadding(0,0,0,height);
int height = binding.fragmentDb.getHeight();
binding.lb.setPadding(0,0,0,height);
}
}); });
new start(id); new start(id);
} }

View File

@ -58,11 +58,12 @@ import com.muqingbfq.mq.gj;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects;
import jp.wasabeef.glide.transformations.BlurTransformation; import jp.wasabeef.glide.transformations.BlurTransformation;
public class mp3 extends FragmentActivity<ActivityMp3Binding> { public class mp3 extends FragmentActivity<ActivityMp3Binding> {
private List<MP3> list = new ArrayList<>(); private final List<MP3> list = new ArrayList<>();
private List<MP3> list_ys = new ArrayList<>(); private List<MP3> list_ys = new ArrayList<>();
public Adapter adapter; public Adapter adapter;
@ -98,7 +99,7 @@ public class mp3 extends FragmentActivity<ActivityMp3Binding> {
ImageView imageView = findViewById(R.id.toolbarimage); ImageView imageView = findViewById(R.id.toolbarimage);
Glide.with(this) Glide.with(this)
.load(drawable) .load(drawable)
.apply(RequestOptions.bitmapTransform(new BlurTransformation(26,3))) .apply(RequestOptions.bitmapTransform(new BlurTransformation(26, 3)))
.addListener(new RequestListener<Drawable>() { .addListener(new RequestListener<Drawable>() {
@Override @Override
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) { public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
@ -111,7 +112,7 @@ public class mp3 extends FragmentActivity<ActivityMp3Binding> {
// 使用 Glide 加载图片并应用高斯模糊效果 // 使用 Glide 加载图片并应用高斯模糊效果
// 1. 创建渐变遮罩层从底部白色渐变到顶部透明 // 1. 创建渐变遮罩层从底部白色渐变到顶部透明
GradientDrawable gradient = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, GradientDrawable gradient = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP,
new int[] {typedValue.data, Color.TRANSPARENT}); new int[]{typedValue.data, Color.TRANSPARENT});
gradient.setShape(GradientDrawable.RECTANGLE); gradient.setShape(GradientDrawable.RECTANGLE);
// 3. 使用 LayerDrawable 来组合模糊图像和渐变效果 // 3. 使用 LayerDrawable 来组合模糊图像和渐变效果
@ -204,7 +205,7 @@ public class mp3 extends FragmentActivity<ActivityMp3Binding> {
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
while (true){ while (true) {
try { try {
Thread.sleep(500); Thread.sleep(500);
//检测音乐是否播放 //检测音乐是否播放
@ -282,13 +283,16 @@ public class mp3 extends FragmentActivity<ActivityMp3Binding> {
case "cd.json": case "cd.json":
playlist.hq_cd(mp3.this, list); playlist.hq_cd(mp3.this, list);
break; break;
case "mp3_listHistory.json":
playlist.hq_listHistory(list);
break;
default: default:
playlist.hq(list, id); playlist.hq(list, id);
break; break;
} }
list_ys = list; list_ys = list;
main.handler.post(() -> { main.handler.post(() -> {
binding.lb.getAdapter().notifyDataSetChanged(); Objects.requireNonNull(binding.lb.getAdapter()).notifyDataSetChanged();
binding.recyclerview1Bar.setVisibility(View.GONE); binding.recyclerview1Bar.setVisibility(View.GONE);
if (list.isEmpty()) { if (list.isEmpty()) {
binding.recyclerview1Text.setVisibility(View.VISIBLE); binding.recyclerview1Text.setVisibility(View.VISIBLE);
@ -300,9 +304,9 @@ public class mp3 extends FragmentActivity<ActivityMp3Binding> {
} }
} }
public class Adapter extends AdapterMp3 implements Filterable { public static class Adapter extends AdapterMp3 implements Filterable {
private List<MP3> list_ys; private final List<MP3> list_ys;
public Adapter(List<MP3> list) { public Adapter(List<MP3> list) {
this.list = list; this.list = list;

View File

@ -45,7 +45,7 @@ public class wode extends Fragment<FragmentWdBinding> {
public TextView name, jieshao; public TextView name, jieshao;
public ImageView imageView; public ImageView imageView;
private final Object[][] lista = { private final Object[][] lista = {
{R.drawable.mdimusicbox, "最近播放", "mp3_hc.json"}, {R.drawable.mdimusicbox, "最近播放", "mp3_listHistory.json"},
{R.drawable.download, "下载音乐", "mp3_xz.json"}, {R.drawable.download, "下载音乐", "mp3_xz.json"},
{R.drawable.mdialbum, "喜欢音乐", "mp3_like.json"}, {R.drawable.mdialbum, "喜欢音乐", "mp3_like.json"},
{R.drawable.filesearc, "本地搜索", "cd.json"}, {R.drawable.filesearc, "本地搜索", "cd.json"},
@ -88,7 +88,7 @@ public class wode extends Fragment<FragmentWdBinding> {
holder.itemView.setOnClickListener(view -> { holder.itemView.setOnClickListener(view -> {
switch (data) { switch (data) {
case "cd.json": case "cd.json":
case "mp3_hc.json": case "mp3_listHistory.json":
case "mp3_xz.json": case "mp3_xz.json":
case "mp3_like.json": case "mp3_like.json":
Intent a = new Intent(getContext(), com.muqingbfq.fragment.mp3.class); Intent a = new Intent(getContext(), com.muqingbfq.fragment.mp3.class);

View File

@ -116,7 +116,7 @@ public class FloatingLyricsService extends Service {
} else { } else {
setup = new SETUP(); setup = new SETUP();
} }
if (setup.i == 0) { if (setup != null && setup.i == 0) {
//在Service中关闭自己 //在Service中关闭自己
stopSelf(); stopSelf();
return; return;

View File

@ -13,6 +13,8 @@ import androidx.viewbinding.ViewBinding;
import com.muqingbfq.R; import com.muqingbfq.R;
import java.util.Objects;
public abstract class FragmentActivity<ViewBindingType extends ViewBinding> public abstract class FragmentActivity<ViewBindingType extends ViewBinding>
extends AppCompatActivity<ViewBindingType> { extends AppCompatActivity<ViewBindingType> {
@Override @Override
@ -27,7 +29,7 @@ public abstract class FragmentActivity<ViewBindingType extends ViewBinding>
View viewById = findViewById(R.id.toolbar); View viewById = findViewById(R.id.toolbar);
if (viewById != null) { if (viewById != null) {
setSupportActionBar((Toolbar) viewById); setSupportActionBar((Toolbar) viewById);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
} }
} }

View File

@ -0,0 +1,49 @@
package com.muqingbfq.mq;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MediaMetadata;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
public class MediaItemAdapter implements JsonSerializer<MediaItem>, JsonDeserializer<MediaItem> {
public static final Type type = new TypeToken<List<MediaItem>>() {
}.getType();
@Override
public JsonElement serialize(MediaItem src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("id", src.mediaId);
jsonObject.addProperty("artist", src.mediaMetadata.artist != null ? src.mediaMetadata.artist.toString() : "");
jsonObject.addProperty("title", src.mediaMetadata.title != null ? src.mediaMetadata.title.toString() : "");
jsonObject.addProperty("artworkUri", src.mediaMetadata.artworkUri != null ? src.mediaMetadata.artworkUri.toString() : "");
// jsonObject.addProperty("like",);
return jsonObject;
}
@Override
public MediaItem deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
String id = jsonObject.has("id") ? jsonObject.get("id").getAsString() : "";
String artist = jsonObject.has("artist") ? jsonObject.get("artist").getAsString() : "";
String title = jsonObject.has("title") ? jsonObject.get("title").getAsString() : "";
String artworkUri = jsonObject.has("artworkUri") ? jsonObject.get("artworkUri").getAsString() : "";
String uri = "";
MediaMetadata metadata = new MediaMetadata.Builder()
.setArtist(artist)
.setTitle(title)
.setArtworkUri(artworkUri.isEmpty() ? null : android.net.Uri.parse(artworkUri))
.build();
return new MediaItem.Builder()
.setMediaId(id)
.setUri(uri)
.setMediaMetadata(metadata)
.build();
}
}

View File

@ -1,9 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="24" xmlns:tools="http://schemas.android.com/tools"
android:viewportHeight="24" android:width="24dp"
android:width="26dp" android:height="24dp"
android:height="26dp"> android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path <path
android:pathData="M12 21.35l-1.45 -1.32C5.4 15.36 2 12.27 2 8.5C2 5.41 4.42 3 7.5 3c1.74 0 3.41 0.81 4.5 2.08C13.09 3.81 14.76 3 16.5 3C19.58 3 22 5.41 22 8.5c0 3.77 -3.4 6.86 -8.55 11.53z" android:fillColor="@android:color/white"
android:fillColor="#000000" /> android:pathData="M480,813Q466,813 451.5,808Q437,803 426,792L357,729Q251,632 165.5,536.5Q80,441 80,326Q80,232 143,169Q206,106 300,106Q353,106 400,128.5Q447,151 480,190Q513,151 560,128.5Q607,106 660,106Q754,106 817,169Q880,232 880,326Q880,441 795,537Q710,633 602,730L534,792Q523,803 508.5,808Q494,813 480,813ZM442,270Q413,229 380,207.5Q347,186 300,186Q240,186 200,226Q160,266 160,326Q160,378 197,436.5Q234,495 285.5,550Q337,605 391.5,653Q446,701 480,732Q480,732 480,732Q480,732 480,732Q514,701 568.5,653Q623,605 674.5,550Q726,495 763,436.5Q800,378 800,326Q800,266 760,226Q720,186 660,186Q613,186 580,207.5Q547,229 518,270Q511,280 501,285Q491,290 480,290Q469,290 459,285Q449,280 442,270ZM480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Q480,459 480,459Z"
tools:ignore="VectorPath" />
</vector> </vector>

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M718,534L831,421Q843,409 859,409Q875,409 887,421Q899,433 899,449.5Q899,466 887,478L746,619Q734,631 717.5,631Q701,631 689,619L633,562Q621,550 621,534Q621,518 633,506Q645,494 661,494.5Q677,495 689,506L718,534ZM440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459L440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459Q440,459 440,459ZM313,726Q241,661 189.5,610Q138,559 104.5,514Q71,469 55.5,427Q40,385 40,339Q40,245 103,182.5Q166,120 260,120Q312,120 359,142Q406,164 440,204Q474,164 521,142Q568,120 620,120Q701,120 756,165.5Q811,211 831,280Q831,280 817.5,280Q804,280 788.5,280Q773,280 759.5,280Q746,280 746,280Q728,240 693,220Q658,200 620,200Q569,200 532,227.5Q495,255 463,300L417,300Q386,255 346.5,227.5Q307,200 260,200Q203,200 161.5,239.5Q120,279 120,339Q120,372 134,406Q148,440 184,484.5Q220,529 282,588.5Q344,648 440,732Q466,709 501,679Q536,649 557,629Q557,629 566,638Q575,647 585.5,657.5Q596,668 605,677Q614,686 614,686Q592,706 558,735.5Q524,765 498,788L467,816Q456,827 440,827Q424,827 413,816L313,726Z"
tools:ignore="VectorPath" />
</vector>

View File

@ -1,20 +1,27 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"> tools:context=".clean.fragment_clean">
<androidx.appcompat.widget.Toolbar <com.google.android.material.appbar.AppBarLayout
android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
app:title="储存清理"/>
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:title="储存清理" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview" android:id="@+id/recyclerview"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/> app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
</LinearLayout> app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -22,15 +22,16 @@
style="@style/TextAppearance.Material3.BodyMedium" style="@style/TextAppearance.Material3.BodyMedium"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:textStyle="bold" android:textStyle="bold"
android:text="@string/app_name" /> android:text="暂无歌词"
tools:ignore="HardcodedText" />
<com.muqingbfq.view.StrokeTextView <com.muqingbfq.view.StrokeTextView
android:id="@+id/lrcViewMessage" android:id="@+id/lrcViewMessage"
style="@style/TextAppearance.Material3.BodySmall" style="@style/TextAppearance.Material3.BodySmall"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_horizontal" tools:text="暂无歌词"
android:text="@string/app_name" /> android:gravity="center_horizontal"/>
<ImageView <ImageView
android:id="@+id/lock" android:id="@+id/lock"