Android 使用Vitamio打造自己的万能播放器(4)——本地播放(快捷搜索、数据存储)
前言
关键字:vitamio、vplayer、android播放器、android影音、android开源播放器
本章节把android万能播放器本地播放的主要功能(缓存播放列表和a-z快速查询功能)完成,和播放组件关系不大,但用到一些实用的技术,欢迎交流!
系列
1、android 使用vitamio打造自己的万能播放器(1)——准备
2、android 使用vitamio打造自己的万能播放器(2)—— 手势控制亮度、音量、缩放
3、android 使用vitamio打造自己的万能播放器(3)——本地播放(主界面、播放列表)
正文
一、目标
1.1 a-z快速切换查找影片
把手机上的联系人上的a-z快速查找运用到了这里,查找文件更便捷。这也是"学"的米聊的 :)
1.2 缓存扫描视频列表
首次使用扫描sd卡一遍,以后就从数据库读取了,下篇文章再加一个监听即可。
1.3 截图
二、实现
核心代码:
public class fragmentfile extends fragmentbase implements onitemclicklistener { private fileadapter madapter; private textview first_letter_overlay; private imageview alphabet_scroller; @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { view v = super.oncreateview(inflater, container, savedinstancestate); // ~~~~~~~~~ 绑定控件 first_letter_overlay = (textview) v.findviewbyid(r.id.first_letter_overlay); alphabet_scroller = (imageview) v.findviewbyid(r.id.alphabet_scroller); // ~~~~~~~~~ 绑定事件 alphabet_scroller.setclickable(true); alphabet_scroller.setontouchlistener(asontouch); mlistview.setonitemclicklistener(this); // ~~~~~~~~~ 加载数据 if (new sqlitehelper(getactivity()).isempty()) new scanvideotask().execute(); else new datatask().execute(); return v; } /** 单击启动播放 */ @override public void onitemclick(adapterview<?> parent, view view, int position, long id) { final pfile f = madapter.getitem(position); intent intent = new intent(getactivity(), videoviewdemo.class); intent.putextra("path", f.path); startactivity(intent); } private class datatask extends asynctask<void, void, arraylist<pfile>> { @override protected void onpreexecute() { super.onpreexecute(); mloadinglayout.setvisibility(view.visible); mlistview.setvisibility(view.gone); } @override protected arraylist<pfile> doinbackground(void... params) { return filebusiness.getallsortfiles(getactivity()); } @override protected void onpostexecute(arraylist<pfile> result) { super.onpostexecute(result); madapter = new fileadapter(getactivity(), filebusiness.getallsortfiles(getactivity())); mlistview.setadapter(madapter); mloadinglayout.setvisibility(view.gone); mlistview.setvisibility(view.visible); } } /** 扫描sd卡 */ private class scanvideotask extends asynctask<void, file, arraylist<pfile>> { private progressdialog pd; private arraylist<file> files = new arraylist<file>(); @override protected void onpreexecute() { super.onpreexecute(); pd = new progressdialog(getactivity()); pd.setmessage("正在扫描视频文件..."); pd.show(); } @override protected arraylist<pfile> doinbackground(void... params) { // ~~~ 遍历文件夹 eachallmedias(environment.getexternalstoragedirectory()); // ~~~ 入库 sqlitehelper sqlite = new sqlitehelper(getactivity()); sqlitedatabase db = sqlite.getwritabledatabase(); try { db.begintransaction(); sqlitestatement stat = db.compilestatement("insert into files(" + filescolumns.col_title + "," + filescolumns.col_title_pinyin + "," + filescolumns.col_path + "," + filescolumns.col_last_access_time + ") values(?,?,?,?)"); for (file f : files) { string name = fileutils.getfilenamenoex(f.getname()); int index = 1; stat.bindstring(index++, name);//title stat.bindstring(index++, pinyinutils.chinenetospell(name));//title_pinyin stat.bindstring(index++, f.getpath());//path stat.bindlong(index++, system.currenttimemillis());//last_access_time stat.execute(); } db.settransactionsuccessful(); } catch (badhanyupinyinoutputformatcombination e) { e.printstacktrace(); } catch (exception e) { e.printstacktrace(); } finally { db.endtransaction(); db.close(); } // ~~~ 查询数据 return filebusiness.getallsortfiles(getactivity()); } @override protected void onprogressupdate(final file... values) { file f = values[0]; files.add(f); pd.setmessage(f.getname()); } /** 遍历所有文件夹,查找出视频文件 */ public void eachallmedias(file f) { if (f != null && f.exists() && f.isdirectory()) { file[] files = f.listfiles(); if (files != null) { for (file file : f.listfiles()) { if (file.isdirectory()) { eachallmedias(file); } else if (file.exists() && file.canread() && fileutils.isvideooraudio(file)) { publishprogress(file); } } } } } @override protected void onpostexecute(arraylist<pfile> result) { super.onpostexecute(result); madapter = new fileadapter(getactivity(), result); mlistview.setadapter(madapter); pd.dismiss(); } } private class fileadapter extends arrayadapter<pfile> { public fileadapter(context ctx, arraylist<pfile> l) { super(ctx, l); } @override public view getview(int position, view convertview, viewgroup parent) { final pfile f = getitem(position); if (convertview == null) { final layoutinflater minflater = getactivity().getlayoutinflater(); convertview = minflater.inflate(r.layout.fragment_file_item, null); } ((textview) convertview.findviewbyid(r.id.title)).settext(f.title); return convertview; } } /** * a-z */ private ontouchlistener asontouch = new ontouchlistener() { @override public boolean ontouch(view v, motionevent event) { switch (event.getaction()) { case motionevent.action_down:// 0 alphabet_scroller.setpressed(true); first_letter_overlay.setvisibility(view.visible); mathscrollerposition(event.gety()); break; case motionevent.action_up:// 1 alphabet_scroller.setpressed(false); first_letter_overlay.setvisibility(view.gone); break; case motionevent.action_move: mathscrollerposition(event.gety()); break; } return false; } }; /** * 显示字符 * * @param y */ private void mathscrollerposition(float y) { int height = alphabet_scroller.getheight(); float charheight = height / 28.0f; char c = 'a'; if (y < 0) y = 0; else if (y > height) y = height; int index = (int) (y / charheight) - 1; if (index < 0) index = 0; else if (index > 25) index = 25; string key = string.valueof((char) (c + index)); first_letter_overlay.settext(key); int position = 0; if (index == 0) mlistview.setselection(0); else if (index == 25) mlistview.setselection(madapter.getcount() - 1); else { for (pfile item : madapter.getall()) { if (item.title_pinyin.startswith(key)) { mlistview.setselection(position); break; } position++; } } }
代码说明:
代码是基于上篇文章,新增了播放列表缓存功能以及快速查找功能。
a). 使用了pinyin4j开源项目,用于提取文件名中的汉字的拼音,以便能够。
b). a-z这部分的代码也是通过反编译参考米聊的,比较有实用价值
c). 入库部分使用了事务
其他代码请参见项目代码。
注意:
由于是示例代码,考虑不尽周全,可能在后续章节中补充,请大家注意不要直接使用代码!例如应该检查一下sd卡是否可用等问题。
三、vtamio与vplayer
vitamio:http://vov.io
vplayer: (使用vitamio最成功的产品,用户超过500万)
以上就是对android vitamio 本地播放功能(快捷搜索,数据存储)资料整理,有开发android播放器的朋友可以参考下。
上一篇: Android实现左右摆动的球体动画效果
下一篇: Android 多线程处理之多线程详解