前言
4、使用Vitamio打造自己的Android萬能播放器(4)——本地播放(快捷搜索、數據存儲)
5、使用Vitamio打造自己的Android萬能播放器(5)——在線播放(播放優酷視頻)
?
本章實現視頻下載的功能
??
使用說明:進入在線視頻,點擊播放時將彈出選擇框詢問播放還是下載,點擊下載后進度條將在本地視頻頂部顯示。如果想邊看便下載,請直接點擊本地播放列表中正在下載的視頻。
?
????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)?{
????????????????????}
????????????????????try?{
????????????????????????if?(inputStream?!=?null)
????????????????????????????inputStream.close();
????????????????????}?catch?(IOException?ex)?{
????????????????????}
????????????????}
????????????????mDownloadUrls.remove(url);
????????????????mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_STOP,?url));
????????????}
????????});
????}
}?
代碼說明:
b. 這里使用了Time定時來刷進度,而沒有直接在write數據時更新進度,這樣的原因時每秒write較高,更新UI過于頻繁,可能導致超時等問題。
Handle
????????@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.add(p,?url);
????????????????????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();
????????????????break;
????????????case?FileDownloadHelper.MESSAGE_STOP://下載結束
????????????????p?=?mDownloadAdapter.getItem(url);
????????????????FileBusiness.insertFile(getActivity(),?p);
????????????????break;
????????????case?FileDownloadHelper.MESSAGE_ERROR:
????????????????Toast.makeText(getActivity(),?url,?Toast.LENGTH_LONG).show();
????????????????break;
????????????}
????????????super.handleMessage(msg);
????????}
? ? };?
代碼說明:
b. 下載流程:開始(顯示mTempListView) -> 正在下載(更新進度圖片和大小) ?-> 完成(入褲)
Dialog
????????????????????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()?{
????????????????????????@Override
????????????????????????public?void?onClick(DialogInterface?dialog,?int?which)?{
????????????????????????????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;
? ? ? ? ? ? ? ? }?
?
至本章節往后,代碼均不再提供下載,請移步Google Code:
http://code.google.com/p/android-oplayer
?
四、Vitamio公告
? ? ? 正式建立Vitamio開發者聯盟QQ群!群號為:246969281
? ? ??注意:目前僅接受已經開發基于Vitamio產品的開發者申請加入,申請理由請填寫產品的名詞和鏈接,獲取最新進展以及與Vitamio作者直接交流機會!
?