天天看點

使用Vitamio打造自己的Android萬能播放器(7)——線上播放(下載下傳視訊)

前言

  本章将實作非常實用的功能——下載下傳線上視訊。涉及到多線程、線程更新ui等技術,還需思考産品的設計,如何将新加的功能更好的融入到現有的産品中,并不是簡單的加一個界面就行了,歡迎大家交流産品設計和技術細節實作!

聲明

  歡迎轉載,但請保留文章原始出處:) 

    部落格園:http://www.cnblogs.com

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

系列

正文

  一、目标

    本章實作視訊下載下傳的功能

    

使用Vitamio打造自己的Android萬能播放器(7)——線上播放(下載下傳視訊)
使用Vitamio打造自己的Android萬能播放器(7)——線上播放(下載下傳視訊)

    使用說明:進入線上視訊,點選播放時将彈出選擇框詢問播放還是下載下傳,點選下載下傳後進度條将在本地視訊頂部顯示。如果想邊看便下載下傳,請直接點選本地播放清單中正在下載下傳的視訊。

  二、實作(部分主要實作代碼)

    filedownloadhelper

使用Vitamio打造自己的Android萬能播放器(7)——線上播放(下載下傳視訊)

public class filedownloadhelper {

    private static final string tag = "filedownloadhelper";

    /** 線程池 */

    private threadpool mpool = new threadpool();

    /** 開始下載下傳 */

    public static final int message_start = 0;

    /** 更新進度 */

    public static final int message_progress = 1;

    /** 下載下傳結束 */

    public static final int message_stop = 2;

    /** 下載下傳出錯 */

    public static final int message_error = 3;

    /** 中途終止 */

    private volatile boolean misstop = false;

    private handler mhandler;

    public volatile hashmap<string, string> mdownloadurls = new hashmap<string, string>();

    public filedownloadhelper(handler handler) {

        if (handler == null)

            throw new illegalargumentexception("handler不能為空!");

        this.mhandler = handler;

    }

    public void stopall() {

        misstop = true;

        mpool.stop();

    public void newdownloadfile(final string url) {

        newdownloadfile(url, environment.getexternalstoragedirectory() + "/" + fileutils.geturlfilename(url));

    /**

     * 下載下傳一個新的檔案

     * 

     * @param url

     * @param savepath

     */

    public void newdownloadfile(final string url, final string savepath) {

        if (mdownloadurls.containskey(url))

            return;

        else

            mdownloadurls.put(url, savepath);

        mpool.start(new runnable() {

            @override

            public void run() {

                mhandler.sendmessage(mhandler.obtainmessage(message_start, url));

                httpclient client = new defaulthttpclient();

                httpget get = new httpget(url);

                inputstream inputstream = null;

                fileoutputstream outputstream = null;

                try {

                    httpresponse response = client.execute(get);

                    httpentity entity = response.getentity();

                    final int size = (int) entity.getcontentlength();

                    inputstream = entity.getcontent();

                    if (size > 0 && inputstream != null) {

                        outputstream = new fileoutputstream(savepath);

                        int ch = -1;

                        byte[] buf = new byte[1024];

                        //每秒更新一次進度

                        new timer().schedule(new timertask() {

                            @override

                            public void run() {

                                try {

                                    fileinputstream fis = new fileinputstream(new file(savepath));

                                    int downloadedsize = fis.available();

                                    if (downloadedsize >= size)

                                        cancel();

                                    mhandler.sendmessage(mhandler.obtainmessage(message_progress, downloadedsize, size, url));

                                } catch (exception e) {

                                }

                            }

                        }, 50, 1000);

                        while ((ch = inputstream.read(buf)) != -1 && !misstop) {

                            outputstream.write(buf, 0, ch);

                        }

                        outputstream.flush();

                    }

                } catch (exception e) {

                    log.e(tag, e.getmessage(), e);

                    mhandler.sendmessage(mhandler.obtainmessage(message_error, url + ":" + e.getmessage()));

                } finally {

                    try {

                        if (outputstream != null)

                            outputstream.close();

                    } catch (ioexception ex) {

                        if (inputstream != null)

                            inputstream.close();

                }

                mdownloadurls.remove(url);

                mhandler.sendmessage(mhandler.obtainmessage(message_stop, url));

            }

        });

使用Vitamio打造自己的Android萬能播放器(7)——線上播放(下載下傳視訊)

    代碼說明:

      a. threadpool是線程池,請參照項目代碼。

      b. 這裡使用了time定時來刷進度,而沒有直接在write資料時更新進度,這樣的原因時每秒write較高,更新ui過于頻繁,可能導緻逾時等問題。

    handle

使用Vitamio打造自己的Android萬能播放器(7)——線上播放(下載下傳視訊)

    public handler mdownloadhandler = new handler() {

        @override

        public void handlemessage(message msg) {

            pfile p;

            string url = msg.obj.tostring();

            switch (msg.what) {

            case filedownloadhelper.message_start://開始下載下傳

                p = new pfile();

                p.path = mparent.mfiledownload.mdownloadurls.get(url);

                p.title = new file(p.path).getname();

                p.status = 0;

                p.file_size = 0;

                if (mdownloadadapter == null) {

                    mdownloadadapter = new fileadapter(getactivity(), new arraylist<pfile>());

                    mdownloadadapter.add(p, url);

                    mtemplistview.setadapter(mdownloadadapter);

                    mtemplistview.setvisibility(view.visible);

                } else {

                    mdownloadadapter.notifydatasetchanged();

                break;

            case filedownloadhelper.message_progress://正在下載下傳

                p = mdownloadadapter.getitem(url);

                p.temp_file_size = msg.arg1;

                p.file_size = msg.arg2;

                int status = (int) ((msg.arg1 * 1.0 / msg.arg2) * 10);

                if (status > 10)

                    status = 10;

                p.status = status;

                mdownloadadapter.notifydatasetchanged();

            case filedownloadhelper.message_stop://下載下傳結束

                filebusiness.insertfile(getactivity(), p);

            case filedownloadhelper.message_error:

                toast.maketext(getactivity(), url, toast.length_long).show();

            super.handlemessage(msg);

        }

使用Vitamio打造自己的Android萬能播放器(7)——線上播放(下載下傳視訊)

    }; 

      a. mtemplistview是新增的,預設是隐藏,請參見項目代碼layout部分。

      b. 下載下傳流程:開始(顯示mtemplistview) -> 正在下載下傳(更新進度圖檔和大小)  -> 完成(入褲)

    dialog

使用Vitamio打造自己的Android萬能播放器(7)——線上播放(下載下傳視訊)

                if (fileutils.isvideooraudio(url)) {

                    dialog dialog = new alertdialog.builder(getactivity()).seticon(android.r.drawable.btn_star).settitle("播放/下載下傳").setmessage(url).setpositivebutton("播放", new onclicklistener() {

                        @override

                        public void onclick(dialoginterface dialog, int which) {

                            intent intent = new intent(getactivity(), videoplayeractivity.class);

                            intent.putextra("path", url);

                            startactivity(intent);

                    }).setneutralbutton("下載下傳", new onclicklistener() {

                            mainfragmentactivity activity = (mainfragmentactivity) getactivity();

                            activity.mfiledownload.newdownloadfile(url);

                            toast.maketext(getactivity(), "正在下載下傳 .." + fileutils.geturlfilename(url) + " ,可從本地視訊檢視進度!", toast.length_long).show();

                    }).setnegativebutton("取消", null).create();

                    dialog.show();

                    return true;

使用Vitamio打造自己的Android萬能播放器(7)——線上播放(下載下傳視訊)

                } 

  三、下載下傳

    至本章節往後,代碼均不再提供下載下傳,請移步google code:

  四、vitamio公告

      正式建立vitamio開發者聯盟qq群!群号為:246969281

      注意:目前僅接受已經開發基于vitamio産品的開發者申請加入,申請理由請填寫産品的名詞和連結,擷取最新進展以及與vitamio作者直接交流機會!

結束

  有bug不可怕,改了就行,大膽設計、放手寫代碼,謹慎處理已知細節,這樣的軟體才會越來越好。寫了一上午代碼,難免有出錯的地方,歡迎回報~

轉載:http://www.cnblogs.com/over140/archive/2012/06/29/2561244.html

繼續閱讀