修复了歌词BUG,优化了播放器随机播放模式

This commit is contained in:
muqing 2024-01-02 14:19:36 +08:00
parent fad23cb3f7
commit 565ff0b700
23 changed files with 545 additions and 170 deletions

View File

@ -59,4 +59,6 @@ dependencies {
//
implementation 'com.mpatric:mp3agic:0.9.1'
implementation 'com.github.QuadFlask:colorpicker:0.0.15'
}

View File

@ -6,6 +6,7 @@ import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioAttributes;
import android.media.AudioManager;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -33,6 +34,7 @@ public class MediaPlayer extends android.media.MediaPlayer {
public void run() {
if (isPlaying() && bfq.lrcView != null) {
long position = getCurrentPosition();
// gj.sc(position);
Media.setProgress((int) position);
}
main.handler.postDelayed(this, 1000); // 每秒更新一次进度
@ -47,7 +49,7 @@ public class MediaPlayer extends android.media.MediaPlayer {
}
//针对错误进行相应的处理
bfqkz.list.remove(bfqkz.xm);
bfqkz.xm = bfqkz.list.get(bfqkz.getmti(bfqkz.ms));
bfqkz.xm = bfqkz.list.get(bfqkz.getmti());
new bfqkz.mp3(com.muqingbfq.api.
url.hq(bfqkz.xm));
return false;
@ -58,6 +60,7 @@ public class MediaPlayer extends android.media.MediaPlayer {
}
bfq_an.xyq();
});
// setAudioStreamType(AudioManager.STREAM_MUSIC);
setAudioAttributes(new AudioAttributes
.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)

View File

@ -8,9 +8,17 @@ import android.net.Uri;
import android.provider.Settings;
import android.view.KeyEvent;
import androidx.core.content.ContextCompat;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.muqingbfq.mq.FloatingLyricsService;
import com.muqingbfq.mq.gj;
import com.muqingbfq.mq.wj;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
@ -100,6 +108,28 @@ public class MyButtonClickReceiver extends BroadcastReceiver {
}
break;
case "like":
try {
Gson gson = new Gson();
Type type = new TypeToken<List<MP3>>() {
}.getType();
List<MP3> list = gson.fromJson(wj.dqwb(wj.gd + "mp3_like.json"), type);
if (list == null) {
list = new ArrayList<>();
}
if (bfqkz.like_bool) {
list.remove(bfqkz.xm);
bfq.setlike(false);
} else {
if (!list.contains(bfqkz.xm)) {
list.add(bfqkz.xm);
bfq.setlike(true);
}
}
bfqkz.like_bool = !bfqkz.like_bool;
wj.xrwb(wj.gd + "mp3_like.json", gson.toJson(list));
} catch (Exception e) {
e.printStackTrace();
}
break;
}
// 处理按钮点击事件的逻辑

View File

@ -1,26 +1,25 @@
package com.muqingbfq.api;
import android.Manifest;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.appcompat.app.AlertDialog;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.mpatric.mp3agic.ID3v2;
import com.mpatric.mp3agic.Mp3File;
import com.muqingbfq.MP3;
import com.muqingbfq.R;
import com.muqingbfq.bfq;
import com.muqingbfq.main;
import com.muqingbfq.mq.gj;
import com.muqingbfq.mq.wj;
import com.muqingbfq.mq.wl;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.File;
@ -35,16 +34,57 @@ import okhttp3.Request;
import okhttp3.Response;
public class FileDownloader {
private final String CHANNEL_ID = "download_channel";
private final int NOTIFICATION_ID = 3;
public void downloadFile(Context context, String url, MP3 x) {
OkHttpClient client = new OkHttpClient();
OkHttpClient client = new OkHttpClient();
AlertDialog dialog;
TextView textView;
Context context;
public FileDownloader(Context context) {
this.context = context;
main.handler.post(() -> {
textView = new TextView(context);
dialog = new MaterialAlertDialogBuilder(context)
.setTitle("下载中...")
.setView(textView)
.show();
});
}
public FileDownloader() {
}
public void downloadFile(MP3 x) {
Request request = new Request.Builder()
.url(main.api + url.api + "?id=" + x.id + "&level=" +
"standard" + "&cookie=" + wl.Cookie)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
e.printStackTrace();
// 下载失败处理
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
if (!response.isSuccessful()) {
// 下载失败处理
return;
}
try {
JSONObject json = new JSONObject(response.body().string());
JSONArray data = json.getJSONArray("data");
JSONObject jsonObject = data.getJSONObject(0);
String url = jsonObject.getString("url");
downloadFile(url, x);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
long fileSizeDownloaded = 0;
public void downloadFile(String url, MP3 x) {
Request request = new Request.Builder()
.url(url)
.build();
// 创建通知渠道仅适用于Android 8.0及以上版本
createNotificationChannel(context);
// 发起请求
client.newCall(request).enqueue(new Callback() {
@Override
@ -59,7 +99,7 @@ public class FileDownloader {
// 下载失败处理
return;
}
File outputFile = new File(wj.mp3, x.id);
File outputFile = new File(wj.mp3, x.id + ".mp3");
File parentFile = outputFile.getParentFile();
if (!parentFile.isDirectory()) {
parentFile.mkdirs();
@ -69,8 +109,6 @@ public class FileDownloader {
try {
byte[] buffer = new byte[4096];
long fileSize = response.body().contentLength();
long fileSizeDownloaded = 0;
inputStream = response.body().byteStream();
outputStream = new FileOutputStream(outputFile);
@ -79,13 +117,19 @@ public class FileDownloader {
outputStream.write(buffer, 0, read);
fileSizeDownloaded += read;
// 更新通知栏进度
updateNotificationProgress(context, fileSize, fileSizeDownloaded);
// updateNotificationProgress(context, fileSize, fileSizeDownloaded);
if (textView != null) {
main.handler.post(() ->
textView.setText(x.name + ":" +
(int) ((fileSizeDownloaded * 100) / fileSize)));
}
}
try {
Mp3File mp3file = new Mp3File(outputFile);
if (mp3file.hasId3v2Tag()) {
ID3v2 id3v2Tag = mp3file.getId3v2Tag();
// 设置新的ID值
gj.sc(x.name);
id3v2Tag.setTitle(x.name);
id3v2Tag.setArtist(x.zz);
id3v2Tag.setAlbum(x.zz);
@ -101,7 +145,9 @@ public class FileDownloader {
// 保存修改后的音乐文件删除原来的文件
} catch (Exception e) {
gj.sc(e);
outputFile.delete();
}
dismiss();
// 下载完成处理
} catch (IOException e) {
e.printStackTrace();
@ -113,45 +159,17 @@ public class FileDownloader {
if (outputStream != null) {
outputStream.close();
}
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.cancel(NOTIFICATION_ID);
dismiss();
}
}
});
}
private void createNotificationChannel(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Download Channel";
String description = "Channel for file download";
int importance = NotificationManager.IMPORTANCE_LOW;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
channel.setShowBadge(false);
channel.enableLights(true);
channel.setLightColor(Color.BLUE);
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
private void updateNotificationProgress(Context context, long fileSize,
long fileSizeDownloaded) {
int progress = (int) ((fileSizeDownloaded * 100) / fileSize);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.icon)
.setContentTitle("Downloading File")
.setContentText(progress + "% downloaded")
.setProgress(100, progress, false)
.setOngoing(true)
.setOnlyAlertOnce(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
public void dismiss() {
if (dialog == null) {
return;
}
notificationManager.notify(NOTIFICATION_ID, builder.build());
main.handler.post(() -> dialog.dismiss());
}
}

View File

@ -48,25 +48,24 @@ public class bfq extends AppCompatActivity {
public static com.muqingbfq.view.LrcView lrcView;
private void setLrc(){
lrcView = binding.lrcView;
ViewGroup.LayoutParams layoutParams = binding.cardview.getLayoutParams();
layoutParams.height = main.k - 100;
layoutParams.width = main.k - 100;
binding.cardview.setLayoutParams(layoutParams);/*
bfqkz.mt.seekTo(Math.toIntExact(time));
binding.cardview.setLayoutParams(layoutParams);
// bfqkz.mt.seekTo(Math.toIntExact(time));
if (!gj.isTablet(this)) {
lrcview.setOnTapListener((view, x, y) -> {
lrcView.setOnClickListener((view) -> {
View kp = binding.kp1;
if (kp.getVisibility() == View.VISIBLE) {
kp.setVisibility(View.GONE);
} else {
kp.setVisibility(View.VISIBLE);
}
lrcView.setLrcline(kp.getVisibility() == View.VISIBLE);
});
} else {
lrcview.setOnTapListener((view, x, y) -> {
});
}*/
lrcView.setOnClickListener(null);
}
}
@SuppressLint("ClickableViewAccessibility")
@Override
@ -116,13 +115,11 @@ public class bfq extends AppCompatActivity {
}
if (bfqkz.like_bool) {
list.remove(bfqkz.xm);
binding.like
.setImageTintList(ContextCompat.getColorStateList(bfq.this, R.color.text));
setlike(false);
} else {
if (!list.contains(bfqkz.xm)) {
list.add(bfqkz.xm);
binding.like.setImageTintList(ContextCompat.
getColorStateList(bfq.this, android.R.color.holo_red_dark));
setlike(true);
}
}
bfqkz.like_bool = !bfqkz.like_bool;
@ -151,7 +148,7 @@ public class bfq extends AppCompatActivity {
JSONArray data = json.getJSONArray("data");
JSONObject jsonObject = data.getJSONObject(0);
String url = jsonObject.getString("url");
new FileDownloader().downloadFile(bfq.this, url, bfqkz.xm);
new FileDownloader(bfq.this).downloadFile(url, bfqkz.xm);
} catch (JSONException e) {
throw new RuntimeException(e);
}

View File

@ -49,11 +49,7 @@ public class bfq_an {
return;
}
bfqkz.mt.pause();
int ms = bfqkz.ms;
if (bfqkz.ms == 0) {
ms = 1;
}
bfqkz.xm = bfqkz.list.get(bfqkz.getmti(ms));
bfqkz.xm = bfqkz.list.get(bfqkz.getmti());
new url(bfqkz.xm);
}

View File

@ -41,7 +41,7 @@ public class bfqkz extends MediaBrowserServiceCompat {
@SuppressLint("StaticFieldLeak")
public static com.muqingbfq.mq.NotificationManagerCompat notify;
public static int getmti(int s) {
public static int getmti() {
int i = bfqkz.list.indexOf(xm) + 1;
if (i >= bfqkz.list.size()) {
i = 0;

View File

@ -1,7 +1,8 @@
package com.muqingbfq.fragment;
import android.widget.SeekBar;
import androidx.annotation.NonNull;
import com.google.android.material.slider.Slider;
import com.muqingbfq.R;
import com.muqingbfq.bfq;
import com.muqingbfq.bfq_an;
@ -32,14 +33,15 @@ public class Media {
if (bfq.view == null) {
return;
}
bfq.binding.tdt.setMax(max);
bfq.binding.tdt.setValueTo(max);
}
public static void setProgress(int progress) {
if (bfq.view == null) {
return;
}
bfq.binding.tdt.setProgress(progress);
// gj.sc(progress);
bfq.binding.tdt.setValue(progress);
// bfq.lrcview.updateTime(progress);
bfq.lrcView.setTimeLrc(progress);
}
@ -60,6 +62,28 @@ public class Media {
}
public Media(ActivityBfqBinding binding) {
binding.tdt.addOnChangeListener(new Slider.OnChangeListener() {
@Override
public void onValueChange(@NonNull Slider slider, float value, boolean fromUser) {
setTime_b(bfq_an.getTime((long) value));
}
});
binding.tdt.addOnSliderTouchListener(new Slider.OnSliderTouchListener() {
@Override
public void onStartTrackingTouch(@NonNull Slider slider) {
// 拖动条移动中
main.handler.removeCallbacks(bfqkz.mt.updateSeekBar);
}
@Override
public void onStopTrackingTouch(@NonNull Slider slider) {
// 播放音乐到指定位置
main.handler.post(bfqkz.mt.updateSeekBar);
bfqkz.mt.seekTo((int) slider.getValue());
}
});
/*
binding.tdt.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
@ -78,11 +102,11 @@ public class Media {
main.handler.post(bfqkz.mt.updateSeekBar);
bfqkz.mt.seekTo(seekBar.getProgress());
}
});
});*/
//初始化播放器列表
if (bfqkz.xm != null) {
long duration = bfqkz.mt.getDuration();
binding.tdt.setMax(bfqkz.mt.getDuration());
binding.tdt.setValueTo(bfqkz.mt.getDuration());
setTime_a(bfq_an.getTime(duration));
long position = bfqkz.mt.getCurrentPosition();
main.handler.post(bfqkz.mt.updateSeekBar); // 在播放开始时启动更新进度

View File

@ -6,6 +6,8 @@ import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
@ -19,6 +21,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.muqingbfq.R;
import com.muqingbfq.activity_about_software;
import com.muqingbfq.api.playlist;
import com.muqingbfq.api.resource;
import com.muqingbfq.bfq_an;
@ -44,16 +47,14 @@ public class gd extends com.muqingbfq.mq.FragmentActivity {
public static String gdid;
private final List<XM> list = new ArrayList<>();
public static RecyclerView.Adapter<VH> adapter;
int k;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentMp3Binding binding = FragmentMp3Binding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
Intent intent = getIntent();
binding.title.setText(intent.getStringExtra("name"));
// inflate.toolbar.setTitle(intent.getStringExtra("name"));
setContentView(binding.getRoot());
adapter = new baseadapter(this,list);
k = (int) (main.k / getResources().getDisplayMetrics().density + 0.5f);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, k / 120);
@ -196,7 +197,6 @@ public class gd extends com.muqingbfq.mq.FragmentActivity {
@Override
public boolean onLongClick(View view) {
String[] stringArray = view.getResources()
.getStringArray(R.array.gd_list);
new MaterialAlertDialogBuilder(view.getContext()).setItems(stringArray, (dialog, id) -> {

View File

@ -5,6 +5,8 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@ -16,6 +18,8 @@ import androidx.recyclerview.widget.RecyclerView;
import com.muqingbfq.MP3;
import com.muqingbfq.R;
import com.muqingbfq.XM;
import com.muqingbfq.api.FileDownloader;
import com.muqingbfq.api.playlist;
import com.muqingbfq.api.url;
import com.muqingbfq.bfq;
@ -24,6 +28,7 @@ import com.muqingbfq.databinding.FragmentMp3Binding;
import com.muqingbfq.list.MyViewHoder;
import com.muqingbfq.main;
import com.muqingbfq.mq.FragmentActivity;
import com.muqingbfq.mq.gj;
import java.util.ArrayList;
import java.util.List;
@ -51,6 +56,35 @@ public class mp3 extends FragmentActivity {
new start(id);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuItem itemA = menu.add("下载所有歌曲");
itemA.setTitle("下载所有歌曲");
itemA.setIcon(R.drawable.download);
itemA.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
gj.sc(itemA.getItemId());
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == 0) {
FileDownloader fileDownloader = new FileDownloader(
mp3.
this);
for (MP3 mp3 : list) {
new Thread(){
@Override
public void run() {
super.run();
fileDownloader.downloadFile(mp3);
}
}.start();
}
}
return super.onOptionsItemSelected(item);
}
@SuppressLint("NotifyDataSetChanged")
class start extends Thread {
String id;

View File

@ -2,6 +2,7 @@ package com.muqingbfq.fragment;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@ -11,6 +12,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -89,6 +91,7 @@ public class wode extends Fragment {
public void onBindViewHolder(@NonNull VH holder, int position) {
String s = lista[position][1].toString();
holder.textView.setText(s);
holder.imageView.setImageTintList(ColorStateList.valueOf(ContextCompat.getColor(getContext(),R.color.text)));
Glide.with(getContext())
.load(lista[position][0])
.into(holder.imageView);

View File

@ -64,7 +64,7 @@ public class FloatingLyricsService extends Service implements View.OnClickListen
public static class SETUP {
//0是关闭 1是打开 2是锁定
public int i = 1;
public int i = 1, size = 20;
public float Alpha = 0.9f;
public String Color = "#0088FF";
public int Y = -main.g;
@ -114,6 +114,9 @@ public class FloatingLyricsService extends Service implements View.OnClickListen
lrcView = binding.lrcView;
lrcView.setTextColor(setup.Color);
lrcView.setSize(setup.size);
lrcView.setAlpha(setup.Alpha);
bfq_an.kz bfqAn = new bfq_an.kz();
binding.kg.setOnClickListener(this);
binding.syq.setOnClickListener(bfqAn);
@ -127,7 +130,7 @@ public class FloatingLyricsService extends Service implements View.OnClickListen
if (setup.i == 2) {
params.flags = lock();
layout.setBackground(null);
lrcView.setAlpha(0.5f);
lrcView.setAlpha(setup.Alpha);
layout.findViewById(com.muqingbfq.R.id.controlLayout).setVisibility(View.GONE);
}
windowManager.addView(layout, params);
@ -164,6 +167,10 @@ public class FloatingLyricsService extends Service implements View.OnClickListen
wj.xrwb(new File(wj.filesdri + "FloatingLyricsService.json").toString(),
new Gson().toJson(setup));
}
public static void baocun(SETUP setup) {
wj.xrwb(new File(wj.filesdri + "FloatingLyricsService.json").toString(),
new Gson().toJson(setup));
}
private int initialY;
private float initialTouchY;

View File

@ -18,8 +18,6 @@ import com.muqingbfq.MyButtonClickReceiver;
import com.muqingbfq.R;
import com.muqingbfq.bfq;
import com.muqingbfq.bfqkz;
import com.muqingbfq.fragment.Media;
import com.muqingbfq.home;
import com.muqingbfq.yc;
public class NotificationManagerCompat {
@ -55,6 +53,8 @@ public class NotificationManagerCompat {
setAction("xyq"));
pendingIntent_lrc = getBroadcast(context, my.
setAction("lrc"));
pendingIntent_like = getBroadcast(context, my.
setAction("like"));
style = new androidx.media.app.NotificationCompat.MediaStyle()
.setShowActionsInCompactView(1, 2, 3)
.setMediaSession(context.mSession.getSessionToken());
@ -81,7 +81,7 @@ public class NotificationManagerCompat {
}
notificationBuilder.mActions.clear();
notificationBuilder
.addAction(R.drawable.like, "like", pendingIntent_kg) // #0
.addAction(R.drawable.like, "like", pendingIntent_like) // #0
.addAction(R.drawable.syq, "syq", pendingIntent_syq) // #0
.addAction(bfqkz.mt.isPlaying() ? R.drawable.bf : R.drawable.zt
, "kg", pendingIntent_kg) // #1
@ -103,7 +103,7 @@ public class NotificationManagerCompat {
notificationBuilder.mActions.clear();
notificationBuilder
.setLargeIcon(bfq.bitmap)
.addAction(R.drawable.like, "like", pendingIntent_kg) // #0
.addAction(R.drawable.like, "like", pendingIntent_like) // #0
.addAction(R.drawable.syq, "syq", pendingIntent_syq) // #0
.addAction(bfqkz.mt.isPlaying() ? R.drawable.bf : R.drawable.zt
, "kg", pendingIntent_kg) // #1
@ -126,7 +126,9 @@ public class NotificationManagerCompat {
private PendingIntent pendingIntent_kg,
pendingIntent_syq,
pendingIntent_xyq,
pendingIntent_lrc;
pendingIntent_lrc,
pendingIntent_like;
private final String CHANNEL_ID = "MediaSessionCompat";
public void notificationManager_notify() {

View File

@ -3,19 +3,41 @@ package com.muqingbfq;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import com.flask.colorpicker.ColorPickerView;
import com.flask.colorpicker.builder.ColorPickerDialogBuilder;
import com.google.android.material.materialswitch.MaterialSwitch;
import com.google.android.material.slider.Slider;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.muqingbfq.databinding.ActivitySzSetlrcBinding;
import com.muqingbfq.mq.FloatingLyricsService;
import com.muqingbfq.mq.gj;
import com.muqingbfq.mq.wj;
import com.muqingbfq.view.LrcView;
import java.io.File;
import java.lang.reflect.Type;
import java.util.Locale;
public class sz extends AppCompatActivity {
@Override
@ -25,6 +47,7 @@ public class sz extends AppCompatActivity {
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setTitle(getString(R.string.sz));
UI();
kaifazhe();
}
@ -70,7 +93,6 @@ public class sz extends AppCompatActivity {
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
@ -86,6 +108,7 @@ public class sz extends AppCompatActivity {
com.muqingbfq.mq.floating.start(sz.this);
}
});
public void kaifazhe() {
MaterialSwitch materialSwitch = findViewById(R.id.switch_kfz);
materialSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
@ -102,4 +125,142 @@ public class sz extends AppCompatActivity {
}
});
}
public static class setlrc extends Fragment implements Slider.OnSliderTouchListener,
Slider.OnChangeListener {
FloatingLyricsService.SETUP setup;
ActivitySzSetlrcBinding binding;
public Runnable updateSeekBar = new Runnable() {
@Override
public void run() {
if (bfqkz.mt.isPlaying()) {
int index = 0;
for (int i = 0; i < LrcView.lrclist.size(); i++) {
LrcView.LRC lineLrc = LrcView.lrclist.get(i);
if (lineLrc.time <= bfqkz.mt.getCurrentPosition()) {
index = i;
} else {
break;
}
}
if (index < LrcView.lrclist.size()) {
String text;
if (LrcView.lrclist.size() <= 3) {
for (LrcView.LRC a : LrcView.lrclist) {
if (a.time == 5940000 && a.lrc.equals("纯音乐,请欣赏")) {
text = "纯音乐,请欣赏";
binding.lrctext.setText(text);
return;
}
}
}
LrcView.LRC currentLrc = LrcView.lrclist.get(index);
text = currentLrc.lrc;
if (currentLrc.tlyric != null) {
text += "\n" + currentLrc.tlyric;
}
binding.lrctext.setText(text);
}
}
gj.sc(getClass()+"执行");
main.handler.postDelayed(this, 1000); // 每秒更新一次进度
}
};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = ActivitySzSetlrcBinding.inflate(inflater, container, false);
File file = new File(wj.filesdri + "FloatingLyricsService.json");
if (file.exists() && file.isFile()) {
String dqwb = wj.dqwb(file.toString());
Gson gson = new Gson();
Type type = new TypeToken<FloatingLyricsService.SETUP>() {
}.getType();
setup = gson.fromJson(dqwb, type);
binding.slide1.setValue(setup.size);
binding.slide2.setValue(setup.Alpha);
binding.lrctext.setAlpha(setup.Alpha);
binding.lrctext.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,
setup.size,
getResources().getDisplayMetrics()));
binding.lrctext.setTextColor(Color.parseColor(setup.Color));
binding.lrctext.setOnClickListener(view -> ColorPickerDialogBuilder
.with(view.getContext())
.setTitle("调色盘")
.initialColor(Color.parseColor(setup.Color))
.wheelType(ColorPickerView.WHEEL_TYPE.FLOWER)
.density(12)
.setOnColorSelectedListener(selectedColor -> {
})
.setPositiveButton("确定", (dialog, selectedColor, allColors) -> {
setup.Color = String.format("#%08X", selectedColor);
binding.lrctext.setTextColor(selectedColor);
FloatingLyricsService.baocun(setup);
})
.setNegativeButton("取消",null)
.build()
.show());
binding.textSlide1.setText(String.valueOf(setup.size));
binding.textSlide2.setText(String.format(Locale.US,"%.2f",setup.Alpha));
main.handler.post(updateSeekBar);
}
if (setup.i != 0) {
binding.switchA1.setChecked(true);
}
binding.switchA1.setOnCheckedChangeListener((compoundButton, b) -> {
if (b) {
setup.i = 1;
} else {
setup.i = 0;
home.appCompatActivity
.stopService(new Intent(home.appCompatActivity,
FloatingLyricsService.class));
}
FloatingLyricsService.baocun(setup);
});
binding.slide1.setLabelFormatter(value -> String.valueOf((int) value));
binding.slide1.addOnChangeListener(this);
binding.slide1.addOnChangeListener(this);
binding.slide1.addOnSliderTouchListener(this);
binding.slide2.addOnChangeListener(this);
binding.slide2.addOnSliderTouchListener(this);
return binding.getRoot();
}
@Override
public void onDestroy() {
super.onDestroy();
main.handler.removeCallbacks(updateSeekBar);
}
@Override
public void onStartTrackingTouch(@NonNull Slider slider) {
}
@Override
public void onStopTrackingTouch(@NonNull Slider slider) {
FloatingLyricsService.baocun(setup);
}
@Override
public void onValueChange(@NonNull Slider slider, float value, boolean fromUser) {
if (slider == binding.slide1) {
setup.size = (int) value;
binding.lrctext.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,
setup.size,
getResources().getDisplayMetrics()));
binding.textSlide1.setText(String.valueOf(setup.size));
}else if (slider == binding.slide2) {
setup.Alpha = value;
binding.lrctext.setAlpha(value);
binding.textSlide2.setText(String.format(Locale.US,"%.2f", value));
}
}
}
}

View File

@ -1,6 +1,7 @@
package com.muqingbfq.view;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
@ -31,11 +32,19 @@ import java.util.List;
public class LrcView extends RecyclerView {
static List<LRC> lrclist = new ArrayList<>();
public static List<LRC> lrclist = new ArrayList<>();
static class LRC {
String lrc, tlyric;
long time;
View.OnClickListener onClickListener;
@Override
public void setOnClickListener(@Nullable OnClickListener l) {
onClickListener = l;
super.setOnClickListener(l);
}
public static class LRC {
public String lrc, tlyric;
public long time;
public LRC(String lrc, long time) {
this.lrc = lrc;
@ -53,6 +62,7 @@ public class LrcView extends RecyclerView {
LRC lrc = (LRC) obj;
return time == lrc.time;
}
public LRC setTlyric(String str) {
this.tlyric = str;
return this;
@ -89,9 +99,11 @@ public class LrcView extends RecyclerView {
public void setTextColor(int textColor) {
TextColor = textColor;
}
public void setTextColor(String textColor) {
TextColor = Color.parseColor(textColor);
}
public void setLrcline(boolean lrcline) {
Lrcline = lrcline;
}
@ -124,6 +136,7 @@ public class LrcView extends RecyclerView {
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
view.setOnClickListener(onClickListener);
int parentHeight = parent.getHeight();
int childHeight = view.getHeight();
@ -136,6 +149,8 @@ public class LrcView extends RecyclerView {
}
}
});
} else {
setOnTouchListener(null);
}
}
@ -161,35 +176,6 @@ public class LrcView extends RecyclerView {
lrclist.clear();
setLrc(a);
setLrc(b);
if (true) {
return;
}
if (TextUtils.isEmpty(b)) {
return;
}
b.trim();
String[] lines = b.split("\n");
for (String line : lines) {
String[] parts = line.split("]");
if (parts.length >= 2) {
String timeString = parts[0].substring(1);
String lyric = parts[1].trim();
String[] timeParts = timeString.split(":");
if (timeParts.length >= 2) {
int minute = Integer.parseInt(timeParts[0]);
String[] secondParts = timeParts[1].split("[.\\-]");
if (secondParts.length >= 2) {
int second = Integer.parseInt(secondParts[0]);
int millisecond = Integer.parseInt(secondParts[1]);
long time = (long) minute * 60 * 1000 + second * 1000L + millisecond;
int currentLineIndex = getCurrentLineIndex(time);
lrclist.set(currentLineIndex,
lrclist.get(currentLineIndex).setTlyric(lyric));
}
}
}
}
} catch (Exception e) {
yc.start("LrcView setLrc :" + e + a + b);
}
@ -229,6 +215,19 @@ public class LrcView extends RecyclerView {
}
int index = -1;
int size = 20;
public void setSize(int size) {
this.size = size;
}
float alpha = 1.0f;
@Override
public void setAlpha(float alpha) {
this.alpha = alpha;
}
boolean addOnGlobalLayoutListener;
class adaper extends RecyclerView.Adapter<VH> {
@ -240,8 +239,11 @@ public class LrcView extends RecyclerView {
TextView textView = inflate.findViewById(R.id.text);
textView.setTextColor(TextColor);
textView.setTextSize(
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20,
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, size,
getResources().getDisplayMetrics()));
textView.setAlpha(alpha);
inflate.setOnClickListener(LrcView.this.onClickListener);
return new VH(inflate);
}
@ -268,7 +270,7 @@ public class LrcView extends RecyclerView {
return;
}
int currentLineIndex = getCurrentLineIndex();
if (currentLineIndex >= 0 && currentLineIndex < lrclist.size()) {
if (currentLineIndex < lrclist.size()) {
String text;
if (lrclist.size() <= 3) {
@ -340,7 +342,7 @@ public class LrcView extends RecyclerView {
}
private int getCurrentLineIndex() {
index = -1;
index = 0;
for (int i = 0; i < lrclist.size(); i++) {
LRC lineLrc = lrclist.get(i);
if (lineLrc.time <= time) {

View File

@ -1,8 +0,0 @@
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/text_tm">
<item android:id="@android:id/mask">
<shape android:shape="oval">
<solid android:color="@android:color/white" />
</shape>
</item>
</ripple>

View File

@ -87,14 +87,14 @@
android:layout_height="wrap_content"
android:text="@string/_00_00" />
<SeekBar
<com.google.android.material.slider.Slider
android:id="@+id/tdt"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:clickable="true"
android:focusable="true"
android:padding="6dp" />
app:labelBehavior="gone"
app:thumbColor="@color/text_tm"
app:trackColorActive="@color/text_tm"/>
<TextView
android:id="@+id/time_b"

View File

@ -177,21 +177,23 @@
android:id="@+id/time_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="@string/_00_00" />
<SeekBar
<com.google.android.material.slider.Slider
android:id="@+id/tdt"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:clickable="true"
android:focusable="true"
android:padding="6dp" />
app:labelBehavior="gone"
app:thumbColor="@color/text_tm"
app:trackColorActive="@color/text_tm"/>
<TextView
android:id="@+id/time_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="@string/_00_00" />
</LinearLayout>

View File

@ -16,6 +16,7 @@
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -46,13 +47,13 @@
android:layout_height="wrap_content"
android:layout_marginStart="26dp"
android:text="深色模式" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:id="@+id/materialDivider"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
@ -64,8 +65,18 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开发者模式" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_setlrc"
android:name="com.muqingbfq.sz$setlrc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout="@layout/activity_sz_setlrc" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>

View File

@ -0,0 +1,105 @@
<LinearLayout 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_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="歌词调节"
android:textSize="20sp" />
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp">
<TextView
android:id="@+id/lrctext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:gravity="center"
android:text="@string/app_name"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/layout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:gravity="center_vertical"
app:layout_constraintTop_toBottomOf="@+id/lrctext">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="大小:"
android:textSize="20sp" />
<com.google.android.material.slider.Slider
android:id="@+id/slide1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:valueFrom="0"
android:valueTo="36"
tools:ignore="SpeakableTextPresentCheck" />
<TextView
android:id="@+id/text_slide1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/layout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
app:layout_constraintTop_toBottomOf="@+id/layout1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="透明度:"
android:textSize="20sp" />
<com.google.android.material.slider.Slider
android:id="@+id/slide2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:valueFrom="0"
android:valueTo="1"
tools:ignore="SpeakableTextPresentCheck" />
<TextView
android:id="@+id/text_slide2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textSize="20sp" />
</LinearLayout>
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switch_a1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="歌词开关"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/layout2" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>

View File

@ -9,8 +9,7 @@
android:id="@+id/lrcView"
android:layout_width="match_parent"
android:layout_height="100dp"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="16dp" />
app:layout_constraintTop_toTopOf="parent"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/controlLayout"
@ -18,20 +17,7 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@+id/lrcView"
tools:layout_editor_absoluteX="16dp">
<ImageView
android:id="@+id/imageView2"
android:layout_width="36dp"
android:layout_height="36dp"
android:src="@drawable/like"
android:text="喜欢"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="UseAppTint" />
tools:layout_editor_absoluteX="-36dp">
<ImageView
android:id="@+id/syq"
@ -39,17 +25,17 @@
android:layout_height="36dp"
android:src="@drawable/syq"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/kg"
app:layout_constraintEnd_toStartOf="@+id/kg"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintTop_toTopOf="@+id/kg"
tools:ignore="ContentDescription,UseAppTint" />
<ImageView
android:id="@+id/kg"
android:layout_width="46dp"
android:layout_height="46dp"
android:tint="@color/white"
android:src="@drawable/zt"
android:tint="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
@ -61,7 +47,7 @@
android:layout_height="36dp"
android:src="@drawable/xyq"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/kg"
app:layout_constraintStart_toEndOf="@+id/kg"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="UseAppTint" />
@ -72,9 +58,9 @@
android:layout_height="wrap_content"
android:src="@drawable/lock"
android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/kg"
tools:ignore="UseAppTint" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="text">@color/white</color>
<color name="text_tm">#99FFFFFF</color>
<color name="text_tm">#CCC2DC</color>
<color name="bj">#2A2831</color>
</resources>

View File

@ -11,7 +11,7 @@
<color name="text_cz">#03A9F4</color>
<color name="text_cz_tm">#9903A9F4</color>
<color name="text">#000000</color>
<color name="text_tm">#80000000</color>
<color name="text_tm">#625B71</color>
<color name="tm">#00FFFFFF</color>
<color name="bj">#F2ECF6</color>