自从学Android以来,我一直都在写一点东西,虽然说不大但是还挺有成就感的。每当在手机上运行自己的程序时,感觉虽然真的挺烂的,但是那种喜悦感不知道大家能不能理解。
我一直上心的一个程序就是音乐播放器,这是我第一个可以拿得出手的程序,虽然说现在还是很烂,但是也要看和什么比较了,能实现基本的功能也算是一个优点了吧。一开始我只是简单的能够播放本地的程序,只是一个简单的ListView的运用,不支持歌词,也不能从网络获取歌词,甚至读取歌曲文件都是从指定目录下获取。但是,我没办法啊,当时学的太少,渐渐的学的多了,我也就在不断补充内容进去。我可以支持歌词显示了,我不甘心于本地读取歌词,看了大量的资料之后,我能从网络下载歌词了,不甘心于本地歌曲,终于,我能从网络下载歌曲了,这个过程可能漫长了一点,但是最后还是实现了,有点被自己感动了,O(∩_∩)O哈哈~,说的有点多了,好了,进入正题吧!
从网络获取歌曲资源,本来就不是多么简单的事,需要对XML有一定的了解,不光是了解,还要会使用,当然也可以不用了解,因为封装的足够好的话,别人的东西可以直接使用,这也是不错的方法。
从头开始说,我想获取歌曲资源就需要接口,从百度找了好长的时间,我大概看了有20篇的博客,让我吃惊的事情是居然有2/3的博客内容是一模一样的,对,一模一样,他们都是给出了百度MP3的API借口,但是怎么用呢,下面就没有解释了,我不知道他们是不了解还是没时间写博客,但是直接Copy别人博客的内容,我个人感觉还是不好的,而且他们给的内容根本没法让你使用,只是告诉了你有这个API的存在,怎么用还真没有,当然我也不会说什么,但是,最后还真让我找到了对这个API的使用,真的是很全面,从一开始的介绍,到最后的运用,我可以说我是看了那个博客才学会下载歌曲的,它对我帮助很大!出于感谢和尊重,我把地址放在这里,大家可以去看一下:
http://blog.youkuaiyun.com/yutengwan/article/details/30220705
好了,话就说到这里,下面我将一下怎么实现下载歌曲,尽我所能把大家给教会^_^。
效果图如下:
输入歌曲名称和歌手,然后我们就可以下载了。
"http://box.zhangmen.baidu.com/x?op=12&count=1&title={title}$${author}$$$$"
这就是百度mp3的API了,在我看过的80%的博客里,都会有这一个API。这个API使用的时候,我们需要把{title}换成歌曲名称,{author}换成歌手,然后就可以去获取URL了。我写了一个工具类来使用,方便转换。
public class Utils {
public static String ToURL(String title,String author) {
String url = "http://box.zhangmen.baidu.com/x?op=12&count=1&title={title}$${author}$$$$";
try {
url = url.replace("{title}", URLEncoder.encode(title, "utf-8"));
url=url.replace("{author}", URLEncoder.encode(author, "utf-8"));
} catch (Exception e) {}
return url;
}
}
从这个类中定义的方法,我们只需要传入如效果图中EditText中的名称和歌手,然后就可以得到URL了。但是这个URL并不是可以直接下载歌曲的,因为它所表示并不是歌曲,而是一个XML文件,XML文件里面所保存的才是我们需要的URL,根据这个URL我们就可以下载歌曲了。
下面是根据URL得到的XML里面的内容:
”http://box.zhangmen.baidu.com/x?op=12&count=1&title=幻听$$许嵩$$$$“
<result>
<count>1</count>
<url>
<encode>
<![CDATA[
http://zhangmenshiting.baidu.com/data2/music/40455198/ZWJnaWpncHBfn6NndK6ap5WXcGdpZmduZGRjaW6anWhilWyXm5dom5dllGqabJmeaJiWlWZqZ5thlmyVbmqcbJdrZFqin5t1YWBoZG1nbmtiY2RqZ2xscTE$
]]>
</encode>
<decode>
<![CDATA[
40455198.mp3?xcode=3400632059df01c9cfa1cf3a6e6bf7fca140c0d9a94e4f91&mid=0.50817311162659
]]>
</decode>
<type>8</type>
<lrcid>1069339</lrcid>
<flag>1</flag>
</url>
<durl>
<encode>
<![CDATA[
http://zhangmenshiting2.baidu.com/data2/music/40455208/ZWJnaWpoZ3Bfn6NndK6ap5WXcGdpZmduZGRjaW6anWhilWyXm5dom5dllGqabJmeaJiWl22baXFnaJRobmiYcZRql1qin5t1YWBoZG1nbmtiY2RqZ2xscTE$
]]>
</encode>
<decode>
<![CDATA[
40455208.mp3?xcode=3400632059df01c9cfa1cf3a6e6bf7fcc8e2966a492a9c8d&mid=0.50817311162659
]]>
</decode>
<type>8</type>
<lrcid>1069339</lrcid>
<flag>1</flag>
</durl>
<p2p>
<hash>7abcd427ab364a7cdfe6bfbce11dc90d97dc8c87</hash>
<url>
<![CDATA[ ]]>
</url>
<type>mp3</type>
<size>6613349</size>
<bitrate>192</bitrate>
</p2p>
</result>
http://zhangmenshiting2.baidu.com/data2/music/40455198/40455198.mp3
这一部分就是我们需要获取的东西,所以我们就需要对XML文件进行解析,所以我才说大家需要对XML有一定的了解和使用,不然使用起来还是很痛苦的,因为不明白。但是,大家还是不需要担心,因为在前话我说了,不懂没关系,因为我给大家封装好了,大家直接使用就可以了,当然如果大家想了解,大家可以对我的代码进行仔细研究,相信大家可以明白的。如果还是存在不明白的地方,欢迎大家和我交流。
public class Main {
public static InputStream downLoad(String urlPath){
InputStream inputStream = null;
try {
URL url = new URL(urlPath);
HttpURLConnection urlCon = (HttpURLConnection) url.openConnection();
urlCon.setRequestMethod("GET");
urlCon.setConnectTimeout(10000);
urlCon.setDoOutput(true);
urlCon.setDoInput(true);
urlCon.setAllowUserInteraction(true);
urlCon.connect();
inputStream = urlCon.getInputStream();
} catch (Exception e ){}
return inputStream;
}
public String downLoadTextFile(String url){
StringBuffer sb = new StringBuffer();
BufferedReader buffer = null;
InputStream instream = null;
String line=null;
try {
instream = downLoad(url);
buffer = new BufferedReader(new InputStreamReader(instream,"GB2312"));
while((line = buffer.readLine()) != null){
sb.append(line+"\n");
}
}catch(Exception e) {}
try {
buffer.close();
instream.close();
}catch(Exception e) {}
return sb.toString();
}
public static String parasXML(InputStream inputStream){
try {
String lrcid = null,url = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(inputStream);
Element root = dom.getDocumentElement();
Node count = root.getFirstChild();
NodeList items = root.getElementsByTagName("url");
if(items.getLength() <= 0) {
return null;
}else {
Element urlNode = (Element)items.item(0);
Element lrcidNode = (Element)(urlNode.getElementsByTagName("lrcid").item(0));
Element encodeNode = (Element)urlNode.getElementsByTagName("encode").item(0);
Element decodeNode = (Element)urlNode.getElementsByTagName("decode").item(0);
if(encodeNode == null) {
return null;
}
if("lrcid".equals(lrcidNode.getNodeName())) {
lrcid = lrcidNode.getTextContent();
}else {
}
//获取encode里的值
String temp1 = encodeNode.getTextContent();
//获取decodeNode的值
String temp2 = decodeNode.getTextContent();
StringBuffer buffer = new StringBuffer();
//接下来是将temp1和temp2进行分割解码合并在一起
String [] arrayTemp1 = temp1.split("/");
for(int i=0;i<arrayTemp1.length-1;i++) {
buffer.append(arrayTemp1[i]+"/");
}
//把解码的地址合在一起
buffer.append(temp2);
url = buffer.toString();
url = url + "##"+ lrcid;
return url;
}
}catch(Exception e) {
e.printStackTrace();
return null;
}
}
}
在这个类里面,我提供了三个方法,不过我们只需要使用两个就可以了。
方法一:
public static InputStream downLoad(String urlPath);
这个方法是根据我们用Utility工具类中获得的URL来获得一个InputStream的对象,这个对象是一个输入流,它是和XML文件连在一起的,根据这个对象,我们就可以解析XML文件。
方法二:
public String downLoadTextFile(String url);
这个方法是将XML文件里面的内容保存到一个字符串中,我们根据这个字符串我们就可以知道XML文件里有什么内容了,但是我们在实现的时候并不需要这个方法,只是在程序出问题的时候我们可以用来调试XML里面是不是包含我们需要的URL罢了。
方法三:
public static String parasXML(InputStream inputStream);
这个方法可以说是最重要的了,因为它返回的就是我们所需要的URL字符串了,根据这个字符串,我们就可以生成URL对象,有了URL对象,想干什么还不是由你说了算嘛。
好了,大家大概对如何根据歌曲名称和歌手获得歌曲的URL有一定的了解了,只需要把我所提供的类运用在自己的项目中就可以直接使用了,如何根据url来下载资源,这个就是另一个问题了,也就是获取网络资源的问题,这个问题问题相对就比较简单了,大家从网上可以找到相关的博客看一看,当然我也会更新一个新的博客,大家可以期待了。还有很重要的一点,大家在获取URL的时候,对上面的几个方法的使用,一定要在一个新的线程中使用,不能在主线程中使用,因为Android不允许你在主线程中进行和网络相关的操作,你只能新建一个线程,在这个线程中进行操作,不然,到时候你是怎么错的你都不知道,我可是被坑过的人啊。