Android 音樂播放器實現歌詞顯示
LrcHandle.java:
package com.example.welcome;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/***
* 獲取時間以及對應的歌詞
*
* @author chao
*
*/
public class LrcHandle {
private List<String> mWords = new ArrayList<String>();
private List<Integer> mTimeList = new ArrayList<Integer>();
// 處理歌詞文件
public void readLRC(String path) {
File file = new File(path);
try {
FileInputStream fileInputStream = new FileInputStream(file);
InputStreamReader inputStreamReader = new InputStreamReader(
fileInputStream, "GBK");
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 {
// ss為時間 [02:12.22]
String ss = s.substring(s.indexOf("["), s.indexOf("]") + 1);
// s為ss時間後的歌詞
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("沒有讀取到歌詞");
}
}
public List<String> getWords() {
return mWords;
}
public List<Integer> 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;
}
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)));
}
}
}
WordView.java:
package com.example.welcome;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
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 {
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;
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) {
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/aa.lrc");
mWordsList = lrcHandler.getWords();
mLoseFocusPaint = new Paint();
mLoseFocusPaint.setAntiAlias(true);
mLoseFocusPaint.setTextSize(22);
mLoseFocusPaint.setColor(Color.WHITE);
mLoseFocusPaint.setTypeface(Typeface.MONOSPACE);
mOnFocusePaint = new Paint();
mOnFocusePaint.setAntiAlias(true);
mOnFocusePaint.setColor(Color.YELLOW);
mOnFocusePaint.setTextSize(40);
mOnFocusePaint.setTypeface(Typeface.SANS_SERIF);
}
}
MainActivity.java:
package com.example.welcome;
import java.io.IOException;
import java.util.List;
import android.R.integer;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private WordView mWordView;
private List mTimeList;
private MediaPlayer mPlayer;
@SuppressLint("SdCardPath")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mPlayer.stop();
finish();
}
});
mWordView = (WordView) findViewById(R.id.text);
mPlayer = new MediaPlayer();
mPlayer.reset();
LrcHandle lrcHandler = new LrcHandle();
try {
lrcHandler.readLRC("/sdcard/aa.lrc");
mTimeList = lrcHandler.getTime();
mPlayer.setDataSource("/sdcard/e.mp3");
mPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
final Handler handler = new Handler();
mPlayer.start();
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 {
Thread.sleep(Integer.parseInt(mTimeList.get(i + 1)
.toString())
- Integer.parseInt(mTimeList.get(i).toString()));
} catch (InterruptedException e) {
}
i++;
if (i == mTimeList.size() - 1) {
mPlayer.stop();
break;
}
}
}
}).start();
}
}
main.xml:
<RelativeLayout 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"
tools:context=".MainActivity" >
<Button
android:id="@+id/button"
android:layout_width="60dip"
android:layout_height="60dip"
android:text="stop" />
<com.example.welcome.WordView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/button"
android:text="song" />
</RelativeLayout>
更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11