android开发步步为营之67:使用android开源项目android-async-http异步下载文件

android-async-http项目地址 https://github.com/loopj/android-async-http,android-async-http顾名思义是异步的http请求,不过它也支持同步请求的,本文主要使用了android-async-http做异步请求下载文件。每当app需要更新新版本的时候,就需要用到下载功能的,经研究android-async-http这个第三方开源项目还是挺好用的,这里介绍给大家。

    1、下载类DownloadManager.java

package com.figo.study.latin.mgr;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;

import org.apache.http.Header;

import android.content.Context;
import android.net.ConnectivityManager;
import android.os.Environment;

import com.figo.study.R;
import com.android.inputmethod.latin.model.AsyncDownload;
import com.figo.study.util.FileUtil;
import com.figo.study.util.NetworkUtil;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.FileAsyncHttpResponseHandler;

/**
 * 异步下载类
 * @author figo
 *
 */
public class DownloadManager {
    private boolean mUseWifiOnly = false;

    public DownloadManager() {

    }

    private HashMap<String, AsyncDownload> asyncDownlaods = null;

    public void init() {
        asyncDownlaods = new HashMap<String, AsyncDownload>();
    }

    public void download(final Context context, String url, final String md5, String dirPath, String fileName, final DownloadListener callback) {
        try {
            callback.onStart();
            if (!NetworkUtil.isNetworkUseful(context)) {
                callback.onError(context.getString(R.string.lbl_network_useless));
            }
            if (mUseWifiOnly) {
                if (NetworkUtil.getNetworkType(context) != ConnectivityManager.TYPE_WIFI) {
                    callback.onError(context.getString(R.string.lbl_not_support));
                }
                return;
            }
            String sdPath = Environment.getExternalStorageDirectory() + "/";
            AsyncHttpClient client =new AsyncHttpClient();
            if (!asyncDownlaods.containsKey(url)) {
                AsyncDownload asyncDownload = new AsyncDownload();
                asyncDownload.setAsyncHttpClient(client);
                asyncDownload.setFileName(sdPath + dirPath + fileName);
                asyncDownlaods.put(url, asyncDownload);
            }else
            {
                client=asyncDownlaods.get(url).getAsyncHttpClient();
            }

            File file = new File(sdPath + dirPath, fileName);
            try {
                FileUtil.createSDDir(dirPath);
                file = FileUtil.createSDFile(dirPath + fileName);
            } catch (IOException e1) {
                if (e1 != null) {
                    e1.printStackTrace();
                }
            }
            FileAsyncHttpResponseHandler fileAsyncHttpResponseHandler = new FileAsyncHttpResponseHandler(file) {

                @Override
                public void onCancel() {
                    super.onCancel();
                    System.out.print("cancel success!");
                }

                @Override
                public void onProgress(int bytesWritten, int totalSize) {
                    super.onProgress(bytesWritten, totalSize);
                    int currentProgress = (int) ((bytesWritten * 1.0f / totalSize) * 100);
                    callback.onProgress(currentProgress);
                }

                @Override
                public void onStart() {
                    super.onStart();

                }

                @Override
                public void onFailure(int arg0, Header[] arg1, Throwable arg2, File arg3) {
                    if (arg2 != null) {
                        arg2.printStackTrace();
                    }
                    if (arg2 != null) {
                        callback.onError(arg2.getMessage());
                    } else {
                        callback.onError(context.getString(R.string.lbl_network_error));
                    }
                }

                @Override
                public void onSuccess(int arg0, Header[] arg1, File arg2) {
                    String md5String = "";
                    try {
                        md5String = FileUtil.getFileMD5String(arg2);

                    } catch (Exception e) {
                        if (e != null) {
                            e.printStackTrace();
                        }
                    }

//                    if (md5.equals(md5String) == false) {
//                        callback.onError(context.getString(R.string.lbl_md5_error));
//                    } else {
//                        callback.onSuccess();
//                    }
                    //测试放开
                    callback.onSuccess();

                }

            };
            client.setEnableRedirects(true);//允许重复下载
            client.get(context, url, fileAsyncHttpResponseHandler);
        } catch (Exception e) {
            callback.onError(context.getString(R.string.lbl_system_err));
        }

    }

    public void setDownloadWifiOnly(boolean value) {
        mUseWifiOnly = value;

    }

    public void cancelDownload(Context context, String url) {
        try {

            if (asyncDownlaods != null && asyncDownlaods.containsKey(url)) {
                //已经下载的文件删除
                FileUtil.deleteFile(asyncDownlaods.get(url).getFileName());
                //取消当前下载
                AsyncHttpClient client = asyncDownlaods.get(url).getAsyncHttpClient();
                if (client != null) {
                    client.cancelRequests(context, true);
                }
                //当前key删除
                asyncDownlaods.remove(url);
            }

        } catch (Exception e) {
            if (e != null) {
                e.printStackTrace();
            }
        }

    }

}

2、下载监听类DownloadListener.java

public interface DownloadListener {
    public void onStart();

    public void onError(String errMessage);

    public void onSuccess();

    public void onProgress(int progress);
}

3、文件管理类FileUtil.java

/**
 *
 */
package com.figo.study.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import android.os.Environment;

/**
 * @author figo
 *
 */
public class FileUtil {
     //得到当前外部存储设备的目录( /SDCARD )
    static String SDPATH = Environment.getExternalStorageDirectory() + "/";
    /**
     * 默认的密码字符串组合,用来将字节转换成 16 进制表示的字符,apache校验下载的文件的正确性用的就是默认的这个组合
     */
    protected static char hexDigits[] = {
            '0',
            '1',
            '2',
            '3',
            '4',
            '5',
            '6',
            '7',
            '8',
            '9',
            'a',
            'b',
            'c',
            'd',
            'e',
            'f' };
    protected static MessageDigest messagedigest = null;
    static {
        try {
            messagedigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    public static String getFileMD5String(File file) throws IOException {
        InputStream fis;
        fis = new FileInputStream(file);
        byte[] buffer = new byte[1024];
        int numRead = 0;
        while ((numRead = fis.read(buffer)) > 0) {
            messagedigest.update(buffer, 0, numRead);
        }
        fis.close();
        return bufferToHex(messagedigest.digest());
    }

    private static String bufferToHex(byte bytes[]) {
        return bufferToHex(bytes, 0, bytes.length);
    }

    private static String bufferToHex(byte bytes[], int m, int n) {
        StringBuffer stringbuffer = new StringBuffer(2 * n);
        int k = m + n;
        for (int l = m; l < k; l++) {
            appendHexPair(bytes[l], stringbuffer);
        }
        return stringbuffer.toString();
    }

    private static void appendHexPair(byte bt, StringBuffer stringbuffer) {
        char c0 = hexDigits[(bt & 0xf0) >> 4];// 取字节中高 4 位的数字转换
        // 为逻辑右移,将符号位一起右移,此处未发现两种符号有何不同
        char c1 = hexDigits[bt & 0xf];// 取字节中低 4 位的数字转换
        stringbuffer.append(c0);
        stringbuffer.append(c1);
    }

    public static void main(String[] args) throws IOException {
        File file = new File("E:/test/crm_account_YYYY_MM_DD.txt");
        String md5 = getFileMD5String(file);
        System.out.println("md5:" + md5);
    }

    /**
     * 在SD卡上创建文件
     * @param fileName
     * @return
     * @throws IOException
     */
    public static File createSDFile(String fileName) throws IOException {
        File file = new File(SDPATH + fileName);
        if(file.exists())
        {
            final File to = new File(file.getAbsolutePath() + System.currentTimeMillis());
            file.renameTo(to);
            to.delete();
//            file.delete();
        }
        file.createNewFile();
        return file;
    }

    /**
     * 在SD卡上创建目录
     * @param dirName
     * @return
     */
    public static File createSDDir(String dirName) {
        File dir = new File(SDPATH + dirName);
        if(!dir.exists())
        {
           dir.mkdirs();
        }
        return dir;
    }

    /**
     * 判断SD卡上的文件夹是否存在
     * @param fileName
     * @return
     */
    public boolean isFileExist(String fileName) {
        File file = new File(SDPATH + fileName);
        return file.exists();
    }

    /**
     * 删除文件
     * @param fileName
     * @return
     */
    public static void deleteFile(String fileName) {
        try {
            File file = new File(fileName);
            if(file.exists())
            {
                file.delete();
            }
        } catch (Exception e) {
            if(e!=null)
            {
                e.printStackTrace();
            }
        }

    }
}

4、网络管理类NetworkUtil.java

public class NetworkUtil {
    public static int getNetworkType(Context mContext) {
        try {
            final ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
            final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            return networkInfo.getType();
        } catch (Exception e) {
            return ConnectivityManager.TYPE_WIFI;
        }
    }

    public static boolean isNetworkUseful(Context mContext)
    {
        final ConnectivityManager connectivityManager = (ConnectivityManager) mContext
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        final NetworkInfo mobNetInfoActivity = connectivityManager
                .getActiveNetworkInfo();
        if (mobNetInfoActivity == null || !mobNetInfoActivity.isAvailable()) {
            return false;
        }else
        {
            return true;
        }
    }
}

5、测试TestDownloadActivity.java

/**
 *
 */
package com.figo.study.activity;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.figo.study.R;
import com.android.inputmethod.latin.mgr.DownloadListener;
import com.android.inputmethod.latin.view.HorizontalProgressBarWithNumber;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.FileAsyncHttpResponseHandler;

/**
 * @author avazu
 *
 */
public class TestDownloadActivity extends Activity {
    private HorizontalProgressBarWithNumber mProgressBar, mProgressBar1;
    private Button btnDownload, btnCancel, btn_pause_continue, btnDownload1, btnCancel1;
    AsyncHttpClient client = new AsyncHttpClient();
    FileAsyncHttpResponseHandler fileAsyncHttpResponseHandler = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_download_test);
        initView();
    }

    private void initView() {
        mProgressBar = (HorizontalProgressBarWithNumber) findViewById(R.id.id_progressbar);
        mProgressBar1 = (HorizontalProgressBarWithNumber) findViewById(R.id.id_progressbar1);
        //        btn_pause_continue = (Button) findViewById(R.id.btn_pause_continue);
        //        btn_pause_continue.setOnClickListener(new OnClickListener() {
        //
        //            @Override
        //            public void onClick(View v) {
        //                // TODO Auto-generated method stub
        //                fileAsyncHttpResponseHandler.sendRetryMessage(0);
        //            }
        //        });
        final String url = "http://dl.wandoujia.com/files/phoenix/latest/wandoujia-wandoujia_web.apk?timestamp=1409388568830";
        final String md5 = "";
        final String dirPath = "study/download/";
        final String fileName = "豌豆荚.apk";
        btnDownload = (Button) findViewById(R.id.btn_download);
        try {
            btnDownload.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    BaseSkinApplication.shared().getDm().setDownloadWifiOnly(false);
                    BaseSkinApplication.shared().getDm().download(TestDownloadActivity.this, url, md5, dirPath, fileName, new DownloadListener() {

                        @Override
                        public void onStart() {
                            btnDownload.setVisibility(View.GONE);
                            btnCancel.setVisibility(View.VISIBLE);

                        }

                        @Override
                        public void onError(String errMessage) {

                        }

                        @Override
                        public void onSuccess() {

                        }

                        @Override
                        public void onProgress(int progress) {
                            mProgressBar.setProgress(progress);
                        }
                    });

                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        final String url1 = "http://msoftdl.360.cn/mobilesafe/shouji360/360safesis/360MobileSafe.apk";
        final String md51 = "";
        final String dirPath1 = "study/download/";
        final String fileName1 = "360.apk";
        btnDownload1 = (Button) findViewById(R.id.btn_download1);
        try {
            btnDownload1.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {

                    BaseSkinApplication.shared().getDm().setDownloadWifiOnly(false);
                    BaseSkinApplication.shared().getDm().download(TestDownloadActivity.this, url1, md51, dirPath1, fileName1, new DownloadListener() {

                        @Override
                        public void onStart() {
                            btnDownload1.setVisibility(View.GONE);
                            btnCancel1.setVisibility(View.VISIBLE);

                        }

                        @Override
                        public void onError(String errMessage) {

                        }

                        @Override
                        public void onSuccess() {

                        }

                        @Override
                        public void onProgress(int progress) {
                            mProgressBar1.setProgress(progress);
                        }
                    });

                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        btnCancel = (Button) findViewById(R.id.btn_cancel);
        btnCancel.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                BaseSkinApplication.shared().getDm().cancelDownload(TestDownloadActivity.this, url);
                btnDownload.setVisibility(View.VISIBLE);
                btnCancel.setVisibility(View.GONE);
            }
        });
        btnCancel1 = (Button) findViewById(R.id.btn_cancel1);
        btnCancel1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                BaseSkinApplication.shared().getDm().cancelDownload(TestDownloadActivity.this, url1);
                btnDownload1.setVisibility(View.VISIBLE);
                btnCancel1.setVisibility(View.GONE);
            }
        });

    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-04 17:52:10

android开发步步为营之67:使用android开源项目android-async-http异步下载文件的相关文章

Java Android 注解(Annotation) 及几个常用开源项目注解原理简析

不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义.解析,并对几个 Android 开源库 Annotation 原理进行简析.PDF 版: Java Annotation.pdf, PPT 版:Java Annotation.pptx, Keynote 版:Java Annotation.key 完整版原文见:Java Android 注解(Ann

Android开发面试经——6.常见面试官提问Android题②(更新中...)

版权声明:本文为寻梦-finddreams原创文章,请关注:http://blog.csdn.net/finddreams 关注finddreams博客:http://blog.csdn.net/finddreams/article/details/44560061 1.HttpURLConnection和HttpClient他们各自的优缺点是什么? HttpUrlConnection 在 2.3 以前的版本是有 bug 的,所以之前的版本推荐使用 HttpClient,但是 google 现在

Android开发学习---使用Intelij idea 13.1 进行android 开发

原文:Android开发学习---使用Intelij idea 13.1 进行android 开发 1.为什么放弃eclipse?太卡!! 实在受不了eclipse的卡了,运行WEB项目还好,但android开发实在太慢,太慢!经常卡死,CPU经常被占满! 看网上很多人都说比Intelij idea好用,就试下,目前还在test阶段,总之是各种不习惯,很多快捷键之类的跟eclipse完全不一样.还要多熟悉! 另外android studio 也比较卡,而且用起来相当难受,完全是intelij 的

【Android开发-1】必做的事情,android开发环境搭建

前言:互联网移动端现在发展的速度越来越快了,各种App应用软件和手游的崛起,把移动端弄的丰富多彩:心情一激动,头脑一发热,就开始看视频.看书学习了.记得11年的时候有学习了下Android的开发,但是只是基础的学习了下,没认真深入学习.这次自己决定认真学习下,并用博客记录下,见证自己成长的过程. 一.准备工作 1.下载最新版jdk:http://www.oracle.com/technetwork/java/javase/downloads/index.html 2.下载Eclipse,选择Ec

可删除超炫&amp;多种特效的Card视图(改造自cardsui-for-android开源项目),提供DEMO下载

       这里贴几个效果图,我做了一个gif的动态图,但是不知道为什么上传后图片不动,所以只能放在相册里. 如果大家想看动态的图片演示请点击后面的链接gif动态演示图片 实例Demo下载地址在本文最后 简单介绍 这个Demo主要是使用了cardsui-for-android开源项目,并且做了一些优化和改进: 1.自定义card视图 2.添加长按事件,避免误操作 3.长按后可以删除card,并播放选中动画 4.删除后浮现一个悬浮button 5.点击悬浮button可以恢复之前删除的card视

android开发步步为营之56:Android开发技术点总结(持续更新)

1.eclipse svn插件下载 http://subclipse.tigris.org/update_1.6.x http://subclipse.tigris.org/update_1.8.x 64位机器 http://subclipse.tigris.org/servlets/ProjectProcess?pageID=p4wYuA 2.eclipse常用插件下载 http://blog.csdn.net/jackiehff/article/details/8181945 3.unico

android开发步步为营之70:android接入Google Analytics总结

求人不如求己,今天项目里要接入Google Analytics,这个是做应用统计分析用的,可以查看当前手机活跃用户,事件点击等等数据,先看看效果: 之前eclipse里面接入已经成功,昨天项目组决定项目转成使用android studio来开发,看google官方文档,官方文档https://developers.google.com/analytics/devguides/collection/android/v4/,然后官方文档里面的配置文件是用google-services.json的,这

android开发步步为营之34:四大组件之ContentProvider

ContentProvider,从字面意义上理解,内容提供者,这个类目的就是一个桥梁的作用,让一个应用的数据(SQLiteDatabase, SharedPreferences,Xml,Txt等数据),通过ContentProvider可以让其他的应用访问. 理论知识 (一).ContentProvider简介 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同

android开发步步为营之53:viewpager+fragment构造可左右滑动标签页效果

可滑动的标签页是很多应用的用来做外面框架的,比如微信,微博等等,我这里实现的效果是下面是主标签页,然后中间一个的标签页里面又可以继续左右滑动,等于是标签页内部再嵌套标签页,用到的组件主要有:用于滑动效果的viewpager,以及用于实现每个tab页功能的fragment,先看看效果图:  第一步:设计页面activity_learn_fragment.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/