转发请注明出处:http://blog.csdn.net/qq_28055429/article/details/51327171
前言:由于最近在做一个音乐播放器,需实现在线播放功能的实现,故而找了一些资料,看了别人的一些博客,现在终于可以实现了
需求:根据用户输入歌曲名+歌手名
返回:从百度音乐api查询,若有该曲则播放该曲,若无这里没做异常处理
一,前提解说:
(1)百度音乐api提供一个接口地址:
http://box.zhangmen.baidu.com/x?op=12&count=1&title=歌曲名$$歌手名$$$$
注意后面是4个
,是4个$不是两个$,,两个的好像传回来时歌词id会变成0,
不知为何这里传上去她不显示出来(歌曲名后面加两个$歌手名后面加4个$)
(2)如打开网址:
http://box.zhangmen.baidu.com/x?op=12&count=1&title=温柔$$五月天$$$$
返回:
<result>
<count>2</count>
<url>
<encode>
<![CDATA[
http://zhangmenshiting.baidu.com/data2/music/12455572/YmRnaWprbmpfn6NndK6ap5WXcGybnGpwY2qVa5tnnG9nZWhkmJqZcWqXmGhma5tslGaWZGVqaGmWamuYbmudnZVkZ1qin5t1YWBnamtsanFnamlmZ21oazE$
]]>
</encode>
<decode>
<![CDATA[
12455572.mp3?xcode=8ff3828b7f1e76350cdb99ee415d4c4c00411e88d95fed24&mid=0.46663968622713
]]>
</decode>
<type>1</type>
<lrcid>32049</lrcid>
<flag>1</flag>
</url>
<durl>
<encode>
<![CDATA[
http://zhangmenshiting2.baidu.com/data2/music/15943866/YmdsaGhubW5fn6NndK6ap5WXcGybnGpwY2qVa5tnnG9nZWiZZm1rnWSWZ2Vul2tuYmuYmpuYbmuUZpRkZmhnb5Vnl1qin5t1YWBnamtsanFnamlmZ21oazE$
]]>
</encode>
<decode>
<![CDATA[
15943866.mp3?xcode=8ff3828b7f1e7635e174e3d419a4619effb73c4a01207d5d&mid=0.46663968622713
]]>
</decode>
<type>1</type>
<lrcid>32049</lrcid>
<flag>1</flag>
</durl>
<url>
<encode>
<![CDATA[
http://zhangmenshiting.baidu.com/data2/music/12455572/YmRnaWprbmpfn6NndK6ap5WXcGybnGpwY2qVa5tnnG9nZWhkmJqZcWqXmGhma5tslGaWZGVqaGmWamuYbmudnZVkZ1qin5t1YWBrbGhncGpjZGNkbGtobzE$
]]>
</encode>
<decode>
<![CDATA[
12455572.mp3?xcode=8ff3828b7f1e76350cdb99ee415d4c4c00411e88d95fed24&mid=0.88319222007517
]]>
</decode>
<type>8</type>
<lrcid>32049</lrcid>
<flag>1</flag>
</url>
<durl>
<encode>
<![CDATA[
http://zhangmenshiting2.baidu.com/data2/music/15943866/YmdsaGhubW5fn6NndK6ap5WXcGybnGpwY2qVa5tnnG9nZWiZZm1rnWSWZ2Vul2tuYmuYmpuYbmuUZpRkZmhnb5Vnl1qin5t1YWBrbGhncGpjZGNkbGtobzE$
]]>
</encode>
<decode>
<![CDATA[
15943866.mp3?xcode=8ff3828b7f1e7635e174e3d419a4619effb73c4a01207d5d&mid=0.88319222007517
]]>
</decode>
<type>8</type>
<lrcid>32049</lrcid>
<flag>1</flag>
</durl>
<p2p>
<hash>4be2421de37f9458cb8ef9863259ce3b2fd327fd</hash>
<url>
<![CDATA[ ]]>
</url>
<type>mp3</type>
<size>12627695</size>
<bitrate>192</bitrate>
</p2p>
</result>
这里我们需要的是:encode,decode,lrcid,好像每一个就是一首歌曲,只是质量不同,这里以第一首为例
encode的值:
http://zhangmenshiting2.baidu.com/data2/music/15943866/YmdsaGhubW5fn6NndK6ap5WXcGybnGpwY2qVa5tnnG9nZWiZZm1rnWSWZ2Vul2tuYmuYmpuYbmuUZpRkZmhnb5Vnl1qin5t1YWBrbGhncGpjZGNkbGtobzE$
decode的值:
12455572.mp3?xcode=8ff3828b7f1e76350cdb99ee415d4c4c00411e88d95fed24&mid=0.46663968622713
lrcid值:32049
歌词下载地址为:http://box.zhangmen.baidu.com/bdlrc/320/32049.lrc
32049/100
= 230,故而后面为:320/32049.lrc
(3)得到歌曲的下载地址:
用decode的值替换encode值得最后一个"/"号后面的东东
如我上面的例子得到的下载地址为:
http://zhangmenshiting2.baidu.com/data2/music/15943866/12455572.mp3?xcode=8ff3828b7f1e76350cdb99ee415d4c4c00411e88d95fed24&mid=0.46663968622713
二,准备工作:
我是用dom4j解析xml字符串的,故而需下载相应的包(待会我会上传,可去下载,解压后存入libs目录下就可以)
三,开始解析,具体见代码吧:
(1)主类
package com.example.texst2; import java.io.IOException; import android.app.Activity; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity { private TextView textView; private EditText editTitle, editAuthor; private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 绑定id textView = (TextView) findViewById(R.id.textView); editTitle = (EditText) findViewById(R.id.editTitle); editAuthor = (EditText) findViewById(R.id.editAuthor); button = (Button) findViewById(R.id.button); // 为按钮设置监听器 button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //用editText来获取用户输入,转换成字符串,如:温柔 ,五月天(搜不到会出错) String title = editTitle.getText().toString(); String name = editAuthor.getText().toString(); System.out.println(title + " " + name ); // 获取音乐 BaiduMusicService d = new BaiduMusicService(); Music music = d.searchMusic(title, name); //通过textView来显示相关信息 textView.setText("音乐名称:" + music.getTitle() + "\n音乐信息:" + music.getDescription() + "\n 普通品质链接:" + music.getMusicUrl() +"\n" + "高品质链接: " + music.getHQMusicUrl()); //传入解析回来的音乐下载地址,这里用普通品质就好, Uri uri = Uri.parse(music.getMusicUrl()); MediaPlayer mPlayer = new MediaPlayer(); //创建MediaPlayer对象 try { mPlayer.setDataSource(MainActivity.this, uri); //设置播放路径 mPlayer.prepare(); //第一次播放前需调用prepare()方法 } catch (Exception e) { e.printStackTrace(); } mPlayer.start(); //开始播放 } }); } }
(2)http,解析类
</pre></div><div class="line"><div style="text-align:left"><span style="font-family:monospace"><span style="font-size:18px"></span></span><pre name="code" class="java">package com.example.texst2; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import android.os.StrictMode; public class BaiduMusicService { /** * 依据名称和作者搜索音乐 * @param musicTitle 音乐名称 * @param musicAuthor 音乐作者 * @return Music */ public static Music searchMusic(String musicTitle, String musicAuthor) { // 百度音乐搜索地址 String requestUrl = "http://box.zhangmen.baidu.com/x?op=12&count=1&title={TITLE}$${AUTHOR}$$$$"; // 对音乐名称、作者进URL编码,replace:替换 requestUrl = requestUrl.replace("{TITLE}", urlEncodeUTF8(musicTitle)); requestUrl = requestUrl.replace("{AUTHOR}", urlEncodeUTF8(musicAuthor)); // 处理名称、作者中间的空格,空格的编码为%20 requestUrl = requestUrl.replaceAll("\\+", "%20"); // 查询返回输入流 InputStream inputStream = httpRequest(requestUrl); // 解析music Music music = parseMusic(inputStream); // 判空 if (null != music) { //设置歌曲名字和作者 music.setTitle(musicTitle); // 假设作者不为"",将描写叙述设置为作者 if (!"".equals(musicAuthor)) music.setDescription(musicAuthor); else music.setDescription("来自百度音乐"); } return music; //返回音乐 } /** * UTF-8编码 * * @param source * @return */ private static String urlEncodeUTF8(String source) { String result = source; try { //用URLEncoder.encode()来转化UTF-8编码 result = java.net.URLEncoder.encode(source, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return result; } /** * 发送http请求取得返回的输入流 * * @param requestUrl 请求地址 * @return InputStream */ private static InputStream httpRequest(String requestUrl) { //注意在Android 4.0之后系统强制性的不允许在主线程访问网络,否则会出现android.os.NetworkOnMainThreadException异常, //常用解决办法是:在onCreat()方法的setContentView()语句之后添加以下句子,此处就加在这里吧 if(android.os.Build.VERSION.SDK_INT > 9){ StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } InputStream inputStream = null; //创建输入流对象 try { URL url = new URL(requestUrl); //创建URL //(2)用URL的openConnection()方法打开网络连接,返回一个HttpURLConnection对象 HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection(); httpUrlConn.setDoInput(true); httpUrlConn.setRequestMethod("GET"); //设置访问方法为GET httpUrlConn.connect(); //用connect()方法连接 // 获得返回的输入流 inputStream = httpUrlConn.getInputStream(); } catch (Exception e) { e.printStackTrace(); } return inputStream; //返回输入流 } /** * 解析音乐参数 * 使用dom4j解析xml字符串 * @param inputStream * @return Music */ @SuppressWarnings("unchecked") private static Music parseMusic(InputStream inputStream) { Music music = null; try { //创建SAXReader对象 SAXReader reader = new SAXReader(); //用SAXReader对象的read()方法读取输入流,返回Document文档 Document document = reader.read(inputStream); // 获取xml根元素 Element root = document.getRootElement(); // 获取搜索到的歌曲数 String count = root.element("count").getText(); // 当搜索到的歌曲数大于0时 if (!"0".equals(count)) { // 普通品质 List<Element> urlList = root.elements("url"); // 高品质 List<Element> durlList = root.elements("durl"); // 普通品质的encode、decode String urlEncode = urlList.get(0).element("encode").getText(); String urlDecode = urlList.get(0).element("decode").getText(); // 普通品质音乐的URL String url = urlEncode.substring(0, urlEncode.lastIndexOf("/") + 1) + urlDecode; //替换掩码,得到下载地址 if (-1 != urlDecode.lastIndexOf("&")) url = urlEncode.substring(0, urlEncode.lastIndexOf("/") + 1) + urlDecode.substring(0, urlDecode.lastIndexOf("&")); // 默认情况下,高音质音乐的URL 等于 普通品质音乐的URL String durl = url; // 判断是否存在高品质音乐 Element durlElement = durlList.get(0).element("encode"); if (null != durlElement) { // 高品质的encode、decode String durlEncode = durlList.get(0).element("encode").getText(); String durlDecode = durlList.get(0).element("decode").getText(); // 得到高品质音乐的下载地址 durl = durlEncode.substring(0, durlEncode.lastIndexOf("/") + 1) + durlDecode; if (-1 != durlDecode.lastIndexOf("&")) durl = durlEncode.substring(0, durlEncode.lastIndexOf("/") + 1) + durlDecode.substring(0, durlDecode.lastIndexOf("&")); } //创建Music对象 music = new Music(); // 设置普通品质音乐链接 music.setMusicUrl(url); // 设置高品质音乐链接 music.setHQMusicUrl(durl); } } catch (Exception e) { e.printStackTrace(); } return music; //返回音乐对象 } }
(3)Music实体类
<pre name="code" class="java">package com.example.texst2; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class Music { // 音乐名称 private String Title; // 音乐描述 private String Description; // 音乐链接 private String MusicUrl; // 高质量音乐链接 private String HQMusicUrl; //4个get方法和4个set方法 public String getTitle() { return Title; } public void setTitle(String title) { Title = title; } public String getDescription() { return Description; } public void setDescription(String description) { Description = description; } public String getMusicUrl() { return MusicUrl; } public void setMusicUrl(String musicUrl) { MusicUrl = musicUrl; } public String getHQMusicUrl() { return HQMusicUrl; } public void setHQMusicUrl(String musicUrl) { HQMusicUrl = musicUrl; } }
(4)布局文件:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.texst2.MainActivity" > <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="歌曲名称:" /> <EditText android:id="@+id/editTitle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入歌曲名" /> </TableRow> <TableRow> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="歌手名字:" /> <EditText android:id="@+id/editAuthor" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入歌手名字" /> </TableRow> <TableRow> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="播放" /> </TableRow> <TableRow> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" /> </TableRow> </TableLayout>
(5)因为要访问网络权限,需在AndroidManifest.xml添加权限
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
加在application外面就行
这样就可以根据输入歌曲名和歌手,播放了,
附注:代码等等打包上传