增加了播放音乐的界面,并初步实现歌手背景显示

pull/1/head
jsyjst 7 years ago
parent 2d8f2b1925
commit 06c7b3ea1f

@ -40,4 +40,11 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.google.code.gson:gson:2.8.2'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
//glide
api('com.github.bumptech.glide:glide:4.7.1') {
exclude group: 'com.android.support'
}
api('jp.wasabeef:glide-transformations:3.3.0') {
exclude group: 'com.android.support'
}
}

@ -4,9 +4,10 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name="com.example.musicplayer.constant.MyApplication"
android:name=".constant.MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
@ -20,20 +21,14 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".view.MainActivity">
</activity>
<activity android:name=".view.MainActivity"></activity>
<service
android:name=".service.PlayerService"
android:enabled="true"
android:exported="true">
</service>
android:exported="true"></service>
<activity android:name=".view.PlayActivity"></activity>
</application>
</manifest>

@ -2,22 +2,22 @@ package com.example.musicplayer.base;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
/**
* Created by on 2018/10/10.
*/
public abstract class BaseActivity extends Activity {
public abstract class BaseActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
initVariables();
initViews();
loadData();
onClick();
}
protected abstract void initVariables();
protected abstract void initViews();
protected abstract void loadData();
protected abstract void onClick();
}

@ -0,0 +1,9 @@
package com.example.musicplayer.constant;
/**
* Created by on 2018/10/26.
*/
public class BaseUri {
public static String SINGER_URL="http://music.163.com/api/search/get/";
}

@ -0,0 +1,21 @@
package com.example.musicplayer.contract;
/**
* Created by on 2018/10/26.
*/
public interface IPlayContract {
interface Model{
void getSingerImg(String singer);//网络请求获得歌手uri
}
interface View{
String getSingerName(); //得到歌手的姓名
void setSingerImg(String ImgUrl); //将图片设置成背景
void setImgFail(String errorMessage);
}
interface Presenter{
void getSingerImg(String singer);
void getSingerImgSuccess(String ImgUrl); //成功获取图片
void getSingerImgFail(); //请求失败
}
}

@ -0,0 +1,105 @@
package com.example.musicplayer.entiy;
import java.util.List;
/**
* Created by on 2018/10/26.
*/
public class SingerImg {
/**
* result : {"artistCount":1,"artists":[{"id":840134,"name":"刘瑞琦","picUrl":"http://p1.music.126.net/qTDkcmWPMK3U54RNC0IgMw==/109951163288035254.jpg","alias":[],"albumSize":20,"picId":109951163288035254,"img1v1Url":"http://p1.music.126.net/a13xmSNqxMY5M_R1OFvPvA==/109951163288038157.jpg","accountId":3788031,"img1v1":109951163288038157,"mvSize":16,"followed":false,"trans":null}]}
* code : 200
*/
private ResultBean result;
private int code;
public ResultBean getResult() {
return result;
}
public void setResult(ResultBean result) {
this.result = result;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public static class ResultBean {
/**
* artistCount : 1
* artists : [{"id":840134,"name":"刘瑞琦","picUrl":"http://p1.music.126.net/qTDkcmWPMK3U54RNC0IgMw==/109951163288035254.jpg","alias":[],"albumSize":20,"picId":109951163288035254,"img1v1Url":"http://p1.music.126.net/a13xmSNqxMY5M_R1OFvPvA==/109951163288038157.jpg","accountId":3788031,"img1v1":109951163288038157,"mvSize":16,"followed":false,"trans":null}]
*/
private List<ArtistsBean> artists;
public List<ArtistsBean> getArtists() {
return artists;
}
public void setArtists(List<ArtistsBean> artists) {
this.artists = artists;
}
public static class ArtistsBean {
/**
* id : 840134
* name :
* picUrl : http://p1.music.126.net/qTDkcmWPMK3U54RNC0IgMw==/109951163288035254.jpg
* alias : []
* albumSize : 20
* picId : 109951163288035254
* img1v1Url : http://p1.music.126.net/a13xmSNqxMY5M_R1OFvPvA==/109951163288038157.jpg
* accountId : 3788031
* img1v1 : 109951163288038157
* mvSize : 16
* followed : false
* trans : null
*/
private int id;
private String name;
private String picUrl;
private String img1v1Url;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPicUrl() {
return picUrl;
}
public void setPicUrl(String picUrl) {
this.picUrl = picUrl;
}
public String getImg1v1Url() {
return img1v1Url;
}
public void setImg1v1Url(String img1v1Url) {
this.img1v1Url = img1v1Url;
}
}
}
}

@ -0,0 +1,41 @@
package com.example.musicplayer.https;
import com.example.musicplayer.constant.BaseUri;
import com.example.musicplayer.https.api.SingerImgApi;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import retrofit2.CallAdapter;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import static com.example.musicplayer.constant.BaseUri.SINGER_URL;
/**
* Created by on 2018/10/26.
*/
public class NetWork {
private static okhttp3.OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(20, TimeUnit.SECONDS);
private static Converter.Factory gsonConverterFactory = GsonConverterFactory.create();
private static CallAdapter.Factory rxJavaCallAdapterFactory = RxJava2CallAdapterFactory.create();
private static SingerImgApi singerImgApi;
public static SingerImgApi getSingerImgApi(){
if(singerImgApi==null){
Retrofit retrofit=new Retrofit.Builder()
.client(builder.build())
.baseUrl(SINGER_URL)
.addCallAdapterFactory(rxJavaCallAdapterFactory)
.addConverterFactory(gsonConverterFactory)
.build();
singerImgApi=retrofit.create(SingerImgApi.class);
}
return singerImgApi;
}
}

@ -0,0 +1,8 @@
package com.example.musicplayer.https;
/**
* Created by on 2018/10/26.
*/
public class RetrofitHelp {
}

@ -0,0 +1,18 @@
package com.example.musicplayer.https.api;
import com.example.musicplayer.entiy.SingerImg;
import io.reactivex.Observable;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
/**
* Created by on 2018/10/26.
*/
public interface SingerImgApi {
@POST("web?csrf_token=&type=100")
@FormUrlEncoded
Observable<SingerImg> getSingerImg(@Field("s")String singer);
}

@ -0,0 +1,66 @@
package com.example.musicplayer.model;
import android.support.annotation.MainThread;
import android.util.Log;
import com.example.musicplayer.contract.IPlayContract;
import com.example.musicplayer.entiy.SingerImg;
import com.example.musicplayer.https.NetWork;
import java.io.IOException;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
/**
* Created by on 2018/10/26.
*/
public class IPlayModel implements IPlayContract.Model {
private String TAG="IPlayModel";
private IPlayContract.Presenter mPresenter;
public IPlayModel(IPlayContract.Presenter presenter){
mPresenter=presenter;
}
@Override
public void getSingerImg(String singer) {
NetWork.getSingerImgApi()
.getSingerImg(singer)
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<SingerImg>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(SingerImg value) {
if(value.getCode()==200) {
mPresenter.getSingerImgSuccess(value.getResult().getArtists().get(0).getImg1v1Url());
Log.d(TAG, "onNext: "+value.getResult().getArtists().get(0).getImg1v1Url());
}else{
Log.d(TAG, "onNext: "+value.getCode());
mPresenter.getSingerImgFail();
}
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
mPresenter.getSingerImgFail();
}
@Override
public void onComplete() {
}
});
}
}

@ -1,19 +1,12 @@
package com.example.musicplayer.model;
import android.database.Cursor;
import android.provider.MediaStore;
import com.example.musicplayer.constant.MyApplication;
import com.example.musicplayer.contract.ILocalMusicContract;
import com.example.musicplayer.entiy.Mp3Info;
import com.example.musicplayer.util.MediaUntil;
import com.example.musicplayer.util.MediaUtil;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.Observable;
import io.reactivex.ObservableOnSubscribe;
/**
* Created by on 2018/10/17.
*/
@ -32,7 +25,7 @@ public class LocalMusicModel implements ILocalMusicContract.Model {
new Thread(new Runnable() {
@Override
public void run() {
mMp3InfoList= MediaUntil.getMp3Info();
mMp3InfoList= MediaUtil.getMp3Info();
mPresenter.showMusicList(mMp3InfoList);
}

@ -0,0 +1,37 @@
package com.example.musicplayer.presenter;
import com.example.musicplayer.base.BasePresenter;
import com.example.musicplayer.contract.IPlayContract;
import com.example.musicplayer.model.IPlayModel;
/**
* Created by on 2018/10/26.
*/
public class PlayPresenter extends BasePresenter<IPlayContract.View> implements IPlayContract.Presenter {
private IPlayModel mModel;
public PlayPresenter(){
mModel=new IPlayModel(this);
}
@Override
public void getSingerImg(String singer) {
mModel.getSingerImg(singer);
}
@Override
public void getSingerImgSuccess(String ImgUrl) {
if(isAttachView()){
getMvpView().setSingerImg(ImgUrl);
}
}
@Override
public void getSingerImgFail() {
if(isAttachView()){
getMvpView().setImgFail("获取歌手照片失败");
}
}
}

@ -12,7 +12,7 @@ import android.util.Log;
import com.example.musicplayer.entiy.Mp3Info;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.util.FileHelper;
import com.example.musicplayer.util.MediaUntil;
import com.example.musicplayer.util.MediaUtil;
import java.util.List;
@ -32,7 +32,7 @@ public class PlayerService extends Service {
@Override
public void onCreate(){
mMp3InfoList= MediaUntil.getMp3Info();
mMp3InfoList= MediaUtil.getMp3Info();
}
@Override
@ -51,6 +51,8 @@ public class PlayerService extends Service {
song.setArtist(mMp3InfoList.get(mCurrent).getArtist());
song.setDuration(mMp3InfoList.get(mCurrent).getDuration());
song.setUrl(mMp3InfoList.get(mCurrent).getUrl());
song.setId(mMp3InfoList.get(mCurrent).getId());
song.setAlbumId(mMp3InfoList.get(mCurrent).getAlbumId());
FileHelper.saveSong(song);
if(mCurrent<=mMp3InfoList.size()){
mPlayStatusBinder.play(0);
@ -133,6 +135,8 @@ public class PlayerService extends Service {
song.setArtist(mMp3InfoList.get(mCurrent).getArtist());
song.setDuration(mMp3InfoList.get(mCurrent).getDuration());
song.setUrl(mMp3InfoList.get(mCurrent).getUrl());
song.setId(mMp3InfoList.get(mCurrent).getId());
song.setAlbumId(mMp3InfoList.get(mCurrent).getAlbumId());
FileHelper.saveSong(song);
mPlayStatusBinder.play(0);

@ -0,0 +1,62 @@
package com.example.musicplayer.util;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.view.View;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
/**
* Created by on 2018/10/26.
*/
//通用的工具类
public class CommonUtil {
private static Toast toast;
public static void hideStatusBar(Activity activity) {
if (Build.VERSION.SDK_INT >= 22) {
View decorView = activity.getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
}
}
//
public static void showToast(Context context, String message) {
if (toast == null) {
toast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
} else {
toast.setText(message);
}
toast.show();
}
/*
*
*/
public static int getScreenWidth(Context context) {
if (null == context) {
return 0;
}
return context.getResources().getDisplayMetrics().widthPixels;
}
/**
*
*/
public static int getScreenHeight(Context context) {
if (null == context) {
return 0;
}
return context.getResources().getDisplayMetrics().heightPixels;
}
}

@ -1,277 +0,0 @@
package com.example.musicplayer.util;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import com.example.musicplayer.R;
import com.example.musicplayer.constant.MyApplication;
import com.example.musicplayer.entiy.Mp3Info;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created by on 2018/10/22.
*/
public class MediaUntil {
//获取专辑封面的Uri
private static final Uri albumArtUri = Uri.parse("content://media/external/audio/albumart");
public static List<Mp3Info> getMp3Info() {
List<Mp3Info> mp3InfoList = new ArrayList<>();
Cursor cursor = MyApplication.getContext().getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToNext();
Mp3Info mp3Info = new Mp3Info();
long id = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media._ID)); //音乐id
String title = cursor.getString((cursor
.getColumnIndex(MediaStore.Audio.Media.TITLE)));//音乐标题
String artist = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.ARTIST));//艺术家
long duration = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media.DURATION));//时长
long size = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media.SIZE)); //文件大小
long albumId = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
String url = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DATA)); //文件路径
int isMusic = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));//是否为音乐
if (isMusic != 0) {//只把音乐添加到集合当中
if (size > 1000 * 800) {
// 注释部分是切割标题,分离出歌曲名和歌手 (本地媒体库读取的歌曲信息不规范)
if (title.contains("-")) {
String[] str = title.split("-");
artist = str[0];
title = str[1];
}
mp3Info.setTitle(title.trim());
mp3Info.setArtist(artist);
mp3Info.setDuration(duration);
mp3Info.setSize(size);
mp3Info.setUrl(url);
mp3Info.setAlbumId(albumId);
mp3Info.setId(id);
mp3InfoList.add(mp3Info);
}
}
}
cursor.close();
return mp3InfoList;
}
public static Bitmap getDefaultArtwork(Context context, boolean small) {
return (Bitmap) BitmapFactory.decodeResource(context.getResources(), R.drawable.background);
}
/**
*
* * @param context
* * @param songid
* * @param albumid
* * @return
*/
private static Bitmap getArtworkFromFile(Context context, long songid, long albumid) {
Bitmap bm = null;
if (albumid < 0) {
throw new IllegalArgumentException("Must specify an album or a song id");
}
try {
BitmapFactory.Options options = new BitmapFactory.Options();
FileDescriptor fd = null;
if (albumid < 0) {
Uri uri = Uri.parse("content://media/external/audio/media/" + songid + "/albumart");
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
if (pfd != null) {
fd = pfd.getFileDescriptor();
}
} else {
Uri uri = ContentUris.withAppendedId(albumArtUri, albumid);
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
if (pfd != null) {
fd = pfd.getFileDescriptor();
}
}
options.inSampleSize = 1; // 只进行大小判断
options.inJustDecodeBounds = true;
// 调用此方法得到options得到图片大小
BitmapFactory.decodeFileDescriptor(fd, null, options);
//我们的目标是在800pixel的画面上显示
// 所以需要调用computeSampleSize得到图片缩放的比例
options.inSampleSize = 100;
//我们得到了缩放的比例现在开始正式读入Bitmap数据
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888; //根据options参数减少所需要的内存
bm = BitmapFactory.decodeFileDescriptor(fd, null, options);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return bm;
}
/**
* * @param context * @param song_id * @param album_id * @param allowdefalut * @return
*/
public static Bitmap getArtwork(Context context, long song_id, long album_id, boolean allowdefalut, boolean small) {
if (album_id < 0) {
if (song_id < 0) {
Bitmap bm = getArtworkFromFile(context, song_id, -1);
if (bm != null) {
return bm;
}
}
if (allowdefalut) {
return getDefaultArtwork(context, small);
}
return null;
}
ContentResolver res = context.getContentResolver();
Uri uri = ContentUris.withAppendedId(albumArtUri, album_id);
if (uri != null) {
InputStream in = null;
try {
in = res.openInputStream(uri);
BitmapFactory.Options options = new BitmapFactory.Options();
//先制定原始大小
options.inSampleSize = 1;
//只进行大小判断
options.inJustDecodeBounds = true;
//调用此方法得到options得到图片的大小
BitmapFactory.decodeStream(in, null, options);
/** 我们的目标是在你N pixel的画面上显示。 所以需要调用computeSampleSize得到图片缩放的比例 **/
/** 这里的target为800是根据默认专辑图片大小决定的800只是测试数字但是试验后发现完美的结合 **/
if (small) {
options.inSampleSize = computeSampleSize(options, 40);
} else {
options.inSampleSize = computeSampleSize(options, 600);
}
// 我们得到了缩放比例现在开始正式读入Bitmap数据
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
in = res.openInputStream(uri);
return BitmapFactory.decodeStream(in, null, options);
} catch (FileNotFoundException e) {
Bitmap bm = getArtworkFromFile(context, song_id, album_id);
if (bm != null) {
if (bm.getConfig() == null) {
bm = bm.copy(Bitmap.Config.RGB_565, false);
if (bm == null && allowdefalut) {
return getDefaultArtwork(context, small);
}
}
} else if (allowdefalut) {
bm = getDefaultArtwork(context, small);
}
return bm;
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
/**
* * @param options * @param target * @return
*/
public static int computeSampleSize(BitmapFactory.Options options, int target) {
int w = options.outWidth;
int h = options.outHeight;
int candidateW = w / target;
int candidateH = h / target;
int candidate = Math.max(candidateW, candidateH);
if (candidate == 0) {
return 1;
}
if (candidate > 1) {
if ((w > target) && (w / candidate) < target) {
candidate -= 1;
}
}
if (candidate > 1) {
if ((h > target) && (h / candidate) < target) {
candidate -= 1;
}
}
return candidate;
}
//
public static Bitmap getMusicBitemp(Context context, long songid,
long albumid) {
Bitmap bm = null;
// 专辑id和歌曲id小于0说明没有专辑、歌曲并抛出异常
if (albumid < 0 && songid < 0) {
throw new IllegalArgumentException(
"Must specify an album or a song id");
}
try {
if (albumid < 0) {
Uri uri = Uri.parse("content://media/external/audio/media/"
+ songid + "/albumart");
ParcelFileDescriptor pfd = context.getContentResolver()
.openFileDescriptor(uri, "r");
if (pfd != null) {
FileDescriptor fd = pfd.getFileDescriptor();
bm = BitmapFactory.decodeFileDescriptor(fd);
}
} else {
Uri uri = ContentUris.withAppendedId(albumArtUri, albumid);
ParcelFileDescriptor pfd = context.getContentResolver()
.openFileDescriptor(uri, "r");
if (pfd != null) {
FileDescriptor fd = pfd.getFileDescriptor();
bm = BitmapFactory.decodeFileDescriptor(fd);
} else {
return null;
}
}
} catch (FileNotFoundException ex) {
}
//如果获取的bitmap为空则返回一个默认的bitmap
if (bm == null) {
Resources resources = context.getResources();
Drawable drawable = resources.getDrawable(R.drawable.background);
//Drawable 转 Bitmap
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
bm = bitmapDrawable.getBitmap();
}
return Bitmap.createScaledBitmap(bm, 150, 150, true);
}
}

@ -0,0 +1,278 @@
package com.example.musicplayer.util;
import android.content.ContentUris;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.util.Log;
import com.example.musicplayer.R;
import com.example.musicplayer.constant.MyApplication;
import com.example.musicplayer.entiy.Mp3Info;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by on 2018/10/22.
*/
public class MediaUtil {
//获取专辑封面的Uri
private static final String TAG="MediaUtil";
private static final Uri albumArtUri = Uri.parse("content://media/external/audio/albumart");
public static List<Mp3Info> getMp3Info() {
List<Mp3Info> mp3InfoList = new ArrayList<>();
Cursor cursor = MyApplication.getContext().getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToNext();
Mp3Info mp3Info = new Mp3Info();
long id = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media._ID)); //音乐id
String title = cursor.getString((cursor
.getColumnIndex(MediaStore.Audio.Media.TITLE)));//音乐标题
String artist = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.ARTIST));//艺术家
long duration = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media.DURATION));//时长
long size = cursor.getLong(cursor
.getColumnIndex(MediaStore.Audio.Media.SIZE)); //文件大小
long albumId = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
String url = cursor.getString(cursor
.getColumnIndex(MediaStore.Audio.Media.DATA)); //文件路径
int isMusic = cursor.getInt(cursor
.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));//是否为音乐
if (isMusic != 0) {//只把音乐添加到集合当中
if (size > 1000 * 800) {
// 注释部分是切割标题,分离出歌曲名和歌手 (本地媒体库读取的歌曲信息不规范)
if (title.contains("-")) {
String[] str = title.split("-");
artist = str[0];
title = str[1];
}
mp3Info.setTitle(title.trim());
mp3Info.setArtist(artist);
mp3Info.setDuration(duration);
mp3Info.setSize(size);
mp3Info.setUrl(url);
mp3Info.setAlbumId(albumId);
mp3Info.setId(id);
mp3InfoList.add(mp3Info);
}
}
}
cursor.close();
return mp3InfoList;
}
//
public static Bitmap getMusicBitmap(Context context, long songid,
long albumid) {
Bitmap bm = null;
// 专辑id和歌曲id小于0说明没有专辑、歌曲并抛出异常
if (albumid < 0 && songid < 0) {
throw new IllegalArgumentException(
"Must specify an album or a song id");
}
try {
if (albumid < 0) {
Uri uri = Uri.parse("content://media/external/audio/media/"
+ songid + "/albumart");
ParcelFileDescriptor pfd = context.getContentResolver()
.openFileDescriptor(uri, "r");
if (pfd != null) {
FileDescriptor fd = pfd.getFileDescriptor();
Log.d(TAG, "getMusicBitmap: songId");
bm = BitmapFactory.decodeFileDescriptor(fd);
}
} else {
Uri uri = ContentUris.withAppendedId(albumArtUri, albumid);
ParcelFileDescriptor pfd = context.getContentResolver()
.openFileDescriptor(uri, "r");
if (pfd != null) {
FileDescriptor fd = pfd.getFileDescriptor();
bm = BitmapFactory.decodeFileDescriptor(fd);
} else {
return null;
}
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
//如果获取的bitmap为空则返回一个默认的bitmap
if (bm == null) {
Resources resources = context.getResources();
Drawable drawable = resources.getDrawable(R.drawable.background);
//Drawable 转 Bitmap
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
bm = bitmapDrawable.getBitmap();
}
return Bitmap.createScaledBitmap(bm, 150, 150, true);
}
// public static Bitmap getDefaultArtwork(Context context, boolean small) {
//
// return (Bitmap) BitmapFactory.decodeResource(context.getResources(), R.drawable.background);
// }
//
// /**
// * 从文件当中获取专辑封面位图
// * * @param context
// * * @param songid
// * * @param albumid
// * * @return
// */
// private static Bitmap getArtworkFromFile(Context context, long songid, long albumid) {
// Bitmap bm = null;
// if (albumid < 0) {
// throw new IllegalArgumentException("Must specify an album or a song id");
// }
// try {
// BitmapFactory.Options options = new BitmapFactory.Options();
// FileDescriptor fd = null;
// if (albumid < 0) {
// Uri uri = Uri.parse("content://media/external/audio/media/" + songid + "/albumart");
// ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
// if (pfd != null) {
// fd = pfd.getFileDescriptor();
// }
// } else {
// Uri uri = ContentUris.withAppendedId(albumArtUri, albumid);
// ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
// if (pfd != null) {
// fd = pfd.getFileDescriptor();
// }
// }
// options.inSampleSize = 1; // 只进行大小判断
// options.inJustDecodeBounds = true;
// // 调用此方法得到options得到图片大小
// BitmapFactory.decodeFileDescriptor(fd, null, options);
// //我们的目标是在800pixel的画面上显示
// // 所以需要调用computeSampleSize得到图片缩放的比例
// options.inSampleSize = 100;
// //我们得到了缩放的比例现在开始正式读入Bitmap数据
// options.inJustDecodeBounds = false;
// options.inDither = false;
// options.inPreferredConfig = Bitmap.Config.ARGB_8888; //根据options参数减少所需要的内存
// bm = BitmapFactory.decodeFileDescriptor(fd, null, options);
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// }
// return bm;
// }
//
// /**
// * 获取专辑封面位图对象 * @param context * @param song_id * @param album_id * @param allowdefalut * @return
// */
// public static Bitmap getArtwork(Context context, long song_id, long album_id, boolean allowdefalut, boolean small) {
// if (album_id < 0) {
// if (song_id < 0) {
// Bitmap bm = getArtworkFromFile(context, song_id, -1);
// if (bm != null) {
// return bm;
// }
// }
// if (allowdefalut) {
// return getDefaultArtwork(context, small);
// }
// return null;
// }
// ContentResolver res = context.getContentResolver();
// Uri uri = ContentUris.withAppendedId(albumArtUri, album_id);
// if (uri != null) {
// InputStream in = null;
// try {
// in = res.openInputStream(uri);
// BitmapFactory.Options options = new BitmapFactory.Options();
// //先制定原始大小
// options.inSampleSize = 1;
// //只进行大小判断
// options.inJustDecodeBounds = true;
// //调用此方法得到options得到图片的大小
// BitmapFactory.decodeStream(in, null, options);
// /** 我们的目标是在你N pixel的画面上显示。 所以需要调用computeSampleSize得到图片缩放的比例 **/
// /** 这里的target为800是根据默认专辑图片大小决定的800只是测试数字但是试验后发现完美的结合 **/
// if (small) {
// options.inSampleSize = computeSampleSize(options, 40);
// } else {
// options.inSampleSize = computeSampleSize(options, 600);
// }
// // 我们得到了缩放比例现在开始正式读入Bitmap数据
// options.inJustDecodeBounds = false;
// options.inDither = false;
// options.inPreferredConfig = Bitmap.Config.ARGB_8888;
// in = res.openInputStream(uri);
// return BitmapFactory.decodeStream(in, null, options);
// } catch (FileNotFoundException e) {
// Bitmap bm = getArtworkFromFile(context, song_id, album_id);
// if (bm != null) {
// if (bm.getConfig() == null) {
// bm = bm.copy(Bitmap.Config.RGB_565, false);
// if (bm == null && allowdefalut) {
// return getDefaultArtwork(context, small);
// }
// }
// } else if (allowdefalut) {
// bm = getDefaultArtwork(context, small);
// }
// return bm;
// } finally {
// try {
// if (in != null) {
// in.close();
// }
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// }
// return null;
// }
//
// /**
// * 对图片进行合适的缩放 * @param options * @param target * @return
// */
// public static int computeSampleSize(BitmapFactory.Options options, int target) {
// int w = options.outWidth;
// int h = options.outHeight;
// int candidateW = w / target;
// int candidateH = h / target;
// int candidate = Math.max(candidateW, candidateH);
// if (candidate == 0) {
// return 1;
// }
// if (candidate > 1) {
// if ((w > target) && (w / candidate) < target) {
// candidate -= 1;
// }
// }
// if (candidate > 1) {
// if ((h > target) && (h / candidate) < target) {
// candidate -= 1;
// }
// }
// return candidate;
// }
}

@ -1,34 +1,24 @@
package com.example.musicplayer.view;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import com.example.musicplayer.R;
import com.example.musicplayer.adapter.SongAdapter;
import com.example.musicplayer.contract.ILocalMusicContract;
import com.example.musicplayer.entiy.Mp3Info;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.presenter.LocalMusicPresenter;
import com.example.musicplayer.service.PlayerService;
import com.example.musicplayer.util.FileHelper;
@ -36,8 +26,6 @@ import com.example.musicplayer.util.FileHelper;
import java.util.ArrayList;
import java.util.List;
import de.hdodenhof.circleimageview.CircleImageView;
public class LocalMusicFragment extends Fragment implements ILocalMusicContract.View {
private static final String TAG = "LocalFragment";

@ -3,6 +3,7 @@ package com.example.musicplayer.view;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.ActivityOptions;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@ -10,15 +11,13 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ImageView;
@ -30,7 +29,7 @@ import com.example.musicplayer.R;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.service.PlayerService;
import com.example.musicplayer.util.FileHelper;
import com.example.musicplayer.util.MediaUntil;
import com.example.musicplayer.util.MediaUtil;
import de.hdodenhof.circleimageview.CircleImageView;
@ -190,6 +189,16 @@ public class MainActivity extends AppCompatActivity {
}
}
});
//点击播放栏,跳转到播放的主界面
mLinear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent toPlayActivityIntent=new Intent(MainActivity.this,PlayActivity.class);
startActivity(toPlayActivityIntent,
ActivityOptions.makeSceneTransitionAnimation(MainActivity.this).toBundle());
}
});
}
private void addMainFragment() {
@ -236,7 +245,7 @@ public class MainActivity extends AppCompatActivity {
mSongNameTv.setText(mSong.getTitle());
mSingerTv.setText(mSong.getArtist());
mPlayerBtn.setSelected(true);
mCoverIv.setImageBitmap(MediaUntil.getMusicBitemp(MainActivity.this,mSong.getId(),mSong.getAlbumId()));
mCoverIv.setImageBitmap(MediaUtil.getMusicBitmap(MainActivity.this,mSong.getId(),mSong.getAlbumId()));
mCircleAnimator.start();
mSeekBar.setMax((int) mSong.getDuration());
mSeekBarThread = new Thread(new SeekBarThread());

@ -17,6 +17,7 @@ import android.widget.LinearLayout;
import com.example.musicplayer.R;
import com.example.musicplayer.adapter.ExpandableListViewAdapter;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.widget.MyListView;
/**
@ -55,12 +56,7 @@ public class MainFragment extends Fragment {
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (Build.VERSION.SDK_INT >= 22) {
View decorView = getActivity().getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
getActivity().getWindow().setStatusBarColor(Color.TRANSPARENT);
}
CommonUtil.hideStatusBar(getActivity());
mAdapter = new ExpandableListViewAdapter(getActivity(), mGroupStrings, mSongStrings);
myListView.setAdapter(mAdapter);

@ -0,0 +1,101 @@
package com.example.musicplayer.view;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.transition.Slide;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.example.musicplayer.R;
import com.example.musicplayer.base.BaseActivity;
import com.example.musicplayer.contract.IPlayContract;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.presenter.PlayPresenter;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.util.FileHelper;
/**
*
*/
public class PlayActivity extends BaseActivity implements IPlayContract.View {
private String TAG = "PlayActivity";
private Button mPlayBtn;
private Button mLastBtn;
private Button mNextBtn;
private RelativeLayout mPlayRelative;
private PlayPresenter mPresenter;
private boolean isPlaying;
@Override
protected void initViews() {
CommonUtil.hideStatusBar(this);
setContentView(R.layout.activity_play);
//设置进入退出动画
getWindow().setEnterTransition(new Slide());
getWindow().setExitTransition(new Slide());
//与Presenter建立关系
mPresenter = new PlayPresenter();
mPresenter.attachView(this);
mPresenter.getSingerImg(getSingerName());
//
mPlayRelative = findViewById(R.id.relative_play);
mPlayBtn = findViewById(R.id.btn_player);
mLastBtn = findViewById(R.id.btn_last);
mNextBtn = findViewById(R.id.next);
}
@Override
protected void onClick() {
mPlayBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
isPlaying = !isPlaying;
mPlayBtn.setSelected(isPlaying);
}
});
}
@Override
public String getSingerName() {
Song song = FileHelper.getSong();
Log.d(TAG, "getSingerName: " + "-" + song.getArtist().toString() + "-");
return song.getArtist().toString().trim();
}
@Override
public void setSingerImg(String ImgUrl) {
Log.d(TAG, "setSingerImg: success");
SimpleTarget<Drawable> simpleTarget = new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
mPlayRelative.setBackground(resource);
}
};
Glide.with(this)
.load(ImgUrl)
.apply(RequestOptions.placeholderOf(R.drawable.background))
.apply(RequestOptions.errorOf(R.drawable.background))
.into(simpleTarget);
}
@Override
public void setImgFail(String errorMessage) {
CommonUtil.showToast(this, errorMessage);
}
}

@ -16,6 +16,7 @@ import android.widget.Toast;
import com.example.musicplayer.R;
import com.example.musicplayer.adapter.SongAdapter;
import com.example.musicplayer.util.CommonUtil;
public class WelcomeActivity extends AppCompatActivity {
@ -23,12 +24,7 @@ public class WelcomeActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(Build.VERSION.SDK_INT>=22){
View decorView=getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
CommonUtil.hideStatusBar(this);
setContentView(R.layout.activity_welcome);
//申请权限

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/activity_play_stop"/>
<item android:drawable="@drawable/activity_play_start"/>
</selector>

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relative_play"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
android:fitsSystemWindows="true"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/relative_song"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize">
<ImageView
android:id="@+id/iv_back"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerVertical="true"
android:src="@drawable/back" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginStart="5dp"
android:text="青茫"
android:textColor="@color/white"
android:textSize="18sp" />
</RelativeLayout>
<TextView
android:id="@+id/tv_artist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/relative_song"
android:gravity="center"
android:text="白敬亭、李宏毅、丁冠森、赵文龙"
android:textColor="@color/white" />
<LinearLayout
android:id="@+id/linear"
android:layout_width="match_parent"
android:layout_height="350dp"
android:layout_below="@+id/tv_artist">
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
<RelativeLayout
android:id="@+id/relative_music_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/relative_control"
android:layout_below="@+id/linear"
android:layout_marginEnd="15dp"
android:layout_marginStart="15dp"
android:layout_marginTop="10dp">
<TextView
android:id="@+id/tv_current_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:text="01:34"
android:textColor="@color/white" />
<SeekBar
android:id="@+id/musicSeekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_toEndOf="@id/tv_current_time"
android:layout_toStartOf="@+id/tvTotalTime"
android:paddingEnd="15dp"
android:paddingStart="15dp" />
<TextView
android:id="@+id/tvTotalTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:text="05:34"
android:textColor="@color/white" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/relative_control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="40dp">
<Button
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/playstatus_order"
android:layout_centerVertical="true"
android:layout_marginStart="20dp"/>
<LinearLayout
android:id="@+id/linear_control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:paddingLeft="20dp"
android:paddingRight="20dp">
<Button
android:id="@+id/btn_last"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/activity_play_last" />
<Button
android:id="@+id/btn_player"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginEnd="20dp"
android:layout_marginStart="20dp"
android:background="@drawable/selector_activity_play" />
<Button
android:id="@+id/next"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/activity_play_next" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
Loading…
Cancel
Save