android示例:简单的播放MP3并显示歌词的应用(待更新)
2017-03-10 16:34
615 查看
闲来无事,写了个小应用,能够播放固定的MP3,并显示歌词,待改进地方有:
1 可播放目录内所有歌曲文件,并同时显示歌词
2 有进度条
3 可快进,回退,停止等
待弄明白的是:判断何时是唱歌的的起始点。
以下为示例:
布局文件main.xml
歌词view:
主文件:
manifest文件:
1 可播放目录内所有歌曲文件,并同时显示歌词
2 有进度条
3 可快进,回退,停止等
待弄明白的是:判断何时是唱歌的的起始点。
以下为示例:
布局文件main.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:local="http://schemas.android.com/apk/res/com.android.test" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/startbt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:layout_gravity="center" android:text="@string/start"> </Button> <com.android.test.view.LyricView android:id="@+id/mylrc" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:layout_gravity="center" android:layout_marginTop="0dp" android:layout_marginBottom="0dp" android:background="@drawable/bg" android:visibility="gone" /> </FrameLayout>
歌词view:
package com.android.test.view; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.util.Currency; import java.util.Iterator; import java.util.TreeMap; import java.util.regex.Pattern; import android.R.integer; import android.app.ActionBar.Tab; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.text.StaticLayout; import android.text.TextPaint; import android.text.Layout.Alignment; import android.util.AttributeSet; import android.util.Log; import android.widget.RelativeLayout; public class LyricView extends RelativeLayout { private static String TAG = "qjy"; private TextPaint mPaint; private int currentIndex = 0; private String currentLrc = null; private static TreeMap<Integer, LyricObject> lrc_map; public LyricView(Context context) { super(context); init(); } public LyricView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { lrc_map = new TreeMap<Integer, LyricView.LyricObject>(); mPaint = new TextPaint(); mPaint.setColor(Color.RED); mPaint.setTextSize(20); // mPaint.setTextAlign(Paint.Align.CENTER); Thread myThread = new Thread(new Runnable() { @Override public void run() { try { read("/data/app/test.lrc"); } catch (Exception e) { Log.e(TAG, "ERROR: can not read test.lrc"); } } }); myThread.start(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Log.e(TAG, "LyricView onDraw start"); // LyricObject ones = lrc_map.get(5); if (currentIndex < 6) { StringBuilder testString = new StringBuilder(); for (int j = 0; j < 6; j++) { if (testString.toString() != null) { testString.append("\n\r"); } testString.append(lrc_map.get(j).lrc); } StaticLayout layout = new StaticLayout(testString.toString(), mPaint, getMeasuredWidth()-getPaddingLeft()-getPaddingRight(), Alignment.ALIGN_CENTER, 1, 0, true); canvas.save(); layout.draw(canvas); canvas.restore(); return; } currentLrc = lrc_map.get(currentIndex).lrc; Rect boundRect = new Rect(); mPaint.getTextBounds(currentLrc, 0,currentLrc.length(), boundRect); canvas.drawText(currentLrc, getMeasuredWidth()/2 - boundRect.width()/2 , getMeasuredHeight()/2 + boundRect.height()/2, mPaint); } public void setTime(int time){ int c; if (currentIndex == (lrc_map.size()-1)) { return; } for (c = currentIndex; c < lrc_map.size()-1; c++) { if (time > lrc_map.get(c).begintime && time < lrc_map.get(c+1).begintime) { currentIndex = c; break; }else if (time > lrc_map.get(lrc_map.size()-1).begintime) { currentIndex = lrc_map.size()-1; break; } } Log.e(TAG, "current index is "+currentIndex); } public static void read(String file) { String data; String mTime; int min; int sec; int ms; int i = 0; LyricObject item; Log.e(TAG, "start to read ! "); lrc_map.clear(); try { File f = new File(file); FileInputStream fis = new FileInputStream(f); BufferedReader br = new BufferedReader(new InputStreamReader(fis, "GB2312")); Pattern pattern = Pattern.compile("[0-9]*"); while ((data = br.readLine()) != null) { item = new LyricObject(); mTime = data.substring(data.indexOf("[") + 1, data.indexOf("]")); if (pattern.matcher(mTime.substring(0, mTime.indexOf(":"))).matches()) { min = Integer.parseInt(mTime.substring(0, mTime.indexOf(":"))); sec = Integer.parseInt(mTime.substring(mTime.indexOf(":")+1, mTime.indexOf("."))); ms = Integer.parseInt(mTime.substring(mTime.indexOf(".")+1)); item.begintime = (min*60 + sec)*1000 + ms; item.lrc = data.substring(data.indexOf("]")+1); } else { item.begintime = 0; item.lrc = mTime; } Log.e(TAG, "i IS " + i); lrc_map.put(new Integer(i), item); Log.e(TAG, "begintime IS " + lrc_map.get(i).begintime); Log.e(TAG, "LRC IS " + lrc_map.get(i).lrc); i++; } fis.close(); } catch (Exception e) { Log.e(TAG, "ERROR can not read! "); e.printStackTrace(); } } protected static class LyricObject { protected int begintime; protected int endtime; protected int consume; protected String lrc; } }
主文件:
package com.android.test; import com.android.test.view.LyricView; import com.android.test.view.TitleView; import android.app.Activity; import android.os.Bundle; import android.os.Message; import android.util.Log; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.widget.Button; import android.view.View.OnClickListener; import android.content.res.Configuration; import android.media.MediaPlayer; import android.os.Handler; public class MActivity extends Activity { String TAG = c1c6 "qjy"; Button myButton; LyricView mv; TitleView mtv; Thread spThread; Thread lrcT; private String mp3 = "file:///data/app/test.mp3"; MediaPlayer myMP; Handler mHandler = new Handler(){ public void handleMessage(Message msg){ Log.e(TAG, "handlerMessage"); switch (msg.what) { case 0: mv.setTime(msg.arg1); mv.invalidate(); break; default: break; } super.handleMessage(msg); } }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main); Log.d(TAG, "onCreate"); myButton =(Button) findViewById(R.id.startbt); mv = (LyricView) findViewById(R.id.mylrc); mtv = (TitleView) findViewById(R.id.mytv); myButton.setOnClickListener(mListener); myMP = new MediaPlayer(); } OnClickListener mListener = new OnClickListener() { @Override public void onClick(View v) { myButton.setVisibility(View.GONE); mtv.setVisibility(View.GONE); mv.setVisibility(View.VISIBLE); mv.invalidate(); try { myMP.setDataSource(mp3); myMP.prepare(); } catch (Exception e) { Log.e(TAG, "ERROR: can not start mediaplayer"); e.printStackTrace(); } startPlayer(); } }; private void startPlayer() { spThread = new Thread(new Runnable() { @Override public void run() { myMP.start(); } }); lrcT = new Thread(new Runnable() { Message msg; @Override public void run() { try { while (true) { Thread.sleep(1000); Log.e(TAG, "current position is " + myMP.getCurrentPosition()); msg = mHandler.obtainMessage(); msg.arg1 = myMP.getCurrentPosition(); msg.what = 0; mHandler.sendMessage(msg); } } catch (Exception e) { Log.e(TAG, "ERROR: set current position!"); e.printStackTrace(); } } }); spThread.start(); lrcT.start(); } @Override public void onStart() { super.onStart(); Log.d(TAG, "onStart"); } @Override public void onRestart() { super.onRestart(); Log.d(TAG, "onRestart"); } @Override public void onPause() { super.onPause(); Log.d(TAG, "onPause"); } @Override public void onResume() { super.onResume(); Log.d(TAG, "onResume"); } @Override public void onStop() { super.onStop(); Log.d(TAG, "onStop"); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy"); spThread.interrupt(); lrcT.interrupt(); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); Log.d(TAG, "onSaveInstanceState"); } @Override public void onRestoreInstanceState(Bundle outState) { super.onRestoreInstanceState(outState); Log.d(TAG, "onRestoreInstanceState"); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Log.d(TAG, "onConfigurationChanged"); } }
manifest文件:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.test" android:versionCode="1" android:versionName="1.0"> <application android:label="@string/app_name" android:icon="@drawable/ic_launcher"> <activity android:name="MActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
相关文章推荐
- Android MediaPlayer 简单综合应用------列出sdcard里所有.mp3文件,并且可以点击播放!
- Android MediaPlayer 简单综合应用------列出sdcard里所有.mp3文件,并且可以点击播放!
- Android MediaPlayer 简单综合应用------列出sdcard里所有.mp3文件,并且可以点击播放!
- android之视频播放控件VideoView简单应用
- 比较完整的android MP3 LRC歌词滚动高亮显示(附源码)
- 【Android】入门级连接网络示例: 网页浏览和播放网络MP3
- android之视频播放控件VideoView简单应用
- android开发--mp3播放器项目源代码(xml文件解析,.lrc,.mp3文件下载,同时显示歌词)
- Android切换系统语言,自动更新应用界面显示语言
- 基于网络音频的Android播放程序简单示例
- Android实现歌曲播放时歌词同步显示具体思路
- android之视频播放控件VideoView简单应用
- 一个算是比较完整的android MP3 LRC歌词滚动高亮显示
- Android 实现歌曲播放时歌词同步显示
- Android深入浅出系列之实例应用—简单的手指拖动图片,图片滑来滑去显示应用Gallery和BaseAdapter以及ImageView的使用
- Android 实现歌曲播放时歌词同步显示
- Android深入浅出系列之实例应用—简单的手指拖动图片,图片滑来滑去显示应用Gallery和BaseAdapter以及ImageView的使用
- Android深入浅出系列之实例应用—简单的手指拖动图片,图片滑来滑去显示应用Gallery和BaseAdapter以及ImageView的使用
- 【Android】入门级连接网络示例: 网页浏览和播放网络MP3
- 最简单、简易的android音乐播放器,android开发应用之(音乐播放)