本文转自;http://www.cnblogs.com/over140/archive/2012/06/08/2541452.html

前言

  关键字:Vitamio、VPlayer、Android播放器、Android影音、Android开源播放器

  本章节把Android万能播放器本地播放的主要功能(缓存播放列表和A-Z快速查询功能)完成,和播放组件关系不大,但用到一些实用的技术,欢迎交流!

声明   欢迎转载,但请保留文章原始出处:)     博客园:http://www.cnblogs.com

    农民伯伯: http://over140.cnblogs.com

系列

  1、使用Vitamio打造自己的Android万能播放器(1)——准备

  2、使用Vitamio打造自己的Android万能播放器(2)—— 手势控制亮度、音量、缩放

  3、使用Vitamio打造自己的Android万能播放器(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卡是否可用等问题。

  三、项目下载

Vitamio-Demo2012-6-8.zip

  四、Vtamio与VPlayer

Vitamio:http://vov.io
VPlayer:http://vplayer.net (使用Vitamio最成功的产品,用户超过500万)


更多相关文章

  1. 箭头函数的基础使用
  2. NPM 和webpack 的基础使用
  3. Python list sort方法的具体使用
  4. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
  5. Android(安卓)回炉 阿里巴巴Android开发规范
  6. 在 Android(安卓)应用程序中使用 Internet 数据
  7. Android(安卓)编码规范
  8. Android~使用Service还是Thread
  9. Android(安卓)中自定义控件和属性(attr.xml,declare-styleable,T

随机推荐

  1. Android集成百度定位以及导航详解
  2. 深入Android(安卓)【三】 —— 组件入门
  3. 简述Android(安卓)解决65536/64K方法数限
  4. Android(安卓)studio文件编码格式怎么快
  5. android 点击字体,图片背景效果一起变换De
  6. 【安卓笔记】res/raw与assets区别
  7. Android(安卓)和 Webview 如何相互 sayHe
  8. Android之Intent深入
  9. android下的蓝牙A2DP
  10. [闲话杂谈] Android(安卓)跟 Linux 是有