Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發本地及網絡Mp3音樂播放器(十七)已存在歌曲歌詞下載

Android開發本地及網絡Mp3音樂播放器(十七)已存在歌曲歌詞下載

編輯:關於Android編程

實現功能:

已存在歌曲歌詞下載

後續將博文,將實現已下載音樂掃描功能。

因為,沒有自己的服務器,所以網絡音樂所有相關功能(包含搜索音樂、下載音樂、下載歌詞)均無法保證時效性,建議,盡快下載和練習;如果你下載時候,已經因為我采集的服務器更改規則,請給我留言,如果可以解決,我將在有空的時候獻上新的源碼。

實現效果如圖:

 

\

\

 

實現代碼如下:
PlayActivity如下:

 

package com.iwanghang.drmplayer;

import android.graphics.Bitmap;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;

import com.douzi.android.view.DefaultLrcBuilder;
import com.douzi.android.view.ILrcBuilder;
import com.douzi.android.view.ILrcView;
import com.douzi.android.view.LrcRow;
import com.douzi.android.view.LrcView;
import com.iwanghang.drmplayer.adapter.ViewPagerAdapter;
import com.iwanghang.drmplayer.utils.Constant;
import com.iwanghang.drmplayer.utils.DownloadUtils;
import com.iwanghang.drmplayer.utils.ImageUtils;
import com.iwanghang.drmplayer.utils.MediaUtils;
import com.iwanghang.drmplayer.utils.SearchMusicUtils;
import com.iwanghang.drmplayer.vo.Mp3Info;
import com.lidroid.xutils.db.sqlite.Selector;
import com.lidroid.xutils.exception.DbException;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

import static com.iwanghang.drmplayer.PlayService.ORDER_PLAY;
import static com.iwanghang.drmplayer.PlayService.RANDOM_PLAY;
import static com.iwanghang.drmplayer.PlayService.SINGLE_PLAY;


/**
 * PlayActivity 點擊MyMusicListFragment(本地音樂)底部UI中的專輯封面圖片打開的Activity
 */
public class PlayActivity extends BaseActivity implements OnClickListener, OnSeekBarChangeListener ,OnPageChangeListener {
    private TextView textView2_title;//歌名
    private ImageView imageView1_ablum;//專輯封面圖片
    private SeekBar seekBar1;//進度條
    private TextView textView1_start_time, textView1_end_time;//開始時間,結束時間
    private ImageView imageView1_play_mode;//菜單
    private ImageView imageView3_previous, imageView2_play_pause, imageView1_next;//上一首,播放暫停,下一首
    private ImageView imageView1_ablum_reflection;//專輯封面圖片倒影
    private ImageView imageView1_favorite;//收藏按鈕

    //private ArrayList mp3Infos;
    //private int position;//當前播放的位置
    private boolean isPause = false;//當前播放的是否為暫停狀態
    private static final int UPDATE_TIME = 0x10;//更新播放事件的標記

    private DRMPlayerApp app;//取出全局對象 方便調用

    //歌詞
    private ViewPager viewPager;
    private LrcView lrcView;// 自定義歌詞視圖
    private ArrayList views = new ArrayList<>();
    private static final int UPDATE_LRC = 0x20;//更新播放事件的標記
    ILrcView mLrcView;
    public final static String TAG = "PlayActivity";
    private MediaPlayer mPlayer;
    private ViewPagerAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_music_play);
        //取出全局對象 方便調用
        app = (DRMPlayerApp) getApplication();
        //初始化界面信息
        //textView2_title = (TextView) findViewById(R.id.textView2_title);//歌名
        //imageView1_ablum = (ImageView) findViewById(R.id.imageView1_ablum);//專輯封面圖片
        seekBar1 = (SeekBar) findViewById(R.id.seekBar1);//進度條
        textView1_start_time = (TextView) findViewById(R.id.textView1_start_time);//開始時間
        textView1_end_time = (TextView) findViewById(R.id.textView1_end_time);//結束時間
        imageView1_play_mode = (ImageView) findViewById(R.id.imageView1_play_mode);//菜單
        imageView3_previous = (ImageView) findViewById(R.id.imageView3_previous);//上一首
        imageView2_play_pause = (ImageView) findViewById(R.id.imageView2_play_pause);//播放暫停
        imageView1_next = (ImageView) findViewById(R.id.imageView1_next);//下一首
        imageView1_favorite = (ImageView) findViewById(R.id.imageView1_favorite);//收藏按鈕
        lrcView = (LrcView) findViewById(R.id.lrcView);//自定義歌詞視圖

        //注冊按鈕點擊監聽事件
        imageView1_play_mode.setOnClickListener(this);
        imageView2_play_pause.setOnClickListener(this);
        imageView3_previous.setOnClickListener(this);
        imageView1_next.setOnClickListener(this);
        seekBar1.setOnSeekBarChangeListener(this);
        imageView1_favorite.setOnClickListener(this);


        //mp3Infos = MediaUtils.getMp3Infos(this);
        //bindPlayService();//綁定服務,異步過程,綁定後需要取得相應的值,來更新界面
        myHandler = new MyHandler(this);

        //獨立音樂播放界面 和 歌詞界面
        //viewPager = (ViewPager) findViewById(R.id.fgv_player_main);
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        initViewPager();//初始化
        

        //以下直接調用change()是不行的,因為異步問題,會發生NullPointerException空指針異常
        //從MyMusicListFragment的專輯封面圖片點擊時間傳過來的position(當前播放的位置)
        //position = getIntent().getIntExtra("position",0);
        //change(position);

        //通過在BaseActivity中綁定Service,添加如下代碼實現change()
        //musicUpdatrListener.onChange(playService.getCurrentProgeress());

        //從MyMusicListFragment的專輯封面圖片點擊時間傳過來的isPause(當前播放的是否為暫停狀態)
        //isPause = getIntent().getBooleanExtra("isPause",false);

        //        mLrcView = new LrcView(this, null);
        //        setContentView((View) mLrcView);
        //
        //        //在目標位置讀取lrc文件
        //        File LrcDirFile = new File(Environment.getExternalStorageDirectory() + Constant.DIR_LRC);
        //        System.out.println("LrcDirFile : " + LrcDirFile);
        //        if (!LrcDirFile.exists()) {
        //            LrcDirFile.mkdirs();
        //        }
        //        //把lrc轉成字符串
        //        String lrc = LrcDirFile + "/" + "山丘" + ".lrc";
        //        //Log.d的輸出顏色是藍色的,僅輸出debug調試的意思,但他會輸出上層的信息,過濾起來可以通過DDMS的Logcat標簽來選擇.
        //        Log.d(TAG, "lrc:" + lrc);
        //
        //        //把lrc的字符串 轉成數組
        //        ILrcBuilder builder = new DefaultLrcBuilder();
        //        List rows = builder.getLrcRows(lrc);
        //
        //        //把lrc數組 設置到mLrcView裡
        //        mLrcView.setLrc(rows);
        //        //beginLrcPlay();
        //
        //        //設置監聽器,監聽歌詞滾動
        //        mLrcView.setListener(new ILrcView.LrcViewListener() {
        //            public void onLrcSeeked(int newPosition, LrcRow row) {
        //                if (mPlayer != null) {
        //                    Log.d(TAG, "onLrcSeeked:" + row.time);
        //                    mPlayer.seekTo((int)row.time);//用戶滑動歌詞界面,調整進度
        //                }
        //            }
        //        });
    }


    private void initViewPager() {//專輯封面圖片Pager與歌詞Pager
        //View album_image_layout = getLayoutInflater().inflate(R.layout.album_image_layout, null);
        //System.out.println("PlayActivity.initViewPager.album_image_layout:" + album_image_layout);

        View album_image_layout = LayoutInflater.from(getApplicationContext()).inflate(R.layout.album_image_layout, null);
        System.out.println("PlayActivity.initViewPager.album_image_layout:" + album_image_layout);
        //初始化界面信息

        //textView2_title = (TextView) findViewById(R.id.textView2_title);//歌名
        //這裡要注意下,直接findViewById,返回的是textView2_title是null;像下面這樣,加上layout才可以,否則在change的時候會報空指針異常
        textView2_title = (TextView) album_image_layout.findViewById(R.id.textView2_title);//歌名
        //System.out.println("PlayActivity.initViewPager.textView2_title:" + textView2_title);
        //System.out.println("PlayActivity.initViewPager.textView2_title.getText:" + textView2_title.getText());


        imageView1_ablum = (ImageView) album_image_layout.findViewById(R.id.imageView1_ablum);//專輯封面圖片

        imageView1_ablum_reflection = (ImageView) album_image_layout.findViewById(R.id.imageView1_ablum_reflection);//專輯封面圖片倒影

        views.add(album_image_layout);//添加專輯封面圖片Pager



        //View lrc_layout = getLayoutInflater().inflate(R.layout.lrc_layout, null);


        View lrc_layout = LayoutInflater.from(getApplicationContext()).inflate(R.layout.lrc_layout, null);
        System.out.println("PlayActivity.initViewPager.lrc_layout:" + lrc_layout);



        lrcView = (LrcView) lrc_layout.findViewById(R.id.lrcView);
        //設置滾動事件
        lrcView.setListener(new ILrcView.LrcViewListener() {
            @Override
            public void onLrcSeeked(int newPosition, LrcRow row) {
                if (playService.isPlaying()) {
                    playService.seekTo((int) row.time);
                }
            }
        });
        lrcView.setLoadingTipText("正在加載歌詞......");
        lrcView.setBackgroundResource(R.mipmap.app_splash_bg);
        lrcView.getBackground().setAlpha(150);//背景透明度0-255
        views.add(lrc_layout);
        System.out.println("PlayActivity.initViewPager.views:" + views);



        //adapter = new ViewPagerAdapter(views);
        adapter = new ViewPagerAdapter(views);
        viewPager.setAdapter(adapter);




        //viewPager.setAdapter(new ViewPagerAdapter(views));
        System.out.println("PlayActivity.initViewPager.viewPager:" + viewPager);
        viewPager.addOnPageChangeListener(this);
        System.out.println("PlayActivity.initViewPager.viewPager:" + viewPager);
    }






    //把播放服務的綁定和解綁放在onResume,onPause裡,好處是,每次回到當前Activity就獲取一次播放狀態
    @Override
    protected void onResume() {
        super.onResume();
        bindPlayService();//綁定服務
    }

    @Override
    protected void onPause() {
        super.onPause();
        unbindPlayService();//解綁服務
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindPlayService();//解綁服務
    }

    //Handler用於更新已經播放時間
    private static MyHandler myHandler;

    //進度條改變 (fromUser 是否來自用戶的改變 , 而不是程序自身控制的改變)
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (fromUser) {
            //playService.pause();//暫停
            playService.seekTo(progress);//尋找指定的時間位置 (跳到某個時間點進行播放)
            //playService.start();//播放
        }
    }

    //進度條開始觸摸
    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    //進度條停止觸摸
    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }

    //頁面滾動
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    //頁面選擇
    @Override
    public void onPageSelected(int position) {

    }

    //頁面滾動狀態改變
    @Override
    public void onPageScrollStateChanged(int state) {

    }


    static class MyHandler extends Handler {
        private PlayActivity playActivity;
        private WeakReference weak;//弱引用

        public MyHandler(PlayActivity playActivity) {
            //this.playActivity = playActivity;
            weak = new WeakReference(playActivity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //System.out.println("PlayActivity.MyHandler.weak = " + weak);
            playActivity = weak.get();
            //System.out.println("PlayActivity.MyHandler.playActivity = " + playActivity);
            if (playActivity != null) {
                switch (msg.what) {
                    case UPDATE_TIME://更新時間(已經播放時間)
                        playActivity.textView1_start_time.setText(MediaUtils.formatTime((int) msg.obj));
                        break;
                    case UPDATE_LRC:
                        playActivity.lrcView.seekLrcToTime((int) msg.obj);
                        break;
                    default:
                        break;
                }
            }
        }
    }

    @Override
    public void publish(int progress) {
        //以下是是直接調用線程,但是不能這樣做,會報錯,線程異常
        //textView1_start_time.setText(MediaUtils.formatTime(progress));
        //所以,我們需要使用Handler
        //Message msg = myHandler.obtainMessage(UPDATE_TIME);//用於更新已經播放時間
        //msg.arg1 = progress;//用於更新已經播放時間
        //myHandler.sendMessage(msg);//用於更新已經播放時間

        //seekBar1.setProgress(progress);

        myHandler.obtainMessage(UPDATE_TIME, progress).sendToTarget();
        seekBar1.setProgress(progress);
        myHandler.obtainMessage(UPDATE_LRC, progress).sendToTarget();
        //System.out.println("PlayActivity.publish.myHandler = " + myHandler);
        //System.out.println("PlayActivity.publish.UPDATE_LRC = " + UPDATE_LRC);
        //System.out.println("PlayActivity.publish.progress = " + progress);
    }

    @Override
    public void change(int position) {//初始化,獨立播放界面的歌曲切換後的初始化界面上的歌曲信息
        //if (this.playService.isPlaying()) {//獲取是否為播放狀態
        //System.out.println("PlayActivity.change.position = " + position);
        Mp3Info mp3Info = playService.mp3Infos.get(position);
        //System.out.println("PlayActivity.change.getTitle = " + mp3Info.getTitle());
        textView2_title.setText(mp3Info.getTitle());//設置歌名
        //textView2_title.setTtileText(mp3Info.getTitle());//設置歌名
        //System.out.println("PlayActivity.change.textView2_title = " + textView2_title);
        //System.out.println("PlayActivity.change.getText : " + textView2_title.getText());
        //System.out.println("PlayActivity.change.getText : " + textView2_title.getTtileText());


        //下面這句話是提交更新UI的,但是這個功能在adapter裡面實現了,但是實現的方式,只適合UI需要更新的內容很少的時候
        //而且,就算使用,也是設置了專輯圖片和倒影,以後使用,不是這裡.
        //之所以放在這裡,是因為我開始調試的時候,無法setText,最後通過Debug找到了問題所在
        //以後我會專門開個博文,介紹一下Debug
        //adapter.notifyDataSetChanged();

        //setText後,歌名沒有顯示,但是可以getText,嘗試隱藏/顯示,來刷新UI,結果歌名還是沒有顯示
        //viewPager.setVisibility(View.GONE);
        //getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.activity_music_play);
        //viewPager.setVisibility(View.VISIBLE);

        //setText後,歌名沒有顯示,但是可以getText,嘗試隱藏/顯示,來刷新UI,結果歌名還是沒有顯示
        //viewPager.setVisibility(View.GONE);
        //viewPager.setVisibility(View.VISIBLE);


        //獲取專輯封面圖片
        Bitmap albumBitmap = MediaUtils.getArtwork(this, mp3Info.getId(), mp3Info.getAlbumId(), true, false);
        //改變播放界面專輯封面圖片
        imageView1_ablum.setImageBitmap(albumBitmap);
        textView1_end_time.setText(MediaUtils.formatTime(mp3Info.getDuration()));//設置結束時間
        imageView2_play_pause.setImageResource(R.mipmap.app_music_pause);//設置暫停圖片
        seekBar1.setProgress(0);//設置當前進度為0
        seekBar1.setMax((int) mp3Info.getDuration());//設置進度條最大值為MP3總時間
        if (playService.isPlaying()) {
            imageView2_play_pause.setImageResource(R.mipmap.app_music_pause);
        } else {
            imageView2_play_pause.setImageResource(R.mipmap.app_music_play);
        }

        if (imageView1_ablum != null) {
            imageView1_ablum_reflection.setImageBitmap(ImageUtils.createReflectionBitmapForSingle(albumBitmap));//顯示倒影
        }
        switch (playService.getPlay_mode()) {
            case ORDER_PLAY://順序播放
                imageView1_play_mode.setImageResource(R.mipmap.app_mode_order);
                //imageView2_play_pause.setTag(ORDER_PLAY);
                break;
            case PlayService.RANDOM_PLAY://隨機播放
                imageView1_play_mode.setImageResource(R.mipmap.app_mode_random);
                //imageView2_play_pause.setTag(RANDOM_PLAY);
                break;
            case PlayService.SINGLE_PLAY://單曲循環
                imageView1_play_mode.setImageResource(R.mipmap.app_mode_single);
                //imageView2_play_pause.setTag(SINGLE_PLAY);
                break;
            default:
                break;
        }

        long id = getId(mp3Info);

        //初始化收藏狀態
        try {
            Mp3Info loveMp3Info = app.dbUtils.findFirst(Selector.from(Mp3Info.class).where("mp3InfoId", "=", mp3Info.getMp3InfoId()));//查出歌曲,SQL語句
            System.out.println("初始化收藏狀態" + loveMp3Info);
//            if (loveMp3Info != null) {
//                imageView1_favorite.setImageResource(R.mipmap.app_love_selected);
//            } else {
//                imageView1_favorite.setImageResource(R.mipmap.app_love_unselected);
//            }
            if (loveMp3Info != null) {
                System.out.println("loveMp3Info.getIsLove() = " + loveMp3Info.getIsLove());
                if (loveMp3Info.getIsLove() == 0) {//返回值不為null,且,isLove為0時,也顯示為'未收藏'
                    imageView1_favorite.setImageResource(R.mipmap.app_love_unselected);
                }else {//返回值為null,且,isLove為1時,一定顯示為'已收藏'
                    imageView1_favorite.setImageResource(R.mipmap.app_love_selected);
                }
            } else {//返回值為null,一定顯示為'未收藏'
                imageView1_favorite.setImageResource(R.mipmap.app_love_unselected);
            }
        } catch (DbException e) {
            e.printStackTrace();
        }

        //歌詞
        String songName = mp3Info.getTitle();
        String artistName = mp3Info.getArtist();
        //歌詞功能還不完善,後面會博文,會繼續完善,暫時使用我已經下載好的lrc測試效果.
        //songName = "山丘";//測試用的lrc的歌名
        String lrcPath = Environment.getExternalStorageDirectory() + Constant.DIR_LRC + "/" + songName + ".lrc";
        File lrcFile = new File(lrcPath);
        if (!lrcFile.exists()){
            //下載歌詞
            System.out.println("下載歌詞");
            DownloadUtils.getsInstance().downloadLRC(songName,artistName,myHandler);
            Toast.makeText(PlayActivity.this, "請下次播放本首歌曲時,將顯示歌詞", Toast.LENGTH_SHORT).show();
        }else{
            loadLRC(lrcFile);
        }
    }

    //如果是本地音樂,id就是id;如果是收藏音樂,id則是mp3InfoId
    //提供給 收藏按鈕 點擊事件時 調用.
    private long getId(Mp3Info mp3Info){
        //初始收藏狀態
        long id = 0;
        switch (playService.getChangePlayList()){
            case PlayService.MY_MUSIC_LIST:
                System.out.println("當前為本地列表");
                id = mp3Info.getId();
                System.out.println("id =" + id);
                break;
            case PlayService.LOVE_MUSIC_LIST:
                System.out.println("當前為收藏列表");
                id = mp3Info.getMp3InfoId();
                System.out.println("id =" + id);
                break;
            default:
                break;
        }
        return id;
    }

    //點擊事件
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.imageView2_play_pause: {//播放暫停按鈕
                if (playService.isPlaying()) {//如果是播放狀態
                    imageView2_play_pause.setImageResource(R.mipmap.app_music_play);//設置播放圖片
                    playService.pause();
                } else {
                    if (playService.isPause()) {
                        imageView2_play_pause.setImageResource(R.mipmap.app_music_pause);//設置暫停圖片
                        playService.start();//播放事件
                    } else {
                        //只有打開APP沒有點擊任何歌曲,同時,直接點擊暫停播放按鈕時.才會調用
                        //playService.play(0);

                        //只有打開APP沒有點擊任何歌曲,同時,直接點擊暫停播放按鈕時.才會調用
                        //默認播放的是,在PlayService的onCreate中 恢復狀態值
                        playService.play(playService.getCurrentPosition());
                    }
                }
                break;
            }
            case R.id.imageView1_next: {//下一首按鈕
                playService.next();//下一首
                break;
            }
            case R.id.imageView3_previous: {//上一首按鈕
                playService.prev();//上一首
                break;
            }
            case R.id.imageView1_play_mode: {//循環模式按鈕
                //int mode = (int) imageView1_play_mode.getTag();
                /**
                 * 以下Tosat內容,在strings.xml裡,添加對應代碼
                 *順序播放
                 *隨機播放
                 *單曲循環
                 */
                switch (playService.getPlay_mode()) {
                    case ORDER_PLAY:
                        imageView1_play_mode.setImageResource(R.mipmap.app_mode_random);
                        //imageView1_play_mode.setTag(RANDOM_PLAY);
                        playService.setPlay_mode(RANDOM_PLAY);
                        //Toast.makeText(getApplicationContext(),"隨機播放",Toast.LENGTH_SHORT).show();//這句也可以
                        //Toast.makeText(PlayActivity.this, "隨機播放", Toast.LENGTH_SHORT).show();//這句也可以
                        Toast.makeText(PlayActivity.this, getString(R.string.random_play), Toast.LENGTH_SHORT).show();
                        break;
                    case RANDOM_PLAY:
                        imageView1_play_mode.setImageResource(R.mipmap.app_mode_single);
                        //imageView1_play_mode.setTag(SINGLE_PLAY);
                        playService.setPlay_mode(SINGLE_PLAY);
                        //Toast.makeText(getApplicationContext(),"單曲循環",Toast.LENGTH_SHORT).show();//這句也可以
                        //Toast.makeText(PlayActivity.this, "單曲循環", Toast.LENGTH_SHORT).show();//這句也可以
                        Toast.makeText(PlayActivity.this, getString(R.string.single_play), Toast.LENGTH_SHORT).show();
                        break;
                    case SINGLE_PLAY:
                        imageView1_play_mode.setImageResource(R.mipmap.app_mode_order);
                        //imageView1_play_mode.setTag(ORDER_PLAY);
                        playService.setPlay_mode(ORDER_PLAY);
                        //Toast.makeText(getApplicationContext(),"順序播放",Toast.LENGTH_SHORT).show();//這句也可以
                        //Toast.makeText(PlayActivity.this, "順序播放", Toast.LENGTH_SHORT).show();//這句也可以
                        Toast.makeText(PlayActivity.this, getString(R.string.order_play), Toast.LENGTH_SHORT).show();
                        break;
                }
                break;
            }
            case R.id.imageView1_favorite: {//收藏按鈕  //在vo.Mp3Info裡  private long mp3InfoId;//在收藏音樂時用於保存原始ID
                Mp3Info mp3Info = playService.mp3Infos.get(playService.getCurrentPosition());//查出歌曲
                System.out.println(mp3Info);
                try {
                    Mp3Info loveMp3Info = app.dbUtils.findFirst(Selector.from(Mp3Info.class).where("mp3InfoId","=",getId(mp3Info)));//查出歌曲,SQL語句
                    System.out.println(loveMp3Info);
                    if (loveMp3Info==null){//返回值為null,則一定需要save
                        System.out.println("不在音樂收藏數據庫中 保存音樂數據 原始數據: " + mp3Info);
                        mp3Info.setMp3InfoId(mp3Info.getId());
                        mp3Info.setIsLove(1);
                        System.out.println(mp3Info);
                        app.dbUtils.save(mp3Info);//在音樂收藏數據庫 保存音樂
                        System.out.println("save");
                        imageView1_favorite.setImageResource(R.mipmap.app_love_selected);

                        //以下是:調試使用,保存以後再查一遍
                        loveMp3Info = app.dbUtils.findFirst(Selector.from(Mp3Info.class).where("mp3InfoId","=",getId(mp3Info)));//查出歌曲,SQL語句
                        System.out.println("調試使用,保存以後再查一遍 最新數據: " + loveMp3Info);
                    }else {//返回值不為null,則一定需要update
                        System.out.println("在音樂收藏數據庫中 更新音樂數據 原始數據: " + loveMp3Info);
                        int isLove = loveMp3Info.getIsLove();
                        if (isLove==1){//返回值不為null,且,isLove為1時;設置isLove為0,同時顯示為'未收藏'
                            loveMp3Info.setIsLove(0);
                            imageView1_favorite.setImageResource(R.mipmap.app_love_unselected);
                        }else {//返回值不為null,且,isLove為0時;設置isLove為1,同時顯示為'已收藏'
                            loveMp3Info.setIsLove(1);
                            imageView1_favorite.setImageResource(R.mipmap.app_love_selected);
                        }
                        System.out.println("update");
                        app.dbUtils.update(loveMp3Info,"isLove");//更新loveMp3Info數據

                        //以下是:調試使用,更新以後再查一遍
                        loveMp3Info = app.dbUtils.findFirst(Selector.from(Mp3Info.class).where("mp3InfoId", "=", getId(mp3Info)));//查出歌曲,SQL語句
                        System.out.println("調試使用,更新以後再查一遍 最新數據: " + loveMp3Info);
                    }
                } catch (DbException e) {
                    e.printStackTrace();
                }
                break;
            }
            default:
                break;
        }
    }


    //加載歌詞
    private void loadLRC(File lrcFile){
        StringBuffer buf = new StringBuffer(1024 * 10);
        char[] chars = new char[1024];
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(lrcFile)));
            int len = -1;
            while ((len = in.read(chars)) != -1){
                buf.append(chars,0,len);
            }
            in.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }
        ILrcBuilder builder = new DefaultLrcBuilder();
        List rows = builder.getLrcRows(buf.toString());
        lrcView.setLrc(rows);
        //加載專輯封面圖片為背景的方法(實際使用,發現效果不理想)
        //long id = mp3Info.getMp3InfoId()==0?mp3Info.getId:mp3Info.getMp3InfoId();
        //Bitmap bg = MediaUtils.getArtwork(this, id ,mp3Info.getAlbumId(),false,false);
        //if(bg != null){
        //    lrcView.getBackground(new BitmapDrawable(getResources(),bg));
        //   lrcView.getBackground().setAlpha(120);
        //}
    }

}

package com.iwanghang.drmplayer.utils;

import android.os.Environment;
import android.os.Handler;
import android.os.Message;

import com.iwanghang.drmplayer.vo.SearchResult;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.xml.parsers.ParserConfigurationException;

/**
 * Created by iwanghang on 16/5/3.
 * 網絡音樂下載工具類
 */
public class DownloadUtils {

    private static final String DOWNLOAD_URL = "/download?_o=%2Fsearch%2Fsong";
    private static final int SUCCESS_LRC = 1;//下載歌詞成功
    private static final int FAILED_LRC = 2;//下載歌詞失敗
    private static final int SUCCESS_MP3 = 3;//下載歌曲成功
    private static final int FAILED_MP3 = 4;//下載歌曲失敗
    private static final int GET_MP3_URL = 5;//獲取音樂下載地址成功
    private static final int GET_FAILED_MP3_URL = 6;//獲取音樂下載地址失敗
    private static final int MUSIC_EXISTS = 7;//下載時,音樂已存在




    private static DownloadUtils sInstance;
    private OnDownloadListener mListener;

    private ExecutorService mThreadPool;

    /**
     *設置回調監聽器對象
     * @param mListener
     * @return
     */
    public DownloadUtils setListener(OnDownloadListener mListener){
        this.mListener = mListener;
        return this;
    }

    //獲取下載工具的實例
    public synchronized static DownloadUtils getsInstance(){
        if (sInstance == null){
            try {
                sInstance = new DownloadUtils();
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            }
        }
        return  sInstance;
    }

    /**
     * 下載的具體業務方法
     * @throws ParserConfigurationException
     */
    private DownloadUtils() throws ParserConfigurationException{
        mThreadPool = Executors.newSingleThreadExecutor();
    }

    public void download(final SearchResult searchResult){
        final Handler handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
               switch (msg.what){
                   case SUCCESS_LRC:
                       if (mListener != null) mListener.onDowload(searchResult.getMusicName()+"的歌詞下載成功");
                       break;
                   case FAILED_LRC:
                       if (mListener != null) mListener.onFailed(searchResult.getMusicName()+"的歌詞下載失敗");
                       break;
                   case GET_MP3_URL:
                       System.out.println("GET_MP3_URL:"+msg.obj);
                       downloadMusic(searchResult,(String)msg.obj,this);
                       break;
                   case GET_FAILED_MP3_URL:
                       if (mListener != null) mListener.onFailed(searchResult.getMusicName()+"的MP3下載失敗");
                       break;
                   case SUCCESS_MP3:
                       if (mListener != null) mListener.onDowload(searchResult.getMusicName()+"的MP3已經下載");
                       String url = Constant.MIGU_URL + searchResult.getUrl();
                       System.out.println("download lrc:"+url);
                       downloadLRC(searchResult.getMusicName(),searchResult.getArtist(),this);
                       break;
                   case FAILED_MP3:
                       if (mListener != null) mListener.onFailed(searchResult.getMusicName()+"的MP3下載失敗");
                       break;
                   case MUSIC_EXISTS:
                       if (mListener != null) mListener.onFailed(searchResult.getMusicName()+"已存在");
                       break;
               }
            }
        };
        getDownloadMusicURL(searchResult,handler);
    }

    //獲取下載歌詞的URL
    private void getDownloadLrcURL(final SearchResult searchResult, final Handler handler) {
        mThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                //http://music.baidu.com/search/lrc?key=%E6%9C%89%E5%BF%83%E4%BA%BA%20G.E.M.%E9%82%93%E7%B4%AB%E6%A3%8B
                //"http://music.baidu.com/search/lrc?key=" + 歌名 + " " + 歌手
                //System.out.println("searchResult.getUrl() = " + searchResult.getUrl());
                //String[] aa = searchResult.getUrl().split("/");
                //String sn = aa[5];
                //System.out.println("歌曲編號 = " + sn);

                //從浏覽器復制出來的Url是這樣的,"http://music.baidu.com/search?key=%E6%B2%A1%E6%9C%89";
                //漢字經過utf8編碼,比如 冰雨 == %E5%86%B0%E9%9B%A8;
                //經過測試 獲取頁面 使用"http://music.baidu.com/search?key=冰雨";無法打開正確連接
                //比如使用URLEncoder.encode轉碼,轉為utf8
                //實際使用 獲取頁面 使用"http://music.baidu.com/search?key=%E6%B2%A1%E6%9C%89";
                try {
                    String musicName = URLEncoder.encode(searchResult.getMusicName(), "utf8");
                    String artistName = URLEncoder.encode(searchResult.getArtist(), "utf8");
                    //String url = Constant.BAIDU_LRC_SEARCH_HEAD + searchResult.getMusicName() + " " + searchResult.getArtist();
                    String url = Constant.BAIDU_LRC_SEARCH_HEAD + musicName + "+" + artistName;
                    System.out.println("歌詞下載頁面url = " + url);

                    Document doc = Jsoup.connect(url).userAgent(Constant.USER_AGENT).timeout(6000).get();
                    //System.out.println("歌詞下載頁面 doc : " + doc);

                    Elements lrcUrls = doc.select("span.lyric-action");
                    System.out.println(lrcUrls);

                    for (int i=0;i下載LRC歌詞
                            if (urla.indexOf("'href':'")>0){
                                String[] uu = urla.split("'href':'");
                                System.out.println("uu1 : " + uu[1]);
                                //uu1 : /data2/lrc/14488216/14488216.lrc' }" href="#">下載LRC歌詞
                                String[] uuu = uu[1].split(".lrc");
                                System.out.println("uuu0 : " + uuu[0]);
                                //uuu0 : /data2/lrc/14488216/14488216
                                String result = "http://music.baidu.com" + uuu[0] + ".lrc";
                                System.out.println("result : " + result);
                                //result :  http://music.baidu.com/data2/lrc/14488216/14488216.lrc
                                Message msg = handler.obtainMessage(SUCCESS_LRC,result);
                                msg.sendToTarget();
                                break;
                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    handler.obtainMessage(FAILED_LRC).sendToTarget();
                }

            }
        });
    }


    //獲取下載音樂的URL
    private void getDownloadMusicURL(final SearchResult searchResult, final Handler handler) {
        mThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                //http://music.migu.cn/#/album/1003215276
                //1003215279
                //http://music.migu.cn/order/1003215279/down/self/P2Z3Y12L1N2/3/001002A/1003215279
                System.out.println("searchResult.getUrl() = " + searchResult.getUrl());
                String[] aa = searchResult.getUrl().split("/");
                String sn = aa[5];
                System.out.println("歌曲編號 = " + sn);
                String url = Constant.MIGU_DOWN_HEAD + sn + Constant.MIGU_DOWN_FOOT;
                System.out.println("歌曲下載頁面url = " + url);

                try {
                    Document doc = Jsoup.connect(url).userAgent(Constant.USER_AGENT).timeout(6000).get();
                    //System.out.println(doc);

                    System.out.println("doc.toString() = " + doc.toString());
                    String[] bb = doc.toString().split("song");//把 下載頁面源碼 按照"song"分割
                    for (int i=0;i0){
                            System.out.println("mp3?msisdn = " + bb[i]);
                            String initMp3Url = bb[i];//initMp3Url 初始Mp3下載鏈接,如下
                            //mp3?msisdn = ":"http://tyst.migu.cn/public/ringmaker01/10月31日中文延期/文件/全套格式/9000首/全曲試聽/Mp3_128_44_16/一起走過的日子-劉德華.mp3?msisdn\u003d7b609763f0ff","

                            String[] arrayHttp = initMp3Url.split("http");//把 初始Mp3下載鏈接 按照"http"分割
                            String[] arrayMp3 = arrayHttp[1].split(".mp3");//把 arrayHttp 按照".mp3"分割
                            String result = "http" + arrayMp3[0] + ".mp3";//把分割去掉的"http"和".mp3",組合回來
                            System.out.println("result");

                            //String result = "http://tyst.migu.cn/public/ringmaker01/10月31日中文延期/文件/全套格式/9000首/全曲試聽/Mp3_128_44_16/一起走過的日子-劉德華.mp3";
                            Message msg = handler.obtainMessage(GET_MP3_URL,result);
                            msg.sendToTarget();
                        }
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                    handler.obtainMessage(GET_FAILED_MP3_URL).sendToTarget();
                }
            }
        });
    }


    //下載歌詞
    public void downloadLRC(final String musicName, final String artistName, final Handler handler){
        mThreadPool.execute(new Runnable() {
            @Override
            public void run() {


                //從浏覽器復制出來的Url是這樣的,"http://music.baidu.com/search?key=%E6%B2%A1%E6%9C%89";
                //漢字經過utf8編碼,比如 冰雨 == %E5%86%B0%E9%9B%A8;
                //經過測試 獲取頁面 使用"http://music.baidu.com/search?key=冰雨";無法打開正確連接
                //比如使用URLEncoder.encode轉碼,轉為utf8
                //實際使用 獲取頁面 使用"http://music.baidu.com/search?key=%E6%B2%A1%E6%9C%89";
                try {
                    String musicNameEn = URLEncoder.encode(musicName, "utf8");
                    String artistNameEn = URLEncoder.encode(artistName, "utf8");
                    //String url = Constant.BAIDU_LRC_SEARCH_HEAD + searchResult.getMusicName() + " " + searchResult.getArtist();
                    String url = Constant.BAIDU_LRC_SEARCH_HEAD + musicNameEn + "+" + artistNameEn;
                    System.out.println("歌詞下載頁面url = " + url);

                    Document doc = Jsoup.connect(url).userAgent(Constant.USER_AGENT).timeout(6000).get();
                    //System.out.println("歌詞下載頁面 doc : " + doc);

                    Elements lrcUrls = doc.select("span.lyric-action");
                    System.out.println(lrcUrls);

                    for (int i = 0; i < lrcUrls.size(); i++) {
                        Elements urlsa = lrcUrls.get(i).getElementsByTag("a");
                        System.out.println("tag a urlsa : " + urlsa);
                        for (int a = 0; a < urlsa.size(); a++) {
                            //System.out.println("----" + urlsa.get(a).toString());
                            String urla = urlsa.get(a).toString();
                            System.out.println("-----" + urla);
                            //-----下載LRC歌詞
                            if (urla.indexOf("'href':'") > 0) {
                                String[] uu = urla.split("'href':'");
                                System.out.println("uu1 : " + uu[1]);
                                //uu1 : /data2/lrc/14488216/14488216.lrc' }" href="#">下載LRC歌詞
                                String[] uuu = uu[1].split(".lrc'");
                                System.out.println("uuu0 : " + uuu[0]);
                                //uuu0 : /data2/lrc/246970367/246970367.lrc
                                String lrcDwonUrl = "http://music.baidu.com" + uuu[0] + ".lrc";
                                System.out.println("lrcDwonUrl : " + lrcDwonUrl);
                                //result :  http://music.baidu.com/data2/lrc/14488216/14488216.lrc


                                File LrcDirFile = new File(Environment.getExternalStorageDirectory() + Constant.DIR_LRC);
                                System.out.println("LrcDirFile : " + LrcDirFile);
                                if (!LrcDirFile.exists()) {
                                    LrcDirFile.mkdirs();
                                }
                                String target = LrcDirFile + "/" + musicName + ".lrc";
                                System.out.println("lrcDwonUrl : " + lrcDwonUrl);
                                System.out.println("target : " + target);
                                File fileTarget = new File(target);
                                if (fileTarget.exists()) {
                                    handler.obtainMessage(MUSIC_EXISTS).sendToTarget();
                                    return;
                                } else {
                                    OkHttpClient client = new OkHttpClient();
                                    Request request = new Request.Builder().url(lrcDwonUrl).build();
                                    Response response = client.newCall(request).execute();
                                    if (response.isSuccessful()) {
                                        PrintStream ps = new PrintStream(new File(target));
                                        byte[] bytes = response.body().bytes();
                                        ps.write(bytes, 0, bytes.length);
                                        ps.close();
                                        handler.obtainMessage(SUCCESS_LRC, target).sendToTarget();
                                    }
                                }
                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        });
    }


    //下載MP3
    private void downloadMusic(final SearchResult searchResult,final String url,final Handler handler){
        mThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                File musicDirFile = new File(Environment.getExternalStorageDirectory()+Constant.DIR_MUSIC);
                if (!musicDirFile.exists()){
                    musicDirFile.mkdirs();
                }

                String mp3url = url;
                //String mp3url = "http://tyst.migu.cn/public/600902-2008430/tone/2008/09/10/2008年9月/4月環球106首歌曲/彩鈴/7_mp3-128kbps/等你等到我心痛-張學友.mp3";

                String target = musicDirFile + "/" + searchResult.getMusicName() + ".mp3";
                System.out.println(mp3url);
                System.out.println(target);
                File fileTarget = new File(target);
                if (fileTarget.exists()){
                    handler.obtainMessage(MUSIC_EXISTS).sendToTarget();
                    return;
                }else {
                    //使用OkHttpClient組件
                    OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder().url(mp3url).build();
                    System.out.println(request);
                    try {
                        Response response = client.newCall(request).execute();
                        if (response.isSuccessful()){
                            PrintStream ps = new PrintStream(fileTarget);
                            byte[] bytes = response.body().bytes();
                            ps.write(bytes,0,bytes.length);
                            ps.close();
                            handler.obtainMessage(SUCCESS_MP3).sendToTarget();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        handler.obtainMessage(FAILED_MP3).sendToTarget();
                    }
                }
            }
        });
    }

    //自定義下載事件監聽器
    public interface OnDownloadListener {
        public void onDowload(String mp3Url);
        public void onFailed(String error);
    }
}


 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved