转载请注明出处: http://blog.csdn.net/u014608640/article/details/51899239


如果没有本地歌词怎么办?现在来将一下加载在线歌词。好了,还是用那张图。



在实现这个功能的时候,lz尝试过baidu api,歌词迷api,后来选用了歌词迷api,虽然还是资源不全,而且还有很多错误。特别头疼的是有时候歌词居然不分行,解析起来简直难受。


歌词迷api歌词查询地址:http://geci.me/api/lyric/


比如我要查询:   http://geci.me/api/lyric/安静/周杰伦


会得到一下json串:

{"count": 2, "code": 0, "result": [{"aid": 2223011, "artist_id": 30796, "song": "\u5b89\u9759", "lrc": "http://s.geci.me/lrc/257/25700/2570058.lrc", "sid": 2570058}, {"aid": 2336033, "artist_id": 30796, "song": "\u5b89\u9759", "lrc": "http://s.geci.me/lrc/272/27282/2728244.lrc", "sid": 2728244}]}

很容易发现里面的歌词文件,然后缓冲到本地(SweetMusicPlayer/Lryics)下,再按本地加载的方式就行了。


捋一捋,我们加载歌词文件要经过以下步骤。

1)通过地址查询出歌词的地址。(这里楼主用URLConnection)

2)通过歌词地址缓冲歌词文件。(这里楼主用URLConnection)

3)加载缓冲好的歌词文件。


上面说的看起来还是比较容易,楼主自己写了个demo,是一个Java工程,发现没啥问题,正常加载歌词文件。

等到Android上,第一步就跪了。发现URLConnection的getInputStream()抛出一个io异常,简直要命,折腾了半天才发现是因为带了http://geci.me/api/lyric/安静/周杰伦中文路径。由于默认是gbk,网络传输为utf-8,所以要把中文转码,URLEncoder.encode(str,"utf-8");即可。


到了第2步,问题又出现了,歌词乱码。解决办法,用字符流操作比较合适,还要注意同一编码。

[java] view plain copy  
  1. package com.huwei.sweetmusicplayer.util;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.BufferedWriter;  
  5. import java.io.File;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8. import java.io.InputStreamReader;  
  9. import java.io.OutputStreamWriter;  
  10. import java.io.PrintWriter;  
  11. import java.io.UnsupportedEncodingException;  
  12. import java.net.HttpURLConnection;  
  13. import java.net.MalformedURLException;  
  14. import java.net.URL;  
  15. import java.net.URLConnection;  
  16. import java.net.URLEncoder;  
  17. import java.util.Random;  
  18.   
  19. import org.json.JSONArray;  
  20. import org.json.JSONException;  
  21. import org.json.JSONObject;  
  22.   
  23. import android.os.Environment;  
  24. import android.util.Log;  
  25.   
  26. public class OnlineLrcUtil {  
  27.     private static String TAG = "OnlineLrcUtil";  
  28.     private static OnlineLrcUtil instance;  
  29.     public static final String lrcRootPath = Environment  
  30.             .getExternalStorageDirectory().toString()  
  31.             + "/SweetMusicPlayer/Lyrics/";  
  32.   
  33.     public static final String queryLrcURLRoot = "http://geci.me/api/lyric/";  
  34.   
  35.     public static OnlineLrcUtil getInstance() {  
  36.         if (null == instance) {  
  37.             instance = new OnlineLrcUtil();  
  38.         }  
  39.   
  40.         return instance;  
  41.     }  
  42.   
  43.     public String getQueryLrcURL(String title, String artist) {  
  44.         return queryLrcURLRoot + Encode(title) + "/" + Encode(artist);  
  45.     }  
  46.   
  47.     public String getLrcURL(String title, String artist) {  
  48.         String queryLrcURLStr = getQueryLrcURL(title, artist);  
  49.         try {  
  50.             URL url = new URL(queryLrcURLStr);  
  51.             URLConnection urlConnection = url.openConnection();  
  52.             urlConnection.connect();  
  53.   
  54.             BufferedReader in = new BufferedReader(new InputStreamReader(  
  55.                     urlConnection.getInputStream()));  
  56.   
  57.             StringBuffer sb = new StringBuffer();  
  58.   
  59.             String temp;  
  60.             while ((temp = in.readLine()) != null) {  
  61.                 sb.append(temp);  
  62.             }  
  63.   
  64.             JSONObject jObject = new JSONObject(sb.toString());  
  65.             int count = jObject.getInt("count");  
  66.             int index = count == 0 ? 0 : new Random().nextInt() % count;  
  67.             JSONArray jArray = jObject.getJSONArray("result");  
  68.             JSONObject obj = jArray.getJSONObject(index);  
  69.             return obj.getString("lrc");  
  70.   
  71.         } catch (MalformedURLException e) {  
  72.             // TODO Auto-generated catch block  
  73.             e.printStackTrace();  
  74.         } catch (IOException e) {  
  75.             // TODO Auto-generated catch block  
  76.             e.printStackTrace();  
  77.         } catch (JSONException e) {  
  78.             // TODO Auto-generated catch block  
  79.             e.printStackTrace();  
  80.         }  
  81.   
  82.         return null;  
  83.     }  
  84.   
  85.     // 歌手,歌曲名中的空格进行转码  
  86.     public String Encode(String str) {  
  87.   
  88.         try {  
  89.             return URLEncoder.encode(str.trim(), "utf-8");  
  90.         } catch (UnsupportedEncodingException e) {  
  91.             // TODO Auto-generated catch block  
  92.             e.printStackTrace();  
  93.         }  
  94.   
  95.         return str;  
  96.   
  97.     }  
  98.   
  99.     // 歌词文件网络地址,歌词文件本地缓冲地址  
  100.     public boolean wrtieContentFromUrl(String urlPath, String lrcPath) {  
  101.         Log.i(TAG, "lrcURL" + urlPath);  
  102.   
  103.         try {  
  104.             URL url = new URL(urlPath);  
  105.   
  106.             URLConnection urlConnection = url.openConnection();  
  107.             urlConnection.connect();  
  108.   
  109.             HttpURLConnection httpConn = (HttpURLConnection) urlConnection;  
  110.             if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {  
  111.                 File file = new File(lrcRootPath);  
  112.                 if (!file.exists()) {  
  113.                     file.mkdirs();  
  114.                 }  
  115.   
  116.                 BufferedReader bf = new BufferedReader(new InputStreamReader(  
  117.                         urlConnection.getInputStream(), "utf-8"));  
  118.                 PrintWriter out = new PrintWriter(new BufferedWriter(  
  119.                         new OutputStreamWriter(new FileOutputStream(lrcPath),  
  120.                                 "utf-8")));  
  121.   
  122.                 char c[] = new char[256];  
  123.                 int temp = -1;  
  124.                 while ((temp = bf.read()) != -1) {  
  125.                     bf.read(c);  
  126.                     out.write(c);  
  127.                 }  
  128.   
  129.                 bf.close();  
  130.                 out.close();  
  131.   
  132.                 return true;  
  133.             }  
  134.   
  135.             // System.out.println("getFile:"+str);  
  136.         } catch (MalformedURLException e) {  
  137.             // TODO Auto-generated catch block  
  138.             e.printStackTrace();  
  139.         } catch (IOException e) {  
  140.             // TODO Auto-generated catch block  
  141.             e.printStackTrace();  
  142.         }  
  143.   
  144.         return false;  
  145.     }  
  146.   
  147.     public String getLrcPath(String title, String artist) {  
  148.         return lrcRootPath + title + " - " + artist + ".lrc";  
  149.     }  
  150. }  

LrcProcess 类,用来保存处理下载后的文件

public class LrcProcess {private List lrcList;//List集合存放歌词内容对象private LrcContent mLrcContent;//声明一个歌词内容对象/** * 无参构造函数用来实例化对象 */public LrcProcess() {mLrcContent = new LrcContent();lrcList = new ArrayList();}/** * 读取歌词 * @param path * @return */public String readLRC(String path) {//定义一个StringBuilder对象,用来存放歌词内容StringBuilder stringBuilder = new StringBuilder();File f = new File(path.replace(".mp3", ".lrc"));try {//创建一个文件输入流对象FileInputStream fis = new FileInputStream(f);InputStreamReader isr = new InputStreamReader(fis, "utf-8");BufferedReader br = new BufferedReader(isr);String s = "";while((s = br.readLine()) != null) {//替换字符s = s.replace("[", "");s = s.replace("]", "@");//分离“@”字符String splitLrcData[] = s.split("@");if(splitLrcData.length > 1) {Log.i("INFO", splitLrcData[1]+"歌词");mLrcContent.setLrcStr(splitLrcData[1]);Log.i("INFO", splitLrcData[0]+"时间");//处理歌词取得歌曲的时间int lrcTime = time2Str(splitLrcData[0]);mLrcContent.setLrcTime(lrcTime);//添加进列表数组lrcList.add(mLrcContent);//新创建歌词内容对象mLrcContent = new LrcContent();}}} catch (FileNotFoundException e) {e.printStackTrace();stringBuilder.append("木有歌词文件,赶紧去下载!...");} catch (IOException e) {e.printStackTrace();stringBuilder.append("木有读取到歌词哦!");}return stringBuilder.toString();}/** * 解析歌词时间 * 歌词内容格式如下: * [00:02.32]陈奕迅 * [00:03.43]好久不见 * [00:05.22]歌词制作  王涛 * @param timeStr * @return */public int time2Str(String timeStr) {timeStr = timeStr.replace(":", ".");timeStr = timeStr.replace(".", "@");String timeData[] = timeStr.split("@");//将时间分隔成字符串数组//分离出分、秒并转换为整型int minute = Integer.parseInt(timeData[0]);int second = Integer.parseInt(timeData[1]);int millisecond = Integer.parseInt(timeData[2]);//计算上一行与下一行的时间转换为毫秒数int currentTime = (minute * 60 + second) * 1000 + millisecond * 10;return currentTime;}public List getLrcList() {return lrcList;}


      

Mainactivity 大概调用方法

public class MainActivity extends Activity {      //好久不见    青花    private String mMusicName="夜曲";    //陈奕迅  周传雄    private String mMusicAutor="周杰伦";    @SuppressLint("SdCardPath")    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);               new Thread(){        public void run() {          String lrcURL = OnlineLrcUtil.getLrcURL(mMusicName, mMusicAutor);                          Log.i("INFO", lrcURL+"lrcURL");                 //开始缓存歌词                 boolean b = OnlineLrcUtil.wrtieContentFromUrl(lrcURL, OnlineLrcUtil.getLrcPath(mMusicName, mMusicAutor));                 Log.i("INFO", "缓存歌词"+b);                 Log.i("INFO", OnlineLrcUtil.getLrcPath(mMusicName, mMusicAutor)+"地址");                                  LrcProcess lrcP=new LrcProcess();                 lrcP.readLRC(OnlineLrcUtil.getLrcPath(mMusicName, mMusicAutor));                 Log.i("INFO", "歌词"+lrcP.getLrcList().size());        };        }.start();           }


   


最后附上源码下载地址:

http://download.csdn.net/detail/u014608640/9575221

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. 打包状态下百度的ak的获得
  6. [置顶] android图形系统详解二:Drawables
  7. 多图片上传Android,服务器端实现
  8. 【Android】查看程序每个方法所花费的时间
  9. 生成安卓证书keystor命令文件

随机推荐

  1. 解决Genymotion运行Android 5.0一直卡在
  2. Android Studio连接华为mate8手机调试时
  3. Android 切换日夜间模式
  4. Android Studio启动异常Unable to start
  5. RK平台修改android系统源码设置开机启动a
  6. SMS发送流程 Android2.2
  7. Android 延迟执行方法
  8. Android中安装软件到模拟器时提示:INSTALL
  9. Android Studio执行Java类的main方法及解
  10. android power manager 之 suspend resum