Android开发本地及网络Mp3音乐播放器(十三)网络音乐搜索功能实现,歌名歌手专辑名搜索

转载请注明出处:http://blog.csdn.net/iwanghang/article/details/51298411


觉得博文有用,请点赞,请留言,请关注,谢谢!~

实现功能:
实现网络音乐搜索功能
使用观察者设计模式
使用URLEncoder.encode转码
SearchMusicUtils是重点

截止到目前的源码下载:
http://download.csdn.net/detail/iwanghang/9747505[免积分]
http://download.csdn.net/detail/iwanghang/9507635[1积分]

实现效果如图:



实现代码如下:
NetMusicListFragment如下:
package com.iwanghang.drmplayer;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;


import com.iwanghang.drmplayer.adapter.MyMusicListAdapter;
import com.iwanghang.drmplayer.adapter.NetMusicListAdapter;
import com.iwanghang.drmplayer.utils.AppUtils;
import com.iwanghang.drmplayer.utils.Constant;
import com.iwanghang.drmplayer.utils.SearchMusicUtils;
import com.iwanghang.drmplayer.vo.Mp3Info;
import com.iwanghang.drmplayer.vo.SearchResult;

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

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

public class NetMusicListFragment extends Fragment implements OnItemClickListener,OnClickListener {

    private ListView listView_net_music;

    //private ArrayList<Mp3Info> mp3Infos;

    private LinearLayout load_layout;
    private LinearLayout ll_search_btn_container;//查询按钮的容器
    private LinearLayout ll_search_container;//查询按钮的容器
    private ImageButton ib_search_btn;
    private EditText et_search_content;

    private NetMusicListAdapter netMusicListAdapter;

    //存放 网络音乐 的集合
    private ArrayList<SearchResult> searchResults = new ArrayList<SearchResult>();

    private int page = 1;//搜索音乐的页码

    private MainActivity mainActivity;

    //private boolean isPause = false;//歌曲播放中的暂停状态

    private int position = 0;//当前播放的位置,提供给PlayActivity

    //onAttach(),当fragment被绑定到activity时被调用(Activity会被传入.).
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        //mainActivity = (MainActivity) context;
        mainActivity = (MainActivity) getActivity();
    }

    public static NetMusicListFragment newInstance() {
        NetMusicListFragment net = new NetMusicListFragment();
        return net;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //UI组件初始化
        View view = inflater.inflate(R.layout.net_music_list_layout,null);
        //item
        listView_net_music = (ListView) view.findViewById(R.id.listView_net_music);
        //findViewById
        load_layout = (LinearLayout) view.findViewById(R.id.load_layout);
        ll_search_btn_container = (LinearLayout) view.findViewById(R.id.ll_search_btn_container);
        ll_search_container = (LinearLayout) view.findViewById(R.id.ll_search_container);
        ib_search_btn = (ImageButton) view.findViewById(R.id.ib_search_btn);
        et_search_content = (EditText) view.findViewById(R.id.et_search_content);

        //Item点击事件监听
        listView_net_music.setOnItemClickListener(this);
        //按钮点击事件监听
        ll_search_btn_container.setOnClickListener(this);
        ib_search_btn.setOnClickListener(this);
        loadNetData();//加载网络音乐
        return view;
    }

    private void loadNetData() {
        load_layout.setVisibility(View.VISIBLE);
        //加载网络音乐的异步任务
        new LoadNetDataTask().execute(Constant.BAIDU_URL + Constant.BAIDU_DAYHOT);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.ll_search_btn_container:
                ll_search_btn_container.setVisibility(View.GONE);
                ll_search_container.setVisibility(View.VISIBLE);
                break;
            case R.id.ib_search_btn:
                //搜索事件
                searchMusic();
                break;
        }
    }

    //搜索音乐
    private void searchMusic() {
        //隐藏键盘
        AppUtils.hideInputMethod(et_search_content);
        ll_search_btn_container.setVisibility(View.VISIBLE);
        ll_search_container.setVisibility(View.GONE);
        //获取输入的文字
        String key = et_search_content.getText().toString();
        if (TextUtils.isEmpty(key)){//如果为空,则,Toast提示
            Toast.makeText(mainActivity,"请输入歌手或歌词",Toast.LENGTH_SHORT).show();
            return;
        }
        load_layout.setVisibility(View.VISIBLE);//加载layout效果.显示
        //填充item 使用SearchMusicUtils搜索音乐工具类,并,使用观察者设计模式,自己回调,自己监听
        SearchMusicUtils.getInstance().setListener(new SearchMusicUtils.OnSearchResultListener(){
            @Override
            public void onSearchResult(ArrayList<SearchResult> results) {
                ArrayList<SearchResult> sr = netMusicListAdapter.getSearchResults();
                sr.clear();
                sr.addAll(results);
                netMusicListAdapter.notifyDataSetChanged();//更新网络音乐列表
                load_layout.setVisibility(View.GONE);
            }
        }).search(key,page);
    }

    //加载网络音乐的异步任务
    //Android1.5提供了 工具类 android.os.AsyncTask,它使创建异步任务变得更加简单,不再需要编写任务线程和Handler实例即可完成相同的任务。
    class LoadNetDataTask extends AsyncTask<String,Integer,Integer>{
        //onPreExecute方法用于在执行后台任务前做一些UI操作
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            load_layout.setVisibility(View.VISIBLE);//加载layout.显示
            listView_net_music.setVisibility(View.GONE);//item.隐藏
            searchResults.clear();//搜索结果.清理
        }

        //doInBackground方法内部执行后台任务,不可在此方法内修改UI
        @Override
        protected Integer doInBackground(String... params) {
            String url = params[0];
            try {
                //使用Jsoup组件请求网络,并解析音乐数据
                Document doc = Jsoup.connect(url).userAgent(Constant.USER_AGENT).timeout(6*1000).get();
//</span></span><span class="song-title " style='width: 240px;'><a href="/song/121353608" target="_blank" title="刘珂矣半壶纱" data-film="null">半壶纱</a></span><span class="singer"  style="width: 240px;" >							<span class="author_list" title="刘珂矣">
//<a hidefocus="true" href="/artist/132632388">刘珂矣</a>        	</span>
//</span></span><span class="song-title " style='width: 240px;'><a href="/song/264506450" target="_blank" title="韩磊千年一般若" data-film="null">千年一般若</a><div class="extra-info"><span class="appendix">影视原声</span></div></span><span class="singer"  style="width: 240px;" >							<span class="author_list" title="韩磊">
//<a hidefocus="true" href="/artist/1302">韩磊</a>        	</span>
                //从doc分析以上html代码;把所有span标签下song-title查找出来,存在songTitles集合中;即,歌名集合;
                //从doc分析以上html代码;把所有span标签下author_list查找出来,存在artists集合中;即,歌手集合;
                Elements songTitles = doc.select("span.song-title");
                Elements artists = doc.select("span.author_list");
                //System.out.println(artists);
                for (int i=0;i<songTitles.size();i++){
                    SearchResult searchResult = new SearchResult();
                    //System.out.println("@searchResult : " + searchResult);

                    //<a href="/song/121353608"
                    //<a href="/song/264506450"
                    //a链接,存在urls集合中;即,歌曲url集合;
                    //a链接,第一个a连接,href属性的值;即,最终的url;
                    //a链接,第一个a连接,text(a链接的内容,例:>半壶纱<,半壶纱就是a链接的内容);即,最终的歌名;
                    Elements urls = songTitles.get(i).getElementsByTag("a");
                    //System.out.println("@urls : " + urls);
                    searchResult.setUrl(urls.get(0).attr("href"));//设置最终的url
                    searchResult.setMusicName(urls.get(0).text());//设置最终的歌名

                    //a链接,存在urls集合中;即,歌曲url集合;
                    Elements artistElements = artists.get(i).getElementsByTag("a");
                    //System.out.println("@artistElements : " + artistElements);
                    searchResult.setArtist(artistElements.get(0).text());//设置最终的歌手

                    searchResult.setAlbum("热歌榜");//设置最终的专辑

                    System.out.println("@searchResult : " + searchResult);
                    searchResults.add(searchResult);//把最终的所有信息,添加到集合
                }
                System.out.println("@searchResults : " + searchResults);
                //System.out.println("@songTitles.size() : " + searchResults.size());
            } catch (IOException e) {
                e.printStackTrace();
                return -1;
            }
            return 1;
        }

        //onPostExecute方法用于在执行完后台任务后更新UI,显示结果
        @Override
        protected void onPostExecute(Integer result) {
            super.onPostExecute(result);
            if (result==1){
                netMusicListAdapter = new NetMusicListAdapter(mainActivity,searchResults);
                //System.out.println(searchResults);
                listView_net_music.setAdapter(netMusicListAdapter);
                listView_net_music.addFooterView(LayoutInflater.from(mainActivity).inflate(R.layout.footviwe_layout,null));
            }
            load_layout.setVisibility(View.GONE);
            listView_net_music.setVisibility(View.VISIBLE);
        }
    }




    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

    }
}

MediaUtils如下:

package com.iwanghang.drmplayer.utils;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;

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

import com.iwanghang.drmplayer.R;
import com.iwanghang.drmplayer.vo.Mp3Info;

import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;

/**
 * Created by iwanghang on 16/4/16.
 */
public class MediaUtils {

    // 获取专辑封面的Uri
    private static final Uri albumArtUri = Uri
            .parse("content://media/external/audio/albumart");

    /**
     * 根据歌曲id查询歌曲信息
     */
    public static Mp3Info getMp3Info(Context context, long _id){
        System.out.println("MediaUtils.java #0 : " + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
        Cursor cursor = context.getContentResolver().query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,
                MediaStore.Audio.Media._ID + "=" + _id, null,
                MediaStore.Audio.Media.DEFAULT_SORT_ORDER);

        Mp3Info mp3Info = null;

        if(cursor.moveToNext()){
            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));//艺术家
            String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));//专辑
            long albumid = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));//专辑id
            long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));//时长
            long size = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE));//文件大小
            String url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));//文件路径
            int isMusic = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));//是否为音乐
            if(isMusic != 0){
                mp3Info.setId(id);
                mp3Info.setTitle(title);
                mp3Info.setArtist(artist);
                mp3Info.setAlbum(album);
                mp3Info.setAlbumId(albumid);
                mp3Info.setDuration(duration);
                mp3Info.setSize(size);
                mp3Info.setUrl(url);
                //System.out.println("MediaUtils.java #101 : title = " + title + " | artist = " + artist + " | duration = " + duration);
                //System.out.println("MediaUtils.java #102 : id = " + id + " | album = " + album + " | size = " + size);
                //System.out.println("MediaUtils.java #103 : url = " + url);
            }
        }
        cursor.close();
        return mp3Info;
    }

    /**
     * 用于从数据库中查询歌曲的信息,保存在List当中
     */
    public static long[] getMp3InfoIds(Context context){
        Cursor cursor = context.getContentResolver().query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                new String[] {MediaStore.Audio.Media._ID},
                MediaStore.Audio.Media.DURATION + ">=30000", null,
                MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
        long[] ids = null;
        if(cursor != null){
            ids = new long[cursor.getCount()];
            for (int i = 0;i<cursor.getCount();i++){
                cursor.moveToNext();
                ids[i] = cursor.getLong(0);
            }
        }
        cursor.close();
        return ids;
    }

    /**
     * 用于从数据库中查询歌曲的信息,保存在List当中
     */
    public static ArrayList<Mp3Info> getMp3Infos(Context context) {
        System.out.println("MediaUtils.java #2 : " + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
        Cursor cursor = context.getContentResolver().query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,
                MediaStore.Audio.Media.DURATION + ">=30000", null,
                MediaStore.Audio.Media.DEFAULT_SORT_ORDER);

        ArrayList<Mp3Info> mp3Infos = new ArrayList<Mp3Info>();
        System.out.println("MediaUtils.java #3 :cursor.getCount() : " + cursor.getCount());
        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));//艺术家
            String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));//专辑
            long albumid = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));//专辑id
            long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));//时长
            long size = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.SIZE));//文件大小
            String url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));//文件路径
            int isMusic = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media.IS_MUSIC));//是否为音乐
            if (isMusic != 0) {
                mp3Info.setId(id);
                mp3Info.setTitle(title);
                mp3Info.setArtist(artist);
                mp3Info.setAlbum(album);
                mp3Info.setAlbumId(albumid);
                mp3Info.setDuration(duration);
                mp3Info.setSize(size);
                mp3Info.setUrl(url);
                mp3Infos.add(mp3Info);
                //System.out.println("MediaUtils.java #401 : title = " + title + " | artist = " + artist + " | duration = " + duration);
                //System.out.println("MediaUtils.java #402 : id = " + id + " | album = " + album + " | size = " + size);
                //System.out.println("MediaUtils.java #403 : url = " + url);
                //System.out.println("MediaUtils.java #404 : mp3Infos = " + mp3Infos.size());
            }
        }
        cursor.close();
        System.out.println("MediaUtils.java #405 : mp3Infos = " + mp3Infos.size());
        return mp3Infos;
    }

    /**
     * 格式化时间,将毫秒转换为分:秒格式
     */
    public static String formatTime(long time){
        String min = time / (1000*60) + "";
        String sec = time % (1000*60) + "";
        if (min.length()<2){
            min = "0" + time / (1000*60) + "";
        }else {
            min = time / (1000*60) + "";
        }
        if (sec.length() == 4){
            sec = "0" + time % (1000*60) + "";
        }else if (sec.length() == 3){
            sec = "00" + time % (1000*60) + "";
        }else if (sec.length() == 2){
            sec = "000" + time % (1000*60) + "";
        }else if (sec.length() == 1) {
            sec = "0000" + time % (1000 * 60) + "";
        }
        return min + ":" + sec.trim().substring(0,2);
    }




    /**
     * 获取默认专辑图片
     */
    public static Bitmap getDefaultArtwork(Context context,boolean small) {
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inPreferredConfig = Bitmap.Config.RGB_565;
        if(small){	//返回小图片
            return BitmapFactory.decodeStream(context.getResources().openRawResource(R.mipmap.music), null, opts);
        }
        return BitmapFactory.decodeStream(context.getResources().openRawResource(R.mipmap.music), null, opts);
    }


    /**
     * 从文件当中获取专辑封面位图
     */
    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 = 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;
    }

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

SearchResult如下:
package com.iwanghang.drmplayer.utils;

import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

import com.iwanghang.drmplayer.vo.SearchResult;

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

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.xml.parsers.ParserConfigurationException;

/**
 * Created by iwanghang on 16/4/30.
 * 搜索音乐工具类
 */
public class SearchMusicUtils {
    private static final int SIZE = 20;//查询歌曲数量
    //private static final String URL = Constant.BAIDU_URL + Constant.BAIDU_SEARCH;
    //private static String URL = Constant.BAIDU_URL + Constant.BAIDU_SEARCH;
    private static SearchMusicUtils sInstance;
    private OnSearchResultListener mListener;

    private ExecutorService mThreadPool;//线程池

    public synchronized static SearchMusicUtils getInstance(){
        if (sInstance == null){
            try {
                sInstance = new SearchMusicUtils();
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            }
        }
        return sInstance;
    }

    //设置搜索事件
    private SearchMusicUtils() throws ParserConfigurationException{
        mThreadPool = Executors.newSingleThreadExecutor();//单任务线程池
    }

    public SearchMusicUtils setListener(OnSearchResultListener l){
        mListener = l;
        return this;
    }

    public void search(final String key,final int page){
        final Handler handler = new Handler(){//handler 用于返回数据
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what){
                    case Constant.SUCCESS:
                        if (mListener != null) mListener.onSearchResult((ArrayList<SearchResult>)msg.obj);
                        break;
                    case Constant.FAILED:
                        if (mListener != null) mListener.onSearchResult(null);
                        break;
                }
            }
        };

        //执行线程
        mThreadPool.execute(new Runnable() {
            @Override
            public void run() {//run方法
                ArrayList<SearchResult> results = getMusicList(key,page);
                if(results == null){
                    handler.sendEmptyMessage(Constant.FAILED);
                    return;
                }
                handler.obtainMessage(Constant.SUCCESS,results).sendToTarget();
            }
        });

    }

    //使用Jsoup组件请求网络,并解析音乐数据
    private ArrayList<SearchResult> getMusicList(final String key,final int page){
        final String start = String.valueOf((page - 1) * SIZE);

        Document doc = null;
        String URL = Constant.BAIDU_URL + Constant.BAIDU_SEARCH;
        try {
            //music.baidu.com/search/song?key=蔡琴&start=0&size=20
            //由上面url得到下面的代码,这个方法也是对的,但是我没有搞懂,搞明白的麻烦告诉我一下
            //doc = Jsoup.connect(URL)
            //        .data("key",key,"start",start,"size",String.valueOf(SIZE))
            //        .userAgent(Constant.USER_AGENT)
            //        .timeout(60 * 1000).get();
            //System.out.println("~~doc = " + doc);


            //从浏览器复制出来的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";
            String keyUrlEnCode = URLEncoder.encode(key, "utf8");
            URL = URL + "=" + keyUrlEnCode;
            System.out.println(URL);
            doc = Jsoup.connect(URL)
                    .data("query", "Java")
                    .userAgent(Constant.USER_AGENT)
                    .timeout(60 * 1000).get();
            //System.out.println("~~doc = " + doc);

            //<div class="song-item clearfix ">
            //由上面的网页源码得到"div.song-item.clearfix"
//<div class="song-item clearfix "><span class="checkbox-item"><input type="checkbox"  class="checkbox-item-hook"  /></span><span class="index-num index-hook"  style="width: 33px;" >01</span><span class="song-info " ></span><!-- 设置截断长度,考虑到有热门歌曲后会跟一个hot标签,需要做相应处理 --><span class="song-title"  style="width: 170px;" ><a href="/song/7313915" target=_blank class="" data-provider="" data-songdata='{ "id": "7313915" }'title="蔡琴《蔡琴海上良宵演唱会》你的眼神" data-film='null' data-info=''>你的眼神</a>
            //由上面代码 >你的眼神< ,你的眼神,就是标题
            Elements songTitles = doc.select("div.song-item.clearfix");
            Elements songInfos;
            ArrayList<SearchResult> searchResults = new ArrayList<SearchResult>();

            int xyz = 0;

            TAG:
            for (Element song : songTitles){
                //System.out.println("W SearchMusicUtils songTitles = " + songTitles);
                songInfos = song.getElementsByTag("a");
                //System.out.println("W SearchMusicUtils songInfos = " + songInfos);
                SearchResult searchResult = new SearchResult();
                //System.out.println("##searchResult = " + searchResult);
                for (Element info : songInfos){
                    //收费的歌曲
                    if (info.attr("href").startsWith("http://y.baidu.com/song/")){
                        continue TAG;
                    }

                    //跳转到百度音乐盒的歌曲
                    if (info.attr("href").equals("#") && !TextUtils.isEmpty(info.attr("data-songdata"))){
                        continue TAG;
                    }

                    //歌曲链接
                    if (info.attr("href").startsWith("/song")){//href="/song/s/570761c8f270856302a79"
                        searchResult.setMusicName(info.text());
                        searchResult.setUrl(info.attr("href"));
                    }

                    //歌手链接
                    if (info.attr("href").startsWith("/data")){//href="/data/artist/redirect?id=23571029"
                        searchResult.setArtist(info.text());//href="/data/artist/redirect?id=23571029">日本原声带
                    }

                    //专辑链接
                    if (info.attr("href").startsWith("/album")){//href="/album/102534774" title="ゴールデンマネジャー">《ゴールデンマ..》</a>
                        searchResult.setAlbum(info.text().replaceAll("《|》",""));
                    }

                    xyz = xyz + 1;
                    System.out.println("~~searchResult"+ xyz + " : " + searchResult);
                }
                searchResults.add(searchResult);
            }
            return searchResults;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }



    public interface OnSearchResultListener {
        public void onSearchResult(ArrayList<SearchResult> results);
    }

}




欢迎移动开发爱好者交流
沈阳或周边城市公司有意开发Android,请与我联系
联系方式

微信:iwanghang
QQ:413711276
邮箱:iwanghang@qq.com




转载请注明出处:http://blog.csdn.net/iwanghang/article/details/51298411

项目源码(打赏1积分请点这边):http://download.csdn.net/detail/iwanghang/9507635

项目源码(免积分下载请点这边):http://download.csdn.net/detail/iwanghang/9747505


Android开发本地及网络Mp3音乐播放器系列博文汇总
Android开发本地及网络Mp3音乐播放器(一)前言
Android开发本地及网络Mp3音乐播放器(二)SplashActivity(欢迎界面)
Android开发本地及网络Mp3音乐播放器(三)MainActivity(主界面)
Android开发本地及网络Mp3音乐播放器(四)实现音乐播放
Android开发本地及网络Mp3音乐播放器(五)实现专辑封面图片
Android开发本地及网络Mp3音乐播放器(六)实现独立音乐播放界面
Android开发本地及网络Mp3音乐播放器(七)循环模式与专辑倒影
Android开发本地及网络Mp3音乐播放器(八)状态存取与界面滑动
Android开发本地及网络Mp3音乐播放器(九)音乐收藏与列表切换
Android开发本地及网络Mp3音乐播放器(十)最近播放界面与数据保存更新
Android开发本地及网络Mp3音乐播放器(十一)使用Jsoup组件请求网络,并解析音乐数据
Android开发本地及网络Mp3音乐播放器(十二)创建NetMusicListAdapter、SearchResult显示网络音乐列表
Android开发本地及网络Mp3音乐播放器(十三)网络音乐搜索功能实现,歌名歌手专辑名搜索
Android开发本地及网络Mp3音乐播放器(十四)网络音乐下载功能实现
Android开发本地及网络Mp3音乐播放器(十五)网络音乐及歌词下载功能实现
Android开发本地及网络Mp3音乐播放器(十六)歌词显示及滚动事件实现、ViewPager使用
Android开发本地及网络Mp3音乐播放器(十七)已存在歌曲歌词下载
Android开发本地及网络Mp3音乐播放器(十八)新下载歌曲加载准备SdcardSearchToList
Android开发本地及网络Mp3音乐播放器(十九)通知媒体库更新刚下载的MP3
Android开发本地及网络Mp3音乐播放器(二十)歌曲下载完成后通知主界面更新本地音乐


觉得博文有用,请点赞,请留言,请关注,谢谢!~

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页