This commit is contained in:
yutou 2020-11-23 18:32:27 +08:00
parent 4daa74c16b
commit c7c6a07e45
14 changed files with 623 additions and 125 deletions

View File

@ -31,11 +31,13 @@ dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'jp.wasabeef:glide-transformations:4.3.0'
implementation 'org.projectlombok:lombok:1.18.12'
implementation 'jp.co.cyberagent.android:gpuimage:2.1.0'
implementation 'com.alibaba:fastjson:1.1.72.android'
//noinspection GradleCompatible
implementation 'com.android.support:support-media-compat:28.0.0'
implementation 'androidx.palette:palette:1.0.0'
implementation 'com.github.zrunker:ZTextView:v1.0.2'
}

View File

@ -1,35 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yutou.nas_music_player">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:usesCleartextTraffic="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".views.OpenActivity">
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<activity
android:name=".views.OpenActivity"
android:theme="@style/Theme.AppCompat.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".views.MainActivity"
android:theme="@style/Theme.AppCompat.NoActionBar"
<activity
android:name=".views.MainActivity"
android:fitsSystemWindows="true"
/>
<service android:name=".services.MusicService"
android:theme="@style/Theme.AppCompat.NoActionBar" />
<service
android:name=".services.MusicService"
android:exported="false">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>
<receiver android:name="androidx.media.session.MediaButtonReceiver" >
<receiver android:name="androidx.media.session.MediaButtonReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>

View File

@ -30,6 +30,7 @@ public class MediaBrowserHelper {
subscriptionCallback=new MediaBrowserSubscriptionCallback();
mMediaBrowser = new MediaBrowserCompat(context, new ComponentName(context, MusicService.class), browserConnectionCallback, null);
mMediaBrowser.connect();
MusicContainer.getInstance().setBrowserHelper(this);
}
public void onStop(){
if(controllerCompat!=null){
@ -40,7 +41,12 @@ public class MediaBrowserHelper {
mMediaBrowser=null;
}
}
public boolean isPlayer(){
return MusicContainer.getInstance().getMediaPlayer().isPlaying();
}
public MediaControllerCompat.TransportControls getTransportControls() {
if(controllerCompat==null)
return null;
return controllerCompat.getTransportControls();
}
private List<MediaControllerCompat.Callback> callbacks=new ArrayList<>();

View File

@ -81,7 +81,6 @@ public class MediaNotificationManager {
@NonNull PlaybackStateCompat state,
MediaSessionCompat.Token token) {
boolean isPlaying = state.getState() == PlaybackStateCompat.STATE_PLAYING;
MediaDescriptionCompat description = metadata.getDescription();
NotificationCompat.Builder builder =
buildNotification(state, token, isPlaying, metadata);
return builder.build();

View File

@ -7,46 +7,88 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yutou.nas_music_player.Interfaces.NetworkInterface;
import com.yutou.nas_music_player.tools.NetworkTool;
import com.yutou.nas_music_player.tools.StringUtil;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import static android.media.MediaMetadata.METADATA_KEY_DISPLAY_ICON;
import java.util.Timer;
import java.util.TimerTask;
public class MusicContainer {
public static final int PLAY_MODEL_RANDOM = 0;
public static final int PLAY_MODEL_LIST = 1;
public static final int PLAY_MODEL_TMP_LIST = 2;
public static final int PLAY_MODEL_ALBUM = 3;
private static MusicContainer container;
private MusicLibs libs;
private MediaPlayer mediaPlayer;
private int playIndex = 0;
private MusicData nowPlayData = null;
private final MusicLibsInitInterface initInterface;
private List<MediaPlayer.OnCompletionListener> completionListener;
private MediaBrowserHelper browserHelper;
private List<MusicData> playList, tmpList;
private Map<String, List<MusicData>> albumMapList;
private int playModel = PLAY_MODEL_RANDOM;
private MusicContainer() {
private MusicContainer(MusicLibsInitInterface initInterface) {
this.initInterface = initInterface;
mediaPlayer = new MediaPlayer();
playList = new ArrayList<>();
tmpList = new ArrayList<>();
albumMapList = new HashMap<>();
initMediaPlayer();
libs = new MusicLibs();
}
private void initMediaPlayer(){
public void setPlayModel(int playModel) {
this.playModel = playModel;
}
private void initMediaPlayer() {
completionListener = new ArrayList<>();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
playTimer.cancel();
playTimer = null;
browserHelper.getTransportControls().skipToNext();
}
});
}
public MediaPlayer getMediaPlayer(){
public void addCompletionListener(MediaPlayer.OnCompletionListener listener) {
completionListener.add(listener);
}
public MediaPlayer getMediaPlayer() {
return mediaPlayer;
}
public MusicData getNowPlayData(){
public MusicData getNowPlayData() {
return nowPlayData;
}
public void setNowPlayData(MusicData musicData) {
this.nowPlayData = musicData;
}
public void setBrowserHelper(MediaBrowserHelper browserHelper) {
this.browserHelper = browserHelper;
}
public static MusicContainer getInstance() {
return getInstance(null);
}
public static MusicContainer getInstance(MusicLibsInitInterface initInterface) {
if (container == null) {
container = new MusicContainer();
container = new MusicContainer(initInterface);
}
return container;
}
@ -56,12 +98,20 @@ public class MusicContainer {
}
public void playOfAllRandom() {
System.out.println("随机下一首");
randomMusic();
play(libs.mainData.get(playIndex));
}
public void play(MusicData data) {
String url =data.getPlayUrl();
System.out.println("准备播放:" + data.getTitle());
if (isPause) {
mediaPlayer.start();
isPause = false;
return;
}
nowPlayData = data;
String url = data.getPlayUrl();
try {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
@ -70,18 +120,48 @@ public class MusicContainer {
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
mediaPlayer.start();
if (playTimer == null) {
playTimer = new Timer();
playTimer.schedule(new TimerTask() {
@Override
public void run() {
for (MediaPlayer.OnCompletionListener listener : completionListener) {
if (listener != null) {
listener.onCompletion(mediaPlayer);
}
}
}
}, 0, 1000);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private Timer playTimer;
public MediaMetadataCompat getNowPlayMetadataCompat() {
if(nowPlayData==null){
if (nowPlayData == null) {
return null;
}
return getMetadataCompat(nowPlayData);
}
public Long getYear(String year) {
try {
return Long.parseLong(year);
} catch (Exception e) {
if (year.contains("-")) {
try {
return Long.parseLong(year.split("-")[0]);
} catch (Exception e1) {
return 8888L;
}
}
}
return 8888L;
}
public MediaMetadataCompat getMetadataCompat(MusicData data) {
MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
builder.putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, data.getTitle());
@ -89,13 +169,14 @@ public class MusicContainer {
builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, data.getTitle());
builder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, data.getAlbum());
builder.putString(MediaMetadataCompat.METADATA_KEY_COMPOSER, data.getComposer());
builder.putLong(MediaMetadataCompat.METADATA_KEY_YEAR, Long.parseLong(data.getYear()));
builder.putLong(MediaMetadataCompat.METADATA_KEY_YEAR, getYear(data.getYear()));
builder.putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, Long.parseLong(data.getTrack()));
builder.putLong(MediaMetadataCompat.METADATA_KEY_DISC_NUMBER, Long.parseLong(data.getDisc_no()));
builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION,3*60*1000);
if(data.getImg()!=null){
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON,data.getImg());
builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, ((int) data.getDurationAsDouble()) * 1000);
if (data.getImg() != null) {
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON, data.getImg());
}
builder.putString("md5", data.getMd5());
return builder.build();
}
@ -103,6 +184,42 @@ public class MusicContainer {
return getInstance().libs;
}
private boolean isPause = false;
public void pause() {
isPause = true;
mediaPlayer.pause();
}
public void playNext() {
switch (playModel) {
case PLAY_MODEL_LIST:
playList(true);
break;
case PLAY_MODEL_TMP_LIST:
playTmpList(true);
break;
case PLAY_MODEL_ALBUM:
playAlbumList(true);
break;
case PLAY_MODEL_RANDOM:
default:
playOfAllRandom();
}
}
private void playList(boolean isNext) {
}
private void playTmpList(boolean isNext) {
}
private void playAlbumList(boolean isNext) {
}
public class MusicLibs {
private List<MusicData> mainData;
@ -111,6 +228,10 @@ public class MusicContainer {
initData();
}
public List<MusicData> getMainData() {
return mainData;
}
private void initData() {
NetworkTool.init().httpGet(NetworkTool.NetworkAPI.MUSIC_ALL, new JSONObject(), new NetworkInterface() {
@Override
@ -123,6 +244,14 @@ public class MusicContainer {
nowPlayData = mainData.get(0);
}
System.out.println("获取列表完成");
for (MusicData mainDatum : mainData) {
if(StringUtil.isEmpty(mainDatum.getMd5())){
System.out.println(mainDatum.getFile());
}
}
if (initInterface != null) {
initInterface.init();
}
}
}
@ -133,5 +262,17 @@ public class MusicContainer {
});
}
public MusicData findMusic(String md5) {
for (MusicData data : mainData) {
if (md5.contains(data.getMd5())) {
return data;
}
}
return null;
}
}
public interface MusicLibsInitInterface {
void init();
}
}

View File

@ -7,6 +7,7 @@ import android.graphics.Color;
import android.util.Base64;
import com.alibaba.fastjson.JSONObject;
import com.yutou.nas_music_player.Interfaces.DownloadInterface;
import com.yutou.nas_music_player.Interfaces.NetworkInterface;
import com.yutou.nas_music_player.tools.NetworkTool;
import com.yutou.nas_music_player.tools.StringUtil;
@ -28,6 +29,16 @@ public class MusicData {
private boolean isDir = false;
private Bitmap img;
private int bitRate;//比特率
private int sampleRate;//采样率
private long noOfSamples;//采样数
private int channelCount;//声道
private String encodingType;//解码类型
private double durationAsDouble;//持续时长
private boolean lossless;//无损
private boolean variableBitRate;//固定码率
private String md5;//确保是同一个文件
public MusicData() {
}
@ -175,10 +186,83 @@ public class MusicData {
});
return img;
}
public int getImageColor(){
if(img==null){
public int getImageColor() {
if (img == null) {
return -1;
}
return Palette.from(img).generate().getLightVibrantColor(Color.parseColor("#6DE1A1"));
}
public int getBitRate() {
return bitRate;
}
public void setBitRate(int bitRate) {
this.bitRate = bitRate;
}
public int getSampleRate() {
return sampleRate;
}
public void setSampleRate(int sampleRate) {
this.sampleRate = sampleRate;
}
public long getNoOfSamples() {
return noOfSamples;
}
public void setNoOfSamples(long noOfSamples) {
this.noOfSamples = noOfSamples;
}
public int getChannelCount() {
return channelCount;
}
public void setChannelCount(int channelCount) {
this.channelCount = channelCount;
}
public String getEncodingType() {
return encodingType;
}
public void setEncodingType(String encodingType) {
this.encodingType = encodingType;
}
public double getDurationAsDouble() {
return durationAsDouble;
}
public void setDurationAsDouble(double durationAsDouble) {
this.durationAsDouble = durationAsDouble;
}
public boolean isLossless() {
return lossless;
}
public void setLossless(boolean lossless) {
this.lossless = lossless;
}
public boolean isVariableBitRate() {
return variableBitRate;
}
public void setVariableBitRate(boolean variableBitRate) {
this.variableBitRate = variableBitRate;
}
public String getMd5() {
return md5;
}
public void setMd5(String md5) {
this.md5 = md5;
}
}

View File

@ -3,6 +3,8 @@ package com.yutou.nas_music_player.services;
import android.app.Notification;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
@ -25,6 +27,8 @@ import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import static android.media.MediaPlayer.SEEK_PREVIOUS_SYNC;
public class MusicService extends MediaBrowserServiceCompat {
public MediaSessionCompat mediaSession;
private PlaybackStateCompat.Builder stateBuilder;
@ -53,6 +57,7 @@ public class MusicService extends MediaBrowserServiceCompat {
mediaSession.setPlaybackState(stateBuilder.build());
mediaSession.setCallback(new MediaSessionCallback());
setSessionToken(mediaSession.getSessionToken());
MusicContainer.getInstance().addCompletionListener(new PlayCompletionListener());
}
@Nullable
@ -73,82 +78,125 @@ public class MusicService extends MediaBrowserServiceCompat {
result.sendResult(mediaItems);
}
public void onSeekTo(long pos) {
MusicData data = MusicContainer.getInstance().getNowPlayData();
MediaMetadataCompat metadataCompat = MusicContainer.getInstance().getMetadataCompat(data);
Notification notification = notificationManager.getNotification(metadataCompat, builderState(pos).build(), getSessionToken());
notificationManager.getManager()
.notify(MediaNotificationManager.NOTIFICATION_ID, notification);
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setActions(MEDIA_SESSION_ACTIONS)
.setState(mState, pos, 1.0f, SystemClock.elapsedRealtime()).build());
}
public PlaybackStateCompat.Builder builderState(long position) {
PlaybackStateCompat.Builder stateBuilder = new PlaybackStateCompat.Builder();
stateBuilder.setActions(getAvailableActions());
stateBuilder.setState(mState,
position,
1.0f,
SystemClock.elapsedRealtime());
return stateBuilder;
}
private long getAvailableActions() {
long actions = PlaybackStateCompat.ACTION_PLAY_FROM_MEDIA_ID
| PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH
| PlaybackStateCompat.ACTION_SKIP_TO_NEXT
| PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS;
switch (mState) {
case PlaybackStateCompat.STATE_STOPPED:
actions |= PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_PAUSE;
break;
case PlaybackStateCompat.STATE_PLAYING:
actions |= PlaybackStateCompat.ACTION_STOP
| PlaybackStateCompat.ACTION_PAUSE
| PlaybackStateCompat.ACTION_SEEK_TO;
break;
case PlaybackStateCompat.STATE_PAUSED:
actions |= PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_STOP;
break;
default:
actions |= PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_PLAY_PAUSE
| PlaybackStateCompat.ACTION_STOP
| PlaybackStateCompat.ACTION_PAUSE;
}
return actions;
}
public class MediaSessionCallback extends MediaSessionCompat.Callback {
public void updateNotification(){
MediaMetadataCompat metadataCompat = MusicContainer.getInstance().getNowPlayMetadataCompat();
mediaSession.setMetadata(metadataCompat);
mediaSession.setActive(true);
Notification notification =
notificationManager.getNotification(
metadataCompat, builderState(0).build(), getSessionToken());
notificationManager.getManager()
.notify(MediaNotificationManager.NOTIFICATION_ID, notification);
}
@Override
public void onPlay() {
super.onPlay();
System.out.println("接收到播放指令");
mState=PlaybackStateCompat.STATE_PLAYING;
MediaMetadataCompat metadataCompat = MusicContainer.getInstance().getNowPlayMetadataCompat();
mediaSession.setMetadata(metadataCompat);
mediaSession.setActive(true);
Notification notification = notificationManager.getNotification(metadataCompat, builderState(0).build(), getSessionToken());
startForeground(MediaNotificationManager.NOTIFICATION_ID, notification);
new Timer().schedule(new TimerTask() {
long position = 0;
@Override
public void run() {
position += 1000;
MusicData data=MusicContainer.getInstance().getNowPlayData();
data.setTitle(position+"");
MediaMetadataCompat metadataCompat = MusicContainer.getInstance().getMetadataCompat(data);
Notification notification = notificationManager.getNotification(metadataCompat, builderState(position).build(), getSessionToken());
notificationManager.getManager()
.notify(MediaNotificationManager.NOTIFICATION_ID, notification);
mediaSession.setPlaybackState(new PlaybackStateCompat.Builder()
.setActions(MEDIA_SESSION_ACTIONS)
.setState(PlaybackStateCompat.STATE_PLAYING,position,1.0f,SystemClock.elapsedRealtime()).build());
}
}, 0, 1000);
MusicContainer.getInstance().play(MusicContainer.getInstance().getNowPlayData());
}
@Override
public void onPause() {
super.onPause();
mState=PlaybackStateCompat.STATE_PAUSED;
MusicContainer.getInstance().pause();
//MusicService.this.onSeekTo(-1);
}
@Override
public void onSeekTo(long pos) {
super.onSeekTo(pos);
}
public PlaybackStateCompat.Builder builderState(long position) {
PlaybackStateCompat.Builder stateBuilder = new PlaybackStateCompat.Builder();
stateBuilder.setActions(getAvailableActions());
stateBuilder.setState(mState,
position,
1.0f,
SystemClock.elapsedRealtime());
return stateBuilder;
}
private long getAvailableActions() {
long actions = PlaybackStateCompat.ACTION_PLAY_FROM_MEDIA_ID
| PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH
| PlaybackStateCompat.ACTION_SKIP_TO_NEXT
| PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS;
switch (mState) {
case PlaybackStateCompat.STATE_STOPPED:
actions |= PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_PAUSE;
break;
case PlaybackStateCompat.STATE_PLAYING:
actions |= PlaybackStateCompat.ACTION_STOP
| PlaybackStateCompat.ACTION_PAUSE
| PlaybackStateCompat.ACTION_SEEK_TO;
break;
case PlaybackStateCompat.STATE_PAUSED:
actions |= PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_STOP;
break;
default:
actions |= PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_PLAY_PAUSE
| PlaybackStateCompat.ACTION_STOP
| PlaybackStateCompat.ACTION_PAUSE;
System.out.println("SeeTo :"+pos);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
MusicContainer.getInstance().getMediaPlayer().seekTo(pos,SEEK_PREVIOUS_SYNC);
}else{
MusicContainer.getInstance().getMediaPlayer().seekTo((int) pos);
}
return actions;
MusicService.this.onSeekTo(pos);
}
@Override
public void onSkipToNext() {
super.onSkipToNext();
MusicContainer.getInstance().playNext();
updateNotification();
}
@Override
public void onSkipToPrevious() {
super.onSkipToPrevious();
}
@Override
public void onStop() {
super.onStop();
mState=PlaybackStateCompat.STATE_STOPPED;
MusicContainer.getInstance().getMediaPlayer().stop();
}
}
private class PlayCompletionListener implements MediaPlayer.OnCompletionListener {
@Override
public void onCompletion(MediaPlayer mp) {
onSeekTo(mp.getCurrentPosition());
}
}
}

View File

@ -0,0 +1,14 @@
package com.yutou.nas_music_player.tools;
import android.content.Context;
import android.content.SharedPreferences;
import com.yutou.nas_music_player.MyApplication;
public class ConfigTools {
public static final String previous_music="previous";
public static SharedPreferences getPreferences(){
return MyApplication.application.getSharedPreferences("app_config", Context.MODE_PRIVATE);
}
}

View File

@ -2,94 +2,229 @@ package com.yutou.nas_music_player.views;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Color;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.v4.media.MediaMetadataCompat;
import android.support.v4.media.session.MediaControllerCompat;
import android.support.v4.media.session.MediaSessionCompat;
import android.support.v4.media.session.PlaybackStateCompat;
import android.view.View;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.alibaba.fastjson.JSON;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.yutou.nas_music_player.R;
import com.yutou.nas_music_player.containers.MediaBrowserHelper;
import com.yutou.nas_music_player.containers.MusicContainer;
import com.yutou.nas_music_player.containers.MusicData;
import com.yutou.nas_music_player.tools.AppData;
import com.yutou.nas_music_player.tools.ConfigTools;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import cc.ibooker.ztextviewlib.MarqueeTextView;
import jp.wasabeef.glide.transformations.BlurTransformation;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
public class MainActivity extends AppCompatActivity {
private ImageButton play, previous, next;
private MediaBrowserHelper browserHelper;
private ImageView imageView2;
private ImageView album_image, background_image;
private MarqueeTextView title, album, artist;
private TextView positionTime, durationTime, bitRate;
private SeekBar seekBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setBarColor(android.R.color.transparent);
setContentView(R.layout.activity_main);
MusicContainer.getInstance();
play = findViewById(R.id.play);
next = findViewById(R.id.next);
previous = findViewById(R.id.previous);
imageView2 = findViewById(R.id.imageView2);
initView();
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (browserHelper.isPlayer()) {
browserHelper.getTransportControls().pause();
} else {
browserHelper.getTransportControls().play();
}
}
});
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
browserHelper.getTransportControls().skipToNext();
}
});
previous.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MusicData data=MusicContainer.getInstance().getNowPlayData();
if(data!=null){
setBarColor(data.getImageColor());
}
browserHelper.getTransportControls().skipToPrevious();
}
});
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (browserHelper.getTransportControls() != null)
browserHelper.getTransportControls().seekTo(progress);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
browserHelper = new MediaBrowserHelper(this);
browserHelper.regPlayListener(new PlayListener());
initData();
}
public void setBarColor(int color){
private void initData() {
String previousMusic = ConfigTools.getPreferences().getString(ConfigTools.previous_music, null);
MusicData data;
if (previousMusic != null) {
data = JSON.parseObject(previousMusic, MusicData.class);
MusicContainer.getInstance().setNowPlayData(data);
setPlayData(data);
} else {
data = MusicContainer.getLibs().getMainData().size() > 0 ? MusicContainer.getLibs().getMainData().get(0) : null;
if (data != null) {
setPlayData(data);
} else {
Toast.makeText(this, "播放列表获取失败", Toast.LENGTH_LONG).show();
}
}
}
@SuppressLint("SetTextI18n")
private void setPlayData(final MusicData data) {
System.out.println("设置歌曲");
System.out.println(data);
if(data==null)
return;
title.setText(data.getTitle());
artist.setText(data.getArtist());
album.setText(data.getAlbum());
bitRate.setText(data.getBitRate() + "kbps / " + data.getSampleRate() + "hz");
seekBar.setMax((int) data.getDurationAsDouble());
int minutes = (int) (data.getDurationAsDouble() / 60);
int seconds = (int) (data.getDurationAsDouble() % 60);
durationTime.setText(minutes + ":" + seconds);
if (data.getImg() != null) {
setImage(data);
} else {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
if (data.getImg() != null) {
AppData.handler.post(new Runnable() {
@Override
public void run() {
setImage(data);
}
});
cancel();
}
}
}, 0, 100);
}
}
private void setImage(MusicData data) {
album_image.setImageBitmap(data.getImg());
background_image.setImageBitmap(data.getImg());
setBarColor(data.getImageColor());
Glide.with(this).load(data.getImg())
.apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(25, 3)))
.into(album_image);
Glide.with(this).load(data.getImg())
.apply(RequestOptions.bitmapTransform(new BlurTransformation(25, 3)))
.into(background_image);
}
private void initView() {
play = findViewById(R.id.play);
next = findViewById(R.id.next);
previous = findViewById(R.id.previous);
album_image = findViewById(R.id.album_image);
background_image = findViewById(R.id.background_image);
title = findViewById(R.id.title);
artist = findViewById(R.id.artist);
album = findViewById(R.id.album);
bitRate = findViewById(R.id.bitRate);
positionTime = findViewById(R.id.positionTime);
durationTime = findViewById(R.id.durationTime);
seekBar = findViewById(R.id.seekBar);
}
public void setBarColor(int color) {
getWindow().setStatusBarColor(color);
getWindow().setNavigationBarColor(color);
}
private class PlayListener extends MediaControllerCompat.Callback {
@SuppressLint("SetTextI18n")
@Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {
super.onPlaybackStateChanged(state);
System.out.println("播放状态变化:" + state.getState());
if (state.getState() == PlaybackStateCompat.STATE_PLAYING) {
int duration = (int) (state.getPosition() / 1000);
int minutes = duration / 60;
int seconds = duration % 60;
positionTime.setText(minutes + ":" + seconds);
seekBar.setProgress((int) (state.getPosition() / 1000));
play.setImageResource(android.R.drawable.ic_media_pause);
} else {
play.setImageResource(android.R.drawable.ic_media_play);
}
}
@Override
public void onMetadataChanged(MediaMetadataCompat metadata) {
super.onMetadataChanged(metadata);
if(metadata!=null){
imageView2.setImageBitmap(metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON));
String md5=null;
try {
System.out.println("播放歌曲变换:"+metadata.getString("md5"));
md5=metadata.getString("md5");
}catch (Exception e){
e.printStackTrace();
}
if (md5 != null) {
setPlayData(MusicContainer.getLibs().findMusic(md5));
}
}
@Override
public void onSessionDestroyed() {
super.onSessionDestroyed();
System.out.println("连接被销毁");
}
@Override
public void onQueueChanged(List<MediaSessionCompat.QueueItem> queue) {
super.onQueueChanged(queue);
System.out.println("不知道是啥变换了");
}
public void setImage(){
public void setImage() {
}
}

View File

@ -2,16 +2,29 @@ package com.yutou.nas_music_player.views;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.yutou.nas_music_player.R;
import com.yutou.nas_music_player.containers.MusicContainer;
public class OpenActivity extends AppCompatActivity {
TextView textView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent=new Intent(this,MainActivity.class);
startActivity(intent);
finish();
setContentView(R.layout.activity_open);
textView=findViewById(R.id.textView);
MusicContainer.getInstance(new MusicContainer.MusicLibsInitInterface() {
@Override
public void init() {
Intent intent=new Intent(OpenActivity.this,MainActivity.class);
startActivity(intent);
finish();
}
});
}
}

View File

@ -16,7 +16,7 @@
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/imageView"
android:id="@+id/background_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
@ -27,16 +27,33 @@
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView2"
android:id="@+id/album_image"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="150dp"
android:contentDescription="专辑图"
android:src="@drawable/ic_launcher_foreground"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<cc.ibooker.ztextviewlib.MarqueeTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="26dp"
android:shadowColor="@color/textColorGray"
android:shadowDx="5"
android:shadowDy="5"
android:shadowRadius="1"
android:text="title"
android:textColor="@color/musicTitle"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@+id/album_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -60,7 +77,16 @@
android:layout_marginStart="10dp"
android:layout_weight="1"
android:text="00:00"
android:textColor="@color/colorBlack" />
android:textColor="@color/textColorWhite" />
<TextView
android:id="@+id/bitRate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textColor="@color/textColorWhite"
android:text="TextView" />
<TextView
android:id="@+id/durationTime"
@ -70,11 +96,11 @@
android:layout_weight="1"
android:gravity="end"
android:text="00:00"
android:textColor="@color/colorBlack" />
android:textColor="@color/textColorGray" />
</LinearLayout>
<ProgressBar
android:id="@+id/progressBar"
<SeekBar
android:id="@+id/seekBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -82,7 +108,6 @@
android:backgroundTint="#D12828"
android:elevation="6dp"
android:max="100"
android:progress="50"
android:progressBackgroundTintMode="add"
android:progressTint="#EC1E1E"
android:textColor="@color/colorBlack" />
@ -134,25 +159,21 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<TextView
android:id="@+id/title"
<cc.ibooker.ztextviewlib.MarqueeTextView
android:id="@+id/album"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="4dp"
android:text="title"
android:shadowColor="@color/textColorGray"
android:shadowRadius="1"
android:shadowDx="5"
android:shadowDy="5"
android:textColor="@color/musicTitle"
android:textSize="24sp" />
android:text="album"
android:textColor="@color/textColorWhite"
android:textSize="20sp" />
<TextView
<cc.ibooker.ztextviewlib.MarqueeTextView
android:id="@+id/artist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="artist-album"
android:textColor="@color/musicArtist"
android:text="artist"
android:textColor="@color/textColorWhite"
android:textSize="20sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent">
<ImageView
android:id="@+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/ic_launcher" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:gravity="center"
android:text="初始化中"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView3" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -8,4 +8,5 @@
<color name="musicTitle">#000000</color>
<color name="musicArtist">#000000</color>
<color name="textColorGray">#DEDEDE</color>
<color name="textColorWhite">#FFFFFF</color>
</resources>

View File

@ -16,6 +16,7 @@ allprojects {
repositories {
google()
jcenter()
maven { url 'https://jitpack.io' }
}
}