转发请注明出处: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>
</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外面就行
这样就可以根据输入歌曲名和歌手,播放了,
附注:代码等等打包上传