使用Vitamio打造自己的Android万能播放器(7)——在线播放(下载视频)

来源:互联网 发布:python 程序 编辑:程序博客网 时间:2024/05/01 20:09
正文
  一、目标
    本章实现视频下载的功能
    2012-6-29_1.png  2012-6-29_2.png
    使用说明:进入在线视频,点击播放时将弹出选择框询问播放还是下载,点击下载后进度条将在本地视频顶部显示。如果想边看便下载,请直接点击本地播放列表中正在下载的视频。

  二、实现(部分主要实现代码)
    FileDownloadHelper
  1. public class FileDownloadHelper {
  2.     private static final String TAG = "FileDownloadHelper";
  3.     /** 线程池 */
  4.     private ThreadPool mPool = new ThreadPool();
  5.     /** 开始下载 */
  6.     public static final int MESSAGE_START = 0;
  7.     /** 更新进度 */
  8.     public static final int MESSAGE_PROGRESS = 1;
  9.     /** 下载结束 */
  10.     public static final int MESSAGE_STOP = 2;
  11.     /** 下载出错 */
  12.     public static final int MESSAGE_ERROR = 3;
  13.     /** 中途终止 */
  14.     private volatile boolean mIsStop = false;
  15.     private Handler mHandler;
  16.     public volatile HashMap<String, String> mDownloadUrls = new HashMap<String, String>();

  17.     public FileDownloadHelper(Handler handler) {
  18.         if (handler == null)
  19.             throw new IllegalArgumentException("handler不能为空!");

  20.         this.mHandler = handler;
  21.     }

  22.     public void stopALl() {
  23.         mIsStop = true;
  24.         mPool.stop();
  25.     }

  26.     public void newDownloadFile(final String url) {
  27.         newDownloadFile(url, Environment.getExternalStorageDirectory() + "/" + FileUtils.getUrlFileName(url));
  28.     }

  29.     /**
  30.      * 下载一个新的文件
  31.      *
  32.      * @param url
  33.      * @param savePath
  34.      */
  35.     public void newDownloadFile(final String url, final String savePath) {
  36.         if (mDownloadUrls.containsKey(url))
  37.             return;
  38.         else
  39.             mDownloadUrls.put(url, savePath);
  40.         mPool.start(new Runnable() {

  41.             @Override
  42.             public void run() {
  43.                 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_START, url));
  44.                 HttpClient client = new DefaultHttpClient();
  45.                 HttpGet get = new HttpGet(url);
  46.                 InputStream inputStream = null;
  47.                 FileOutputStream outputStream = null;
  48.                 try {
  49.                     HttpResponse response = client.execute(get);
  50.                     HttpEntity entity = response.getEntity();
  51.                     final int size = (int) entity.getContentLength();
  52.                     inputStream = entity.getContent();
  53.                     if (size > 0 && inputStream != null) {
  54.                         outputStream = new FileOutputStream(savePath);
  55.                         int ch = -1;
  56.                         byte[] buf = new byte[1024];
  57.                         //每秒更新一次进度
  58.                         new Timer().schedule(new TimerTask() {

  59.                             @Override
  60.                             public void run() {
  61.                                 try {
  62.                                     FileInputStream fis = new FileInputStream(new File(savePath));
  63.                                     int downloadedSize = fis.available();
  64.                                     if (downloadedSize >= size)
  65.                                         cancel();
  66.                                     mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_PROGRESS, downloadedSize, size, url));
  67.                                 } catch (Exception e) {

  68.                                 }
  69.                             }
  70.                         }, 50, 1000);

  71.                         while ((ch = inputStream.read(buf)) != -1 && !mIsStop) {
  72.                             outputStream.write(buf, 0, ch);
  73.                         }
  74.                         outputStream.flush();
  75.                     }
  76.                 } catch (Exception e) {
  77.                     Log.e(TAG, e.getMessage(), e);
  78.                     mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_ERROR, url + ":" + e.getMessage()));
  79.                 } finally {
  80.                     try {
  81.                         if (outputStream != null)
  82.                             outputStream.close();
  83.                     } catch (IOException ex) {
  84.                     }
  85.                     try {
  86.                         if (inputStream != null)
  87.                             inputStream.close();
  88.                     } catch (IOException ex) {
  89.                     }
  90.                 }
  91.                 mDownloadUrls.remove(url);
  92.                 mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_STOP, url));
  93.             }
  94.         });
  95.     }
复制代码
代码说明:
      a. ThreadPool是线程池,请参照项目代码。
      b. 这里使用了Time定时来刷进度,而没有直接在write数据时更新进度,这样的原因时每秒write较高,更新UI过于频繁,可能导致超时等问题。    Handle
  1. public Handler mDownloadHandler = new Handler() {
  2.         @Override
  3.         public void handleMessage(Message msg) {
  4.             PFile p;
  5.             String url = msg.obj.toString();
  6.             switch (msg.what) {
  7.             case FileDownloadHelper.MESSAGE_START://开始下载
  8.                 p = new PFile();
  9.                 p.path = mParent.mFileDownload.mDownloadUrls.get(url);
  10.                 p.title = new File(p.path).getName();
  11.                 p.status = 0;
  12.                 p.file_size = 0;
  13.                 if (mDownloadAdapter == null) {
  14.                     mDownloadAdapter = new FileAdapter(getActivity(), new ArrayList<PFile>());
  15.                     mDownloadAdapter.add(p, url);
  16.                     mTempListView.setAdapter(mDownloadAdapter);
  17.                     mTempListView.setVisibility(View.VISIBLE);
  18.                 } else {
  19.                     mDownloadAdapter.add(p, url);
  20.                     mDownloadAdapter.notifyDataSetChanged();
  21.                 }
  22.                 break;
  23.             case FileDownloadHelper.MESSAGE_PROGRESS://正在下载
  24.                 p = mDownloadAdapter.getItem(url);
  25.                 p.temp_file_size = msg.arg1;
  26.                 p.file_size = msg.arg2;
  27.                 int status = (int) ((msg.arg1 * 1.0 / msg.arg2) * 10);
  28.                 if (status > 10)
  29.                     status = 10;
  30.                 p.status = status;
  31.                 mDownloadAdapter.notifyDataSetChanged();
  32.                 break;
  33.             case FileDownloadHelper.MESSAGE_STOP://下载结束
  34.                 p = mDownloadAdapter.getItem(url);
  35.                 FileBusiness.insertFile(getActivity(), p);
  36.                 break;
  37.             case FileDownloadHelper.MESSAGE_ERROR:
  38.                 Toast.makeText(getActivity(), url, Toast.LENGTH_LONG).show();
  39.                 break;
  40.             }
  41.             super.handleMessage(msg);
  42.         }
复制代码
代码说明:
      a. mTempListView是新增的,默认是隐藏,请参见项目代码layout部分。
      b. 下载流程:开始(显示mTempListView) -> 正在下载(更新进度图片和大小)  -> 完成(入裤)    Dialog
  1. if (FileUtils.isVideoOrAudio(url)) {
  2.                     Dialog dialog = new AlertDialog.Builder(getActivity()).setIcon(android.R.drawable.btn_star).setTitle("播放/下载").setMessage(url).setPositiveButton("播放", new OnClickListener() {
  3.                         @Override
  4.                         public void onClick(DialogInterface dialog, int which) {
  5.                             Intent intent = new Intent(getActivity(), VideoPlayerActivity.class);
  6.                             intent.putExtra("path", url);
  7.                             startActivity(intent);
  8.                         }
  9.                     }).setNeutralButton("下载", new OnClickListener() {
  10.                         @Override
  11.                         public void onClick(DialogInterface dialog, int which) {
  12.                             MainFragmentActivity activity = (MainFragmentActivity) getActivity();
  13.                             activity.mFileDownload.newDownloadFile(url);
  14.                             Toast.makeText(getActivity(), "正在下载 .." + FileUtils.getUrlFileName(url) + " ,可从本地视频查看进度!", Toast.LENGTH_LONG).show();
  15.                         }
  16.                     }).setNegativeButton("取消", null).create();
  17.                     dialog.show();
  18.                     return true;
复制代码
原创粉丝点击