先看看效果图吧,再看代码

转换文件的编码格式

 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卡中获取歌词并与歌曲同步的更多相关文章

  1. Android BaseAdapter ListView (SD卡中文件目录显示出来)

    首先搭建activity_main.xml布局 搭建ListView中显示的布局 创建适配器 将File数据和UI适配 MainActivity中将ListView设置适配器,并设置监听 //获取SD ...

  2. Android中从SD卡中读取歌曲

    先看看我的效果图吧 Activity类 private TextView nameTextView; private SeekBar seekBar; private ListView listVie ...

  3. 将文件放到Android模拟器的SD卡中的两种解决方法

    两种方式:一.窗口界面操作1.打开DDMS页面2.打开File Explorer页,如果没有,在Window --> Show View -->File Explorer3.一般就在mnt ...

  4. Android模拟器使用SD卡

    在Android的应用开发中经常要用到与SD卡有关的调试,本文就是介绍关于在Android模拟器中SD卡的使用 一.      准备工作 在介绍之前首先做好准备工作,即配好android的应用开发环境 ...

  5. Android获取SD卡中选中图片的路径(URL)

    最近在做一个图片上传的功能,需要提供上传图片在SD卡中的路径,在网上看了些例子,改改调试成功,代码很简单.其布局文件如下: [html]  view plain copy   <?xml ver ...

  6. Android中使用SQLiteOpenHelper管理SD卡中的数据库

    使用Android中自带的SQLiteOpenHelper可以完成数据库的创建与管理,但有两点局限: (1)数据库创建在内存卡中,大小受限,创建位置位于/data/data/应用程序名/databas ...

  7. android 读取sd卡中的图片

    一.获取读取SD卡的权限 <!--在SDCard中创建与删除文件权限  -->    <uses-permission android:name="android.perm ...

  8. 转-Android 之 使用File类在SD卡中读取数据文件

    如果需要在程序中使用sdcard进行数据的存储,那么需要在AndroidMainfset.xml文件中 进行权限的配置: Java代码:   <!-- 在sd中创建和删除文件的权限 --> ...

  9. 【Android 界面效果30】Android中ImageSwitcher结合Gallery展示SD卡中的资源图片

    本文主要是写关于ImageSwitcher结合Gallery组件如何展示SDCard中的资源图片,相信大家都看过API Demo 中也有关于这个例子的,但API Demo 中的例子是展示工程中Draw ...

随机推荐

  1. Extracts

    @1:四层和七层负载均衡的区别:所谓四层负载均衡,也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器.以常见的TCP为例,负载均衡设备在接收到第一个 ...

  2. Python(正则 re模块)

    1. 匹配一个字符 表达式 说明 等价表达式 \d 数字 [0-9] \w 字母.数字.下划线 [a-zA-Z0-9_] . 除换行外任意字符   \s 空格 [\t\n\r\f\v] \D 除数字 ...

  3. s5_day4作业

    # #流程控制练习题: # #==========>基础部分 # #练习一: # if True or False and False: # print('yes') # else: # pri ...

  4. Java并发(1):synchronized

    虽然多线程编程极大地提高了效率,但是也会带来一定的隐患.比如说两个线程同时往一个数据库表中插入不重复的数据,就可能会导致数据库中插入了相同的数据.今天我们就来一起讨论下线程安全问题,以及Java中提供 ...

  5. php 内存泄漏

    所谓内存泄漏是指进称在执行过程中,内存的占有率逐步升高,不释放, 系统所拥有的可用内存越来越少的现象. php-fpm耗光内存,不释放,就是所谓的内存泄漏,内存泄漏对长期运行的程序有威胁,所以应该定期 ...

  6. PAT 天梯赛 L1-001 【水】

    L1-001. Hello World 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 这道超级简单的题目没有任何输入. 你只需要在一行中输 ...

  7. Kotlin学习记录1

    参考我的博客:http://www.isedwardtang.com/2017/09/02/kotlin-primer-1/

  8. 【Java】Swing+IO流实现一个简单的文件加密程序(较完整版)

    留着参考 beans package com.my.bean; import java.io.Serializable; public class EncryptedFile implements S ...

  9. Mybatis${}、#{}及使用#{}时指定jdbcType

    一.Mybatis 的Mapper.xml语句中parameterType向SQL语句传参有两种方式:#{}和${} 我们经常使用的是#{},一般解说是因为这种方式可以防止SQL注入,简单的说#{}这 ...

  10. 关于PropertyGrid控件的排序问题

    前些天,由于在项目中需要用到PropertyGrid这个控件,展现其所在控件的某些属性,由于有些控件的属性较多,不易浏览,而且PropertyGrid的排序默认的按照字母的顺序排列的,这样导致在在某些 ...