android音乐播放器之在线播放功能的实现

转发请注明出处: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外面就行

这样就可以根据输入歌曲名和歌手,播放了,
附注:代码等等打包上传

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值