我的第一个安卓应用---音乐播放器

前几天接触了安卓,了解了一些知识。首先就是Activity,这个在之前有提到,所以在这里就不多说了。然后就是在实现了一个能够画直线,曲线的app,在这里,说下onTouchEvent()方法(就是对手机屏幕进行监听),在这个方法中,系统可以监听到你对屏幕的所作所为,所以呢,你画图形的所有坐标应该是从这个方法中获得;

当坐标获取之后,然后就是获取画布和画笔,这个和java相比,就比较容易一些,可以直接去创建画布、画笔对象;然后就可以画图形了。之前的这些操作只是让你能够画出图形,但是想要保存你画的图形,也就是重绘,那么就要用到Bitmap这个类,具体操作是让你的画布和这个Bitmap关联起来,当你把图形画完之后,最后在将这个Bitmap画出来,就能实现重绘功能了。具体代码如下:

protected void onDraw(Canvas canvas){
		//创建一个画布,并且和Bitmap关联起来
		c=new Canvas(bitmap);
		//创建一个画笔
		Paint paint=new Paint();
		//设置画笔颜色
		paint.setColor(Color.RED);
		//画直线
		c.drawLine(x1, y1, x2, y2, paint);	
		//最后将Bitmap在画一次
		canvas.drawBitmap(bitmap, 0,0, null);
接下来就是我的音乐播放器的实现了

在这里,我就简单介绍下我实现对音乐文件的搜索、歌词搜索、歌词和歌曲同步的方法

对音乐文件的搜索,这个是根据Cursor实现的,调用ContentResolver 的query方法可以将内存卡上的所以音乐文件都找到,然后放在cursor中,遍历cursor的时候,根据cursor.moveToNext()方法,如果corsor中没有数据,那么这个方法返回false。然后根据MediaStroe可以找出音乐文件的信息,

while(cursor.moveToNext()){
				Map<String,Object> map=new HashMap<String,Object>();
				//获取歌曲的绝对路径				
				String path=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
				//获取歌曲名
				String name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
				String title=cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
				//获取歌曲总时间
				long time = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));	
				//转换格式
				Date date=new Date(time);
				SimpleDateFormat format=new SimpleDateFormat("mm:ss");
				String s=format.format(date);
				//将得到的内容添加到map中
				map.put("image", R.drawable.backs);
				map.put("songname", name);
				map.put("time", s);
				map.put("path", path);
				map.put("title", title);
				//将map添加到list中
				list.add(map);
			}


首先歌词的搜索,这个就相当于是将你的内存卡遍历一遍,然后找出后缀是.lrc的文件,最后把找到的文件放到一个list中,以便后面方便查询,下面是具体的代码

public void findLrc(String path){
		//创建一个file对象
		File file=new File(path);
		if(file.exists()){		
			if(file.isFile()){			
				if(file.getName().contains(".lrc")){					
					String s=file.getAbsolutePath();
					Map<String,Object> map=new HashMap<String,Object>();
					map.put("url",s );
					map.put("title", file.getName().substring(0, file.getName().length()-".lrc".length()));
					FindMusic.list_lrc.add(map);				
				}				
			}
			else if(file.isDirectory()){				
				//如果是文件夹,就要遍历文件夹下的所有文件或目录
				//创建一个File数组
				File[] files=file.listFiles();
				if(files!=null){					
					for(File f:files){						
						//递归调用自身
						findLrc(f.getAbsolutePath());
					}
				}
			}
		}
	}
然后实现歌词和歌曲同步,这个就要牵扯到文件的读写,再之前找音乐文件的时候,可以通过cursor找到歌曲的标题,所以在你播放音乐的时候,音乐的标题就可以获得,因为歌词名和歌曲名的标题都是一样的,所以就可以根据当前播放的音乐的标题在歌词list中找到歌词,当找到歌词后,就要读写了,因为歌词都是一行一行出现的,所以,在读的时候,我是把歌词文件封装成一个流,然后去一行一行的读,这样不容易出错,效率也相对高一些,下面的代码就是将一个文件封装成一个流

FileInputStream fis =new FileInputStream(file);
InputStreamReader is=new InputStreamReader(fis);
BufferedReader br=new BufferedReader(is);
然后调用br.readline()方法。

当歌词读到之后,就是要分离歌词中信息了,这个主要是把时间分离出来。因为br.readline()这个方法的返回类型是一个String类型,所以分离的时候就用replace()、split()来分离,具体操作如下

String time=line.substring(0, line.indexOf("]")+1);                 //因为在歌词中,时间都是放在一对【】中,所以要把时间取出来
				time=time.replace("[", "");	    //歌词中时间的格式是mm:ss.xx,所以要把:和.代替掉,
				time=time.replace("]", "");
				time=time.replace(".", ":");	    //在这里不能写成time=time.replace(":", ".");因为‘.’会转义
				lrc_time=time.split(":");	   //根据:将time分离出来

然后再将时间和对应的歌词加到list中,

 List<Map<String,String>> time_list=new ArrayList<Map<String,String>>();
	Map<String,String> map=new HashMap<String,String>();
					map.put("time",lrc_time[0]+":"+lrc_time[1]);
					map.put("line",line);
					time_list.add(map);
歌词中的时间分离出来后,就要和音乐播放的时间去比较,如果相同的话,就显示歌词时间对应的歌词

				p=mp.getCurrentPosition();
					Date date=new Date(p);
					SimpleDateFormat format=new SimpleDateFormat("mm:ss");
					s=format.format(date);
					//判断当前播放时间和歌词时间列表中的内容,如果相同,就显示到TextView上
					for(final Map<String, String> t:time_list){
						String str = t.get("time");
						if(s.equals(str)){
							show_loyic.post(new Runnable(){
								public void run(){
									show_loyic.setText(t.get("line"));
								}
							});
						}
					}

以上操作就能够把歌词和音乐同步了看下效果图





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
一.创建一个DataBaseHelper DataBaseHelper是一个访问SQLite的助类,提供两个方面的功能 1.getReadableDatebase(),getWriteableDatabase()可以获取SQLiteDatabase对象,通过 2.提供了onCreate()和onUpdate()两个回调函数,允许我们常见和升级数据库是进行使用 A、 在SQLiteOpenHelper的子类当中,必须要有的构造函数 B、该函数是在第一次创建数据库的时候执行,实际上是在第一次得到SQLiteDataBase对象的时候onCreate 二、创建一个实体person类并且给字段和封装 三、创建一个业务类对SQL的CRUD操作 1.getWritableDatabase()和getReadableDatabase()的区别 ,两个方法都可以获取一个用于操作数据库的SQLiteDatabase实例 2.execSQL(增,删,改都是这个方法)和close();android内部有缓存可关闭也不关闭也行,查询rawQuery是方法 3.在分页有到Cursor(游标)取游标下一个值cursor.moveToNext(),用游标对象接数据 "select * from person limit ?,?" person不能加上where 关键字 4.在删除注意:sb.deleteCharAt(sb.length() - 1); 四、AndroidCRUD业务对SQLite的CRUD操作 1.ContentValues对象的使用 2.android内部insert添加数据的方法,而且values这个不给值也必须要执行,而主键是不是null的其他字段的值是为null 3.insert update query delete 五、单元测试类要注意的 AndroidCRUDService curdService = new AndroidCRUDService(this.getContext()); /* * 注意:getContext必须在我们使用前已经注解进去的,在使用前要实力化,而且是使用后才有上下文 *一般设置为局部对象 */ 六、AndroidManifest.xml的配置 <!-- 配置用户类库android.test.runner测试 --> package jll.sqlitedb; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteDatabase.CursorFactory; /** * *@author Administrator DataBaseHelper是一个访问SQLite的助类,提供两个方面的功能 * 1.getReadableDatebase(),getWriteableDatabase()可以获取SQLiteDatabase对象,通过 * 2.提供了onCreate()和onUpdate()两个回调函数,允许我们常见和升级数据库是进行使用 */ public class DataBaseHelper extends SQLiteOpenHelper { // 给一个默认的SQLite的数据库名 private static final String DataBaseName = "SQLite_DB"; private static final int VERSION = 2; // 在SQLiteOpenHelper的子类当中,必须要有的构造函数 public DataBaseHelper(Context context, String name, CursorFacto
package cn.iimob.waiters.db; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DB_Table_Number extends SQLiteOpenHelper { private static final String DB_NAME = "tablenumber.db"; private static final String TBL_NAME = "TableNumber"; private static final String CREATE_TBL = " create table " + " TableNumber(_id integer primary key autoincrement,number text) "; static String tempall=""; private SQLiteDatabase db; public DB_Table_Number(Context c) { super(c, DB_NAME, null, 2); } public void onCreate(SQLiteDatabase db) { this.db = db; db.execSQL(CREATE_TBL); } public void insert(ContentValues values) { SQLiteDatabase db = getWritableDatabase(); db.insert(TBL_NAME, null, values); db.close(); } public Cursor query() { SQLiteDatabase db = getWritableDatabase(); Cursor c = db.query(TBL_NAME, null, null, null, null, null, null); return c; } public String select(String s){ SQLiteDatabase db = getWritableDatabase(); String sql="select *from TableNumber " + "where number='"+s+"'"; Cursor cursor=db.rawQuery(sql, null); if (cursor != null) { String temp = ""; int i = 0; while (cursor.moveToNext()) { temp+=cursor.getString(0); } tempall=temp; cursor.close(); } return tempall; } public void delete(String s) { SQLiteDatabase db = getWritableDatabase(); String sql="delete from TableNumber " + "where number='"+s+"'"; db.execSQL(sql); } public void close() { if (db != null) db.close(); } public void clean (){ this.getWritableDatabase().execSQL("DROP TABLE IF EXISTS "+TBL_NAME); this.onCreate(this.getWritableDatabase()); this.getWritableDatabase().close(); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值