靠譜的Android下載文件到SD卡的方法

Android下載文件的方法網上有好多,找來都不太靠譜,下載的文件經常不全。

我參考了多個方法,寫了一個比較靠譜的,實測成功。


下載類代碼:

在這個下載類中,我定義了一個回掉,可以回傳當前下載的進度。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.os.Environment;
import android.util.Log;

import com.tct.manager.android.file.FileUtils;

/**
 * 下載的操作類
 * @author drlyee
 */
public class DownloadHelper
{
    /**
     * 請求的地址
     */
    private String sRequestUrl;
    /**
     * SD卡路徑
     */
    private String sSDCardPath;
    /**
     * 連接管理
     */
    private HttpURLConnection httpURLConnection;

    /**
     * 構造函數
     * @param url
     */
    public DownloadHelper(String url)
    {
        this.sRequestUrl = url;
        //獲取設備sd卡目錄
        this.sSDCardPath = Environment.getExternalStorageDirectory() + "/";
        this.httpURLConnection = getConnection();
    }

    /**
     * 讀取網絡文本
     */
    public String downloadAsString()
    {
        StringBuilder sb = new StringBuilder();
        String temp = null;
        try
        {
            InputStream is = httpURLConnection.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            while ((temp = br.readLine()) != null)
            {
                sb.append(temp);
            }
            br.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return sb.toString();
    }

    /**
     * 獲取http連接處理類HttpURLConnection
     */
    private HttpURLConnection getConnection()
    {
        URL url;
        HttpURLConnection urlcon = null;
        try
        {
            url = new URL(sRequestUrl);
            urlcon = (HttpURLConnection) url.openConnection();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return urlcon;
    }

    /**
     * 獲取連接文件長度。
     */
    public int getLength()
    {
        return httpURLConnection.getContentLength();
    }

    /**
     * 下載文件到SD卡
     * @param dir 下載後存放的文件夾路徑,不需要SD卡路徑
     * @param filename 文件名稱
     * @param handler 回掉事件
     */
    public synchronized void downloadToSDCard(String dir, String filename, DownLoadHandler handler)
    {
        String sFolderName = sSDCardPath + dir + "/";
        String sFileName = sSDCardPath + dir + "/" + filename;
        File file = new File(sFolderName.toString());
        //如果文件夾不存在 創建文件夾
        if (!file.exists())
        {
            file.mkdirs();
            Log.d("log", sFolderName.toString());
        }
        //獲取文件
        file = new File(sFileName);
        FileOutputStream fos = null;
        BufferedInputStream in = null;
        BufferedOutputStream out = null;
        int totalSize = 0;
        try
        {
            //創建文件
            fos = new FileOutputStream(file);
            byte[] buffer = new byte[1024 * 8];
            totalSize = httpURLConnection.getContentLength();
            in = new BufferedInputStream(httpURLConnection.getInputStream(), 1024 * 8);
            out = new BufferedOutputStream(fos, 1024 * 8);
            int count = 0, n = 0;
            while ((n = in.read(buffer, 0, 1024 * 8)) != -1)
            {
                out.write(buffer, 0, n);
                count += n;
                handler.progress(filename, count, totalSize);
            }
            out.flush();
            out.close();
            in.close();
            fos.flush();
            fos.close();
            handler.onFinished(totalSize, sFileName);
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            try
            {
                out.close();
                in.close();
                fos.flush();
                fos.close();
            }
            catch (IOException ex)
            {
                // TODO Auto-generated catch block
                ex.printStackTrace();
            }
            handler.onFail("下載失敗");
            e.printStackTrace();
        }
    }

    /**
     * 內部回調接口類
     */
    public abstract class DownLoadHandler
    {
        public abstract void progress(String name, int hasDownloadSize, int totalSize);

        public abstract void onFinished(int totalSize, String path);

        public abstract void onFail(String info);
    }
}


使用如下:

定義一個下載的Runable,因爲網絡請求不可以在主線程裏邊去做。

    private class DownLoadRunable implements Runnable
    {
        @Override
        public void run()
        {
            // TODO Auto-generated method stub
            String path = "http://msoftdl.360.cn/mobilesafe/shouji360/360safesis/360MobileSafe.apk";
            DownloadHelper downloadHelper = new DownloadHelper(path);
            downloadHelper.downloadToSDCard("MyDownload", "360MobileSafe.apk", downloadHelper.new DownLoadHandler()
            {

                @Override
                public void progress(String name, int hasDownloadSize, int totalSize)
                {
                    // TODO Auto-generated method stub
                    Log.i("progress ", name + " down:" + hasDownloadSize + " Total:" + totalSize);
                }

                @Override
                public void onFinished(int totalSize, String path)
                {
                    // TODO Auto-generated method stub
                    Log.i("onFinished ", "下載成功  Total:" + totalSize);
                }

                @Override
                public void onFail(String info)
                {
                    // TODO Auto-generated method stub
                    Log.e("onFail ", "下載成失敗");
                }
            });
        }
    }


調用的方法,比如點擊按鈕下載:

        btnDownLoad.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                // TODO Auto-generated method stub
                Thread thread = new Thread(new DownLoadRunable());
                thread.start();
            }
        });

執行的Log如下:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章