靠谱的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如下:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值