Android中从SD卡中获取歌词并与歌曲同步
先看看效果图吧,再看代码

转换文件的编码格式
package com.xm; import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader; /**
* 转换文件的编码格式
*
* @author yangchuxi
*
*/
public class ConvertFileCode {
public String converfile(String filepath) {
File file = new File(filepath);
FileInputStream fis = null;
BufferedInputStream bis = null;
BufferedReader reader = null;
String text = "";
try {
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
bis.mark(4);
byte[] first3bytes = new byte[3];
// System.out.println("");
// 找到文档的前三个字节并自动判断文档类型。
bis.read(first3bytes);
bis.reset();
if (first3bytes[0] == (byte) 0xEF && first3bytes[1] == (byte) 0xBB && first3bytes[2] == (byte) 0xBF) {// utf-8 reader = new BufferedReader(new InputStreamReader(bis, "utf-8")); } else if (first3bytes[0] == (byte) 0xFF && first3bytes[1] == (byte) 0xFE) { reader = new BufferedReader(new InputStreamReader(bis, "unicode"));
} else if (first3bytes[0] == (byte) 0xFE && first3bytes[1] == (byte) 0xFF) { reader = new BufferedReader(new InputStreamReader(bis, "utf-16be"));
} else if (first3bytes[0] == (byte) 0xFF && first3bytes[1] == (byte) 0xFF) { reader = new BufferedReader(new InputStreamReader(bis, "utf-16le"));
} else { reader = new BufferedReader(new InputStreamReader(bis, "GBK"));
}
String str = reader.readLine(); while (str != null) {
// text = text + str + "/n";
// str = reader.readLine();
text = text + str + "/n";
str = reader.readLine();
if(str==null){
break;
}
System.out.println(str);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return text;
}
}
代码
读取歌词文件
package com.xm;
/**
* 读取歌词文件
*/
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern; public class LrcHandle {
@SuppressWarnings("unchecked")
private List mWords = new ArrayList(); @SuppressWarnings("unchecked")
private List mTimeList = new ArrayList(); //处理歌词文件
@SuppressWarnings("unchecked")
public void readLRC(String path) {
ConvertFileCode c=new ConvertFileCode();
String a =c.converfile(path);
String[] lists = a.split("\\s"+"\n"+"|/n");
if(mWords!=null){
for(String s:lists){
addTimeToList(s);
if ((s.indexOf("[ar:") != -1) || (s.indexOf("[ti:") != -1)
|| (s.indexOf("[by:") != -1 || (s.indexOf("[offset:") != -1))) {
continue;
} else {
String ss = s.substring(s.indexOf("["), s.indexOf("]") + 1);
s = s.replace(ss, "");
}
mWords.add(s);
}
}else{
mWords.add("没有读取到歌词");
} // ConvertFileCode c=new ConvertFileCode();
// String a=c.converfile("/sdcard/xn.lrc");
// File file = new File(path);
// try {
// FileInputStream fileInputStream = new FileInputStream(file);
// InputStreamReader inputStreamReader = new InputStreamReader(
// fileInputStream);
// BufferedReader bufferedReader = new BufferedReader(
// inputStreamReader);
// String s = "";
// while ((s = bufferedReader.readLine()) != null) {
// addTimeToList(s);
// if ((s.indexOf("[ar:") != -1) || (s.indexOf("[ti:") != -1)
// || (s.indexOf("[by:") != -1)) {
// s = s.substring(s.indexOf(":") + 1, s.indexOf("]"));
// } else {
// String ss = s.substring(s.indexOf("["), s.indexOf("]") + 1);
// s = s.replace(ss, "");
// }
// mWords.add(s);
// }
// bufferedReader.close();
// inputStreamReader.close();
// fileInputStream.close();
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// mWords.add("没有歌词,快去下载");
// } catch (IOException e) {
// e.printStackTrace();
// mWords.add("没有读取到歌词");
// }
}
@SuppressWarnings("unchecked")
public List getWords() {
return mWords;
} @SuppressWarnings("unchecked")
public List getTime() {
return mTimeList;
} // 分离出时间
private int timeHandler(String string) {
string = string.replace(".", ":");
String timeData[] = string.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;
} @SuppressWarnings({ "unchecked", "unused" })
private void addTimeToList(String string) {
Matcher matcher = Pattern.compile(
"\\[\\d{1,2}:\\d{1,2}([\\.:]\\d{1,2})?\\]").matcher(string);
if (matcher.find()) {
String str = matcher.group();
mTimeList.add(new LrcHandle().timeHandler(str.substring(1,
str.length() - 1)));
}
}
}
代码
实现xml
package com.xm; import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.TextView; public class WordView extends TextView {
@SuppressWarnings("unchecked")
private List mWordsList = new ArrayList();
private Paint mLoseFocusPaint;
private Paint mOnFocusePaint;
private float mX = 0;
private float mMiddleY = 0;
private float mY = 0;
private static final int DY = 50;
private int mIndex = 0;
private String name; public WordView(Context context) throws IOException {
super(context);
init();
} public WordView(Context context, AttributeSet attrs) throws IOException {
super(context, attrs);
init();
} public WordView(Context context, AttributeSet attrs, int defStyle)throws IOException {
super(context, attrs, defStyle);
init();
} @Override
protected void onDraw(Canvas canvas) {
if(mWordsList.size()==0){
LrcHandle lrcHandler = new LrcHandle();
lrcHandler.readLRC("/sdcard/"+name);
mWordsList = lrcHandler.getWords();
}
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
Paint p = mLoseFocusPaint;
p.setTextAlign(Paint.Align.CENTER);
Paint p2 = mOnFocusePaint;
p2.setTextAlign(Paint.Align.CENTER);
canvas.drawText((String) mWordsList.get(mIndex), mX, mMiddleY, p2);
int alphaValue = 25;
float tempY = mMiddleY;
for (int i = mIndex - 1; i >= 0; i--) {
tempY -= DY;
if (tempY < 0) {
break;
}
p.setColor(Color.argb(255 - alphaValue, 245, 245, 245));
canvas.drawText((String) mWordsList.get(i), mX, tempY, p);
alphaValue += 25;
}
alphaValue = 25;
tempY = mMiddleY;
for (int i = mIndex + 1, len = mWordsList.size(); i < len; i++) {
tempY += DY;
if (tempY > mY) {
break;
}
p.setColor(Color.argb(255 - alphaValue, 245, 245, 245));
canvas.drawText((String) mWordsList.get(i), mX, tempY, p);
alphaValue += 25;
}
mIndex++;
} @Override
protected void onSizeChanged(int w, int h, int ow, int oh) {
super.onSizeChanged(w, h, ow, oh);
mX = w * 0.5f;
mY = h;
mMiddleY = h * 0.3f;
} // @SuppressLint("SdCardPath")
private void init() throws IOException {
setFocusable(true);
// LrcHandle lrcHandler = new LrcHandle();
// lrcHandler.readLRC("/sdcard/wwyx.lrc");
// mWordsList = lrcHandler.getWords(); mLoseFocusPaint = new Paint();
mLoseFocusPaint.setAntiAlias(true);
mLoseFocusPaint.setTextSize(22);
mLoseFocusPaint.setColor(Color.WHITE);
mLoseFocusPaint.setTypeface(Typeface.SERIF); mOnFocusePaint = new Paint();
mOnFocusePaint.setAntiAlias(true);
mOnFocusePaint.setColor(Color.YELLOW);
mOnFocusePaint.setTextSize(30);
mOnFocusePaint.setTypeface(Typeface.SANS_SERIF);
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
代码
xml配置文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF"
>
<TableLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
>
<TableRow>
<ImageButton
android:id="@+id/ibgc1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/hh"
android:background="#00000000"
android:layout_marginLeft="10px"
android:layout_marginRight="98px"
/>
</TableRow>
</TableLayout>
<TableLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TableRow>
<com.xm.WordView
android:id="@+id/text"
android:layout_width="330px"
android:layout_height="355px"
/>
</TableRow>
</TableLayout>
<TableLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#FFFFFF"
android:layout_alignParentBottom="true"
android:layout_marginTop="10px"
>
<TableRow>
<Button
android:id="@+id/bt10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始"
android:background="#FFFFFF"
android:layout_marginLeft="30px"
/>
<Button
android:id="@+id/bt11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂停"
android:background="#FFFFFF"
android:layout_marginLeft="180px"
/>
</TableRow>
</TableLayout>
</LinearLayout>
xml
Activity类
private WordView mWordView;
private List mTimeList;
private MediaPlayer mPlayer;
private boolean isPause;
private boolean isStartTrackingTouch;
final Handler handler = new Handler();
bt10 = (Button) findViewById(R.id.bt10);
bt10.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mPlayer.start();
isPause = false;
new Thread(new Runnable() {
int i = 0;
@Override
public void run() {
while (mPlayer.isPlaying()) {
handler.post(new Runnable() {
@Override
public void run() {
mWordView.invalidate();
}
});
try {
int a = Integer.parseInt(String.valueOf(mTimeList
.get(i + 1)));
int b = Integer.parseInt(String.valueOf(mTimeList
.get(i)));
Thread.sleep(a - b);
} catch (Exception e) {
}
i++;
if (i == mTimeList.size() - 1) {
mPlayer.stop();
break;
}
}
}
}).start();
}
});
bt11 = (Button) findViewById(R.id.bt11);
bt11.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mPlayer.pause();
isPause = true;
}
});
LrcHandle lrcHandler = new LrcHandle();
String name1 = getIntent().getStringExtra("name");
String str=name1.substring(0,name1.indexOf('.'));
String str1=str+".lrc";
String name2 = getIntent().getStringExtra("name");
mWordView = (WordView) findViewById(R.id.text);
mWordView.setName(str1);
mPlayer = new MediaPlayer();
mPlayer.reset();
try {
lrcHandler.readLRC("/sdcard/"+str1);
mTimeList = lrcHandler.getTime();
mPlayer.setDataSource("/sdcard/"+name2);
mPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
代码
Android中从SD卡中获取歌词并与歌曲同步的更多相关文章
- Android BaseAdapter ListView (SD卡中文件目录显示出来)
首先搭建activity_main.xml布局 搭建ListView中显示的布局 创建适配器 将File数据和UI适配 MainActivity中将ListView设置适配器,并设置监听 //获取SD ...
- Android中从SD卡中读取歌曲
先看看我的效果图吧 Activity类 private TextView nameTextView; private SeekBar seekBar; private ListView listVie ...
- 将文件放到Android模拟器的SD卡中的两种解决方法
两种方式:一.窗口界面操作1.打开DDMS页面2.打开File Explorer页,如果没有,在Window --> Show View -->File Explorer3.一般就在mnt ...
- Android模拟器使用SD卡
在Android的应用开发中经常要用到与SD卡有关的调试,本文就是介绍关于在Android模拟器中SD卡的使用 一. 准备工作 在介绍之前首先做好准备工作,即配好android的应用开发环境 ...
- Android获取SD卡中选中图片的路径(URL)
最近在做一个图片上传的功能,需要提供上传图片在SD卡中的路径,在网上看了些例子,改改调试成功,代码很简单.其布局文件如下: [html] view plain copy <?xml ver ...
- Android中使用SQLiteOpenHelper管理SD卡中的数据库
使用Android中自带的SQLiteOpenHelper可以完成数据库的创建与管理,但有两点局限: (1)数据库创建在内存卡中,大小受限,创建位置位于/data/data/应用程序名/databas ...
- android 读取sd卡中的图片
一.获取读取SD卡的权限 <!--在SDCard中创建与删除文件权限 --> <uses-permission android:name="android.perm ...
- 转-Android 之 使用File类在SD卡中读取数据文件
如果需要在程序中使用sdcard进行数据的存储,那么需要在AndroidMainfset.xml文件中 进行权限的配置: Java代码: <!-- 在sd中创建和删除文件的权限 --> ...
- 【Android 界面效果30】Android中ImageSwitcher结合Gallery展示SD卡中的资源图片
本文主要是写关于ImageSwitcher结合Gallery组件如何展示SDCard中的资源图片,相信大家都看过API Demo 中也有关于这个例子的,但API Demo 中的例子是展示工程中Draw ...
随机推荐
- JAVA垃圾回收笔记
一.分析GC日志 /** * @author : Hejinsheng * @date : 2019/1/18 0018 * @Description: 模拟FULL GC/YOUNG GC * -X ...
- 分支语句(switch case)
/switch case 的应用 Console.WriteLine("1.汉堡包"); Console.WriteLine("2.薯条"); Console. ...
- Apache 浏览器访问限制配置
浏览器访问限制配置 user_agent收入的浏览器中,我们通过百度,谷歌很容易就可以查到相关的一些资料,方便了我们对知识的查找,但在某些特定情况下,我们并不希望有人可以通过某写搜索引擎直接访问到我们 ...
- 部署 LAMP (CentOS 7.2),摘自阿里云,方便查看使用
原文地址:https://help.aliyun.com/document_detail/50774.html?spm=5176.product25365.6.728.C9s3V8 简介 LAMP指L ...
- HDU 1238 Substing
思路: 1.找出n个字符串中最短的字符串Str[N] 2.从长到短找Str[N]的子子串 subStr[N],以及subStr[N]的反转字符串strrev(subStr[N]):(从长到短是做剪枝处 ...
- codevs.cn 2776寻找代表元 最大流解法
网址:http://codevs.cn/problem/2776/ 题目大意: n个社团,m个人,每个社团可以有一个人担任代表,每个人可以担任多个代表,问最多有多少人是代表. 思路:可以建一个图,然后 ...
- Nginx Rewrite 规则入门 伪静态规则
文件及目录匹配: -f 和 !-f 用来判断是否存在文件 -d 和 !-d 用来判断是否存在目录 -e 和 !-e 用来判断是否存在文件或目录 -x 和 !-x 用来判断文件是否可执行 正则表达式匹配 ...
- DPDK之(八)——vhost库
转:http://www.cnblogs.com/danxi/p/6652725.html vhost库实现了一个用户空间的virtio net server,允许用户直接处理virtio ring队 ...
- localhost不能访问127.0.0.1可以访问的原因以及解决办法
今天在调试程序的时候,出现了一个奇怪问题,localhost不能访问但127.0.0.1可以访问? localhost与127.0.0.1的概念和工作原理之不同 要比较两个东西有什么不同,首先要弄清两 ...
- LeetCode第[4]题(Java):Median of Two Sorted Arrays (俩已排序数组求中位数)——HARD
题目难度:hard There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median ...