转载请注明出处: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会被传入.).@Overridepublic void onAttach(Context context) {super.onAttach(context);//mainActivity = (MainActivity) context;mainActivity = (MainActivity) getActivity();}public static NetMusicListFragment newInstance() {NetMusicListFragment net = new NetMusicListFragment();return net;}@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {//UI组件初始化View view = inflater.inflate(R.layout.net_music_list_layout,null);//itemlistView_net_music = (ListView) view.findViewById(R.id.listView_net_music);//findViewByIdload_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);}@Overridepublic 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(){@Overridepublic 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操作@Overrideprotected void onPreExecute() {super.onPreExecute();load_layout.setVisibility(View.VISIBLE);//加载layout.显示listView_net_music.setVisibility(View.GONE);//item.隐藏searchResults.clear();//搜索结果.清理}//doInBackground方法内部执行后台任务,不可在此方法内修改UI@Overrideprotected 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"));//设置最终的urlsearchResult.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,显示结果@Overrideprotected 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);}}@Overridepublic 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 {// 获取专辑封面的Uriprivate 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));//音乐idString 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));//专辑idlong 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));//音乐idString 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));//专辑idlong 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 用于返回数据@Overridepublic 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() {@Overridepublic 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音乐播放器(二十)歌曲下载完成后通知主界面更新本地音乐

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

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

  1. linux安装深度播放器,分享|Ubuntu 14.04 用户如何安装深度音乐播放器和百度音乐插件...

    播放本地音乐或者收听国外的音乐电台,Ubuntu 14.04 自带的音乐播放器 Rhythmbox 完全能够满足,但是如果你想有像酷狗那样的国内播放器就需要折腾一下,还好有深度音乐播放器,这是一款完全 ...

  2. React Native (一) react-native-video实现音乐播放器和进度条的功能

    React Native (一) react-native-video实现音乐播放器和进度条的功能 功能: 1.卡片滑动切歌 2.显示进度条 效果图: 第三方组件: 1.react-native-vi ...

  3. iOS之基于FreeStreamer的简单音乐播放器(模仿QQ音乐)

    代码地址如下: http://www.demodashi.com/demo/11944.html 天道酬勤 前言 作为一名iOS开发者,每当使用APP的时候,总难免会情不自禁的去想想,这个怎么做的?该 ...

  4. android 收藏歌曲功能,基于android的网络音乐播放器-回调实现音乐播放及音乐收藏的实现(三)...

    作为android初学者,最近把疯狂android讲义和疯狂Java讲义看了一遍,看到书中介绍的知识点非常多,很难全部记住,为了更好的掌握基础知识点,我将开发一个网络音乐播放器-EasyMusic来巩 ...

  5. 基于android的网络音乐播放器-回调实现音乐播放及音乐收藏的实现(三)

    作为android初学者,最近把疯狂android讲义和疯狂Java讲义看了一遍,看到书中介绍的知识点非常多,很难全部记住,为了更好的掌握基础知识点,我将开发一个网络音乐播放器-EasyMusic来巩 ...

  6. android学习笔记---43_音乐播放器,音频采集,音乐播放,使用SoundPool播放音效

    43_音乐播放器 ------------------------------------------ 1.注意在string.xml中不可以使用java的关键字,因为用关键字的话,会和java内部冲 ...

  7. 基于Qt的网络音乐播放器(四)酷狗API接口获取歌曲的搜索列表和歌曲的播放

    2020博客之星年度总评选进行中:请为74号的狗子投上宝贵的一票! 我的投票地址:点击为我投票 文章目录 1.效果图 2.准备好前面获取的酷狗api接口 3.网络歌曲搜索实现 4.网络歌曲播放的实现 ...

  8. java音乐播放器文库_android音乐播放器开发教程

    关于音乐列表的读取,不同的音乐播放器都会有不同的方案,有的是有多重方案并用.例如说,全盘扫描音乐格式文件等. 首先我封装了一个Audio类来存储读取的音频信息: public class MediaU ...

  9. 音乐播放器的设计与实现 功能要求:设计一款基于HTML5音频技术的音乐播放器,要求实现音乐的播放、暂停、音量大小调节、上一首和下一首切换,运行效果如图所示

    本地资源在谷歌浏览器上是无法快进的.这个是重点!!!有很多解决方法,我直接用火狐就ok了 https://www.gaitubao.com/# 改图宝链接 用于修改歌曲头像 大小标准显示才正常 我用的 ...

最新文章

  1. vim+cscope+ctags打造属于自己的IDE
  2. java memorycache原理_JVM代码缓存区CodeCache原理及用法解析
  3. mysql 单表查询
  4. VC对话框最小化到托盘
  5. 微信小程序用wxs实现手机号码用****代替
  6. hyperopt中文文档:Interfacing-With-Other-Languages(在其他语言中使用hyperopt)
  7. Linux Python 安装第三方库时报错 package wheel is not installed
  8. 仅用18天,英伟达新型GAN合成真假难辨高清明星脸
  9. 两种方法身份证读卡器对接,实现扫描身份证读取身份证信息功能。
  10. vb webQQ登陆器
  11. 为你的企业建立竞争情报系统
  12. 教小师妹学多线程,看完我写的例子,脸红成那样!
  13. 计算机无法查看隐藏文件夹,Windows7系统无法显示隐藏文件如何解决
  14. 模块化开发RequireJS之shim配置
  15. 详解Python中列表切片及浅拷贝的关系(下)
  16. uva 557 Buger 概率
  17. java mysql多媒体积件管理库的开发与应用源码+论文
  18. 页面访问量和网站访问量的统计
  19. php artisan tanker,Artisan 开发
  20. 用opencv-python建立纯色图

热门文章

  1. 《炬丰科技-半导体工艺》纳米柱 GaN-LED的制备
  2. 素数回文(来自计蒜客T1986题目)
  3. 拼多多的评价是真实的吗?多久会消失?
  4. 时间序列预测专项——基于Prophet的业务预测
  5. 声明html单选框组label,使用HTML“label”标签与单选按钮
  6. 前端-js生成pdf文件
  7. 开车通过红绿灯及转弯时各类操作技巧
  8. JAVA中强引用和弱引用的区别
  9. 3D建模|手绘角色模型和手绘场景模型有什么区别?
  10. 中国高层外墙清洗机器人行业业运行态势分析与未来产销需求分析报告2021-2027年