低仿网易云音乐音频播放器!自动获取歌曲封面,并旋转

这个是实习的时候做的了,当时看了半本第一行代码就去上班,Java 都没学过,最后实习走的时候还做了挺多东西,这个音频播放器就是其一,现在写个博客纪念一下上班两年了,虽然还是菜狗程序员!

前言

实习的时候很菜,一直追求使用开源库,这个播放器也用到了几个有名的库,也不算强凑的吧。

  • Glide
  • ButterKnife
  • BaseRecyclerViewAdapterHelper

效果图我也不想放了,很 low,但能用,就自己记录下,如果希望借鉴的话继续看吧!

代码

  • AudioPlayerActivity
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
import com.bumptech.glide.request.RequestOptions;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * 低仿网易云播放器
 * @author :Silence
 * @date:2019/5/21 16:53
 */
@SuppressWarnings("unused")
@SuppressLint("NonConstantResourceId")
public class AudioPlayerActivity extends AppCompatActivity {

    /**
     * 列表循环播放模式
     */
    public static final int PLAY_MOD_LOOP = 0;

    /**
     * 单曲循环播放模式
     */
    public static final int PLAY_MOD_SINGLE = 1;

    /**
     * 随机播放模式
     */
    public static final int PLAY_MOD_RANDOM = 2;

    /**
     * 退出 activity
     */
    @OnClick(R.id.play_audio_back)
    public void backClick(){ finish(); }

    /**
     * 标题
     */
    @BindView(R.id.play_audio_title)
    TextView textTitle;

    /**
     * 中心图片 ImageView,可以获取到音乐的封面放这,靠Glide加载,及属性动画转起来
     */
    @BindView(R.id.play_audio_center)
    ImageView imageCenter;

    /**
     * 上一首
     */
    @BindView(R.id.last_audio)
    ImageView lastAudio;
    @OnClick(R.id.last_audio)
    public void last(){
        switch (playbackMode){
            case PLAY_MOD_LOOP:
            case PLAY_MOD_SINGLE:
                nowPosition--;
                if (nowPosition < 0) {
                    //跳转循环
                    nowPosition = mediaItems.size() - 1;
                }
                //播放
                startPlay();

                //选中歌曲变色
                audioAdapter.setSelect(nowPosition);
                audioAdapter.notifyDataSetChanged();
                break;
            case PLAY_MOD_RANDOM:
                nowPosition = (int) (Math.random()*mediaItems.size());
                startPlay();

                //选中歌曲变色
                audioAdapter.setSelect(nowPosition);
                audioAdapter.notifyDataSetChanged();
                break;
            default:
        }
    }

    /**
     * 播放或者暂停
     */
    @BindView(R.id.startOrPause)
    ImageView startOrPause;
    @OnClick(R.id.startOrPause)
    public void pause(){
        if (mediaPlayer.isPlaying()) {
            //中间图片暂停旋转
            mAnimator.pause();

            mediaPlayer.pause();
            startOrPause.setImageResource(R.drawable.ic_pic_pause);
        } else {
            //中间图片继续旋转
            mAnimator.resume();

            mediaPlayer.start();
            startOrPause.setImageResource(R.drawable.ic_pic_play);
        }
    }

    /**
     * 下一首
     */
    @BindView(R.id.next_audio)
    ImageView nextAudio;
    @OnClick(R.id.next_audio)
    public void next(){
        switch (playbackMode){
            case PLAY_MOD_LOOP:
            case PLAY_MOD_SINGLE:
                nowPosition++;
                //跳转循环
                if (nowPosition > (mediaItems.size() - 1)) {
                    nowPosition = 0;
                }

                //播放
                startPlay();

                //选中歌曲变色
                audioAdapter.setSelect(nowPosition);
                audioAdapter.notifyDataSetChanged();
                break;
            case PLAY_MOD_RANDOM:
                //随机
                nowPosition = (int) (Math.random()*mediaItems.size());
                startPlay();

                //选中歌曲变色
                audioAdapter.setSelect(nowPosition);
                audioAdapter.notifyDataSetChanged();
                break;
            default:
        }
    }

    /**
     * 进度条
     */
    @BindView(R.id.seekBar)
    SeekBar seekBar;

    /**
     * 歌曲时间
     */
    @BindView(R.id.audio_time)
    TextView textTime;

    /**
     * 播放模式,点击来回切换
     */
    @BindView(R.id.playMode)
    ImageView playMode;
    @OnClick(R.id.playMode)
    public void playMode(){
        switch (playbackMode){
            case PLAY_MOD_LOOP:
                playbackMode = 1;
                playMode.setImageResource(R.drawable.pic_playmod_signle);
                break;
            case PLAY_MOD_SINGLE:
                playbackMode = 2;
                playMode.setImageResource(R.drawable.pic_playmod_random);
                break;
            case PLAY_MOD_RANDOM:
                playbackMode = 0;
                playMode.setImageResource(R.drawable.pic_playmod_loop);
                break;
            default:
        }
    }

    /**
     * 列表相关,仅文字列表,但和音频对应
     */
    @BindView(R.id.audioList)
    RecyclerView audioList;
    AudioPlayListAdapter audioAdapter;
    List<String> data = new ArrayList<>();

    /**
     * 是否是网络资源
     */
    boolean isNet = true;

    /**
     * 音频链接
     */
    String link;

    /**
     * 列表中正在播放的位置
     */
    private int nowPosition = 0;

    /**
     * 播放模式
     */
    private int playbackMode = 0;

    /**
     * 音频列表
     */
    List<Audio> mediaItems = new ArrayList<>();

    /**
     * 音频播放器
     */
    MediaPlayer mediaPlayer;

    /**
     * 封面图片
     */
    Bitmap albumBitmap;

    /**
     * 旋转动画
     */
    ObjectAnimator mAnimator;

    /**
     * 处理 seekBar进度的重置和更新,要注意内存泄漏
     */
    @SuppressLint("HandlerLeak")
    Handler handler = new Handler(){
        @SuppressLint("SetTextI18n")
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 0) {
                //得到当前进度
                int currentPosition = mediaPlayer.getCurrentPosition();
                int duration = mediaPlayer.getDuration();
                seekBar.setMax(duration);

                //设置seekBar的进度
                seekBar.setProgress(currentPosition);
                textTime.setText(formatSeconds(currentPosition / 1000)
                        + "/" + formatSeconds(duration / 1000));

                //定时更新,1秒
                removeMessages(0);
                sendEmptyMessageDelayed(0, 1000);
            }
        }
    };


    /**
     * 转换秒值为字符串
     * @param seconds 秒
     * @return 时分秒字符串
     */
    private String formatSeconds(long seconds) {
        int temp;
        StringBuilder sb = new StringBuilder();
        if (seconds > 3600) {
            //时
            temp = (int) (seconds / 3600);
            sb.append((seconds / 3600) < 10 ? "0" + temp + ":" : temp + ":");
        }

        //分
        temp = (int) (seconds % 3600 / 60);
        sb.append((temp < 10) ? "0" + temp + ":" : "" + temp + ":");

        //秒
        temp = (int) (seconds % 3600 % 60);
        sb.append((temp < 10) ? "0" + temp : "" + temp);

        return sb.toString();
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.component_audio);
        //全屏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        ButterKnife.bind(this);

        init();

        //获取intent数据
        getIntentData();

        //启动播放
        startPlay();

        //设置歌曲列表适配器
        initAdapter();
    }


    private void init(){

        mediaPlayer = new MediaPlayer();

        //将 seekBar和播放器联系起来
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                if (b) { mediaPlayer.seekTo(i); } }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) { }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) { }
        });
    }

    /**
     * 旋转图片
     */
    private void rotateImage() {

        //旋转动画
        mAnimator = ObjectAnimator.ofFloat(imageCenter, "rotation", 0.0f, 360.0f);

        //设定转一圈的时间
        mAnimator.setDuration(20000);
        //设定无限循环
        mAnimator.setRepeatCount(Animation.INFINITE);
        // 循环模式
        mAnimator.setRepeatMode(ObjectAnimator.RESTART);
        // 匀速
        mAnimator.setInterpolator(new LinearInterpolator());

        //开始动画
        mAnimator.start();
    }


    private void getIntentData(){
        Intent intent = getIntent();
        isNet = intent.getBooleanExtra("isNet",false);
        if(isNet) {
            //网络链接
            link = intent.getStringExtra("link");
        }else {
            if(null != intent.getExtras()) {
                //noinspection unchecked
                mediaItems = (List<Audio>) intent.getExtras().getSerializable("audioList");
            }

            //传入播放音乐在列表中位置
            nowPosition = intent.getIntExtra("position", 0);
        }
    }

    private void initAdapter() {
        audioList.setHasFixedSize(true);
        audioList.setLayoutManager(new LinearLayoutManager(this));

        //从音频列表中获取音频文件列表
        for (Audio audio : mediaItems){
            data.add(audio.getName());
        }

        //创建列表适配器
        audioAdapter = new AudioPlayListAdapter(R.layout.item_text_singleline,data);
        //选中项
        audioAdapter.setSelect(nowPosition);
        //列表为空时布局
        audioAdapter.setEmptyView(R.layout.view_empty_file, (ViewGroup) audioList.getParent());
        //单击列表项切换音频
        audioAdapter.setOnItemClickListener((adapter, view, position) -> {
            audioAdapter.setSelect(nowPosition);
            audioAdapter.notifyDataSetChanged();
            nowPosition = position;
            startPlay();
        });
        audioList.setAdapter(audioAdapter);
    }

    private void startPlay() {
        // 释放之前音频
        if (mediaPlayer != null) {
            mediaPlayer.reset();
        }

        try {
            assert mediaPlayer != null;
            mediaPlayer.setDataSource(AudioPlayerActivity.this, Uri.parse(link));
            mediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (isNet){

            //解码
            mediaPlayer.setOnPreparedListener(mediaPlayer -> {
                mediaPlayer.start();
                //加载默认图片
                albumBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
                Glide.with(AudioPlayerActivity.this).load(albumBitmap)
                        .apply(RequestOptions.bitmapTransform(new CircleCrop()))
                        .skipMemoryCache(true)                     // 不使用内存缓存
                        .diskCacheStrategy(DiskCacheStrategy.NONE) // 不使用磁盘缓存
                        .into(imageCenter);
                handler.sendEmptyMessage(0);
            });

            //播放完成监听
            mediaPlayer.setOnCompletionListener(mediaPlayer -> finish());

            mediaPlayer.setOnErrorListener((mediaPlayer, i, i1) -> {
                Toast.makeText(AudioPlayerActivity.this,"播放出错了",Toast.LENGTH_SHORT).show();
                finish();
                return true;
            });

            //网络资源关闭上下曲和播放模式
            lastAudio.setVisibility(View.GONE);
            nextAudio.setVisibility(View.GONE);
            playMode.setVisibility(View.GONE);
        }else{
            //设置标题为音频文件名
            textTitle.setText(mediaItems.get(nowPosition).getName());

            //解码
            mediaPlayer.setOnPreparedListener(mediaPlayer -> {
                mediaPlayer.start();
                //获取专辑封面图片
                albumBitmap = MediaUtiles.getArtwork(AudioPlayerActivity.this,
                        mediaItems.get(nowPosition).getAudioId(),
                        mediaItems.get(nowPosition).getAlbumId(),true,false);

                Glide.with(AudioPlayerActivity.this).load(albumBitmap)
                        .apply(RequestOptions.bitmapTransform(new CircleCrop()))
                        .skipMemoryCache(true)                     // 不使用内存缓存
                        .diskCacheStrategy(DiskCacheStrategy.NONE) // 不使用磁盘缓存
                        .into(imageCenter);

                handler.sendEmptyMessage(0);
            });

            //播放完成监听
            mediaPlayer.setOnCompletionListener(mediaPlayer -> next());

            mediaPlayer.setOnErrorListener((mediaPlayer, i, i1) -> {
                Toast.makeText(AudioPlayerActivity.this,"播放出错了",Toast.LENGTH_SHORT).show();
                next();
                return true;
            });

            //本地播放有循环模式
            mediaPlayer.setLooping((playbackMode == PLAY_MOD_LOOP));
        }

        //旋转中间图片
        rotateImage();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mediaPlayer.pause();
    }

    @Override
    protected void onDestroy() {
        mediaPlayer.stop();
        mediaPlayer.release();
        handler.removeCallbacksAndMessages(null);
        super.onDestroy();
    }
}

这里就是一个 activity,记得在 manifest 里面注册。最烦那些放代码不给引入库的,这个全给了吧,还有几个用到的类,下面写。

  • XML 布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/whitesmoke"
    android:orientation="vertical">
    <RelativeLayout
        android:background="@color/gray"
        android:layout_width="match_parent"
        android:layout_height="40dp">
        <ImageView
            android:id="@+id/play_audio_back"
            android:layout_alignParentStart="true"
            android:layout_marginStart="10dp"
            android:scaleType="centerCrop"
            android:src="@drawable/ic_pic_back"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" />
        <TextView
            android:id="@+id/play_audio_title"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:text="音频播放" />
    </RelativeLayout>
    <ImageView
        android:id="@+id/play_audio_center"
        android:layout_centerInParent="true"
        android:src="@drawable/pic_audio_default"
        android:layout_width="200dp"
        android:layout_height="200dp" />
    <LinearLayout
        android:background="@color/colorGray"
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:gravity="center"
        android:layout_height="50dp">
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent">
            <ImageView
                android:id="@+id/last_audio"
                android:layout_width="40dp"
                android:layout_margin="5dp"
                android:padding="5dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_pic_previous"/>

            <ImageView
                android:id="@+id/startOrPause"
                android:layout_width="40dp"
                android:layout_margin="5dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_pic_pause"/>
            <ImageView
                android:id="@+id/next_audio"
                android:layout_width="40dp"
                android:padding="5dp"
                android:layout_margin="5dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_pic_next"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="0dp"
            android:layout_weight="1"
            android:gravity="center"
            android:layout_marginEnd="3dp"
            android:layout_height="match_parent">
            <SeekBar
                android:id="@+id/seekBar"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="match_parent" />
            <TextView
                android:id="@+id/audio_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#ffffff"
                android:textSize="18sp"
                android:text="00:00/00:00"/>
        </LinearLayout>
        <ImageView
            android:id="@+id/playMode"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_marginStart="10dp"
            android:layout_marginEnd="10dp"
            android:src="@drawable/pic_playmod_loop"/>
    </LinearLayout>
    <android.support.v7.widget.RecyclerView
        android:id="@+id/audioList"
        android:layout_alignParentEnd="true"
        android:layout_marginTop="40dp"
        android:layout_marginBottom="50dp"
        android:layout_width="200dp"
        android:layout_height="match_parent"/>
</RelativeLayout>

图标、颜色、toolbar如果要用的话,自己改改吧,原谅我之前的菜!

  • Audio
public class Audio implements Serializable {
    private String name;
    private Long duration;
    private Long size;
    private String address;
    private String artist;

    private Long audioId;
    private Long albumId;

    public Audio(String name, Long duration, Long size, String address, String artist) {
        this.name = name;
        this.duration = duration;
        this.size = size;
        this.address = address;
        this.artist = artist;

        this.audioId = -1L;
        this.albumId = -1L;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getDuration() {
        return duration;
    }

    public void setDuration(Long duration) {
        this.duration = duration;
    }

    public Long getSize() {
        return size;
    }

    public void setSize(Long size) {
        this.size = size;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getArtist() {
        return artist;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }

    public Long getAudioId() {
        return audioId;
    }

    public void setAudioId(Long audioId) {
        this.audioId = audioId;
    }

    public Long getAlbumId() {
        return albumId;
    }

    public void setAlbumId(Long albumId) {
        this.albumId = albumId;
    }
}

这个是本地音频的类,用的 Serializable,偷懒了,虽然我当时都不知道序列化有什么用,更不要说泛型了。

  • 适配器
import android.graphics.Color;
import android.support.annotation.Nullable;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;

import java.util.List;

public class AudioPlayListAdapter extends BaseQuickAdapter<String, BaseViewHolder> {

    private int select = 0;

    public AudioPlayListAdapter(int layoutResId, @Nullable List<String> data) {
        super(layoutResId, data);
    }

    @Override
    protected void convert(BaseViewHolder helper, String item) {
        helper.setText(R.id.item_text_singleline, item);
        //标记选中项
        if (helper.getLayoutPosition() == select){
            helper.setTextColor(R.id.item_text_singleline, Color.parseColor("#4caf50"));
        }else {
            helper.setTextColor(R.id.item_text_singleline, Color.parseColor("#8A8A8A"));
        }
    }

    public void setSelect(int select) {
        this.select = select;
    }
}

这里用到了 BARVH 里面的类,item_text_singleline 这个可以用 android 自带的单行布局,省的写了。

  • 获取音频封面工具类
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.ParcelFileDescriptor;

import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class MediaUtiles {
    private static final Uri albumArtUri = Uri.parse("content://media/external/audio/albumart");
    /**
     * 获取默认专辑图片
     */
    public static Bitmap getDefaultArtwork(Context context, boolean small) {
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inPreferredConfig = Bitmap.Config.RGB_565;
        if(small){  //返回小图片
            return BitmapFactory.decodeResource(context.getResources(), R.drawable.pic_audio_default);
        }
        return BitmapFactory.decodeResource(context.getResources(), R.drawable.pic_audio_default);
    }


    /**
     * 从文件当中获取专辑封面位图
     */
    private static Bitmap getArtworkFromFile(Context context, long songid, long albumid){
        Bitmap bm = null;
        if(albumid < 0 && songid < 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 = null;
                try {
                    pfd = context.getContentResolver().openFileDescriptor(uri, "r");
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                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;
    }

    /**
     * 获取专辑封面位图对象
     */
    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;
    }

    /**
     * 对图片进行合适的缩放
     */
    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;
    }
}

这里实际上很多音乐都会把海报存到文件里面,获取到像 MP3 就可能拿到里面的封面。

结语

实际上这些代码写的不是很好,ButterKnife 现在用的也不多了,音频播放应该放到 service 里面去的,数据的序列化,布局的适配等都要提高。但是我也是想记录下自己当时有多菜,勉励吧!

end

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值