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() + "/";
/**
* 默认的password字符串组合,用来将字节转换成 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);
}
}); }
}
android开发步步为营之67:使用android开源项目android-async-http异步下载文件的更多相关文章
- Java Android 注解(Annotation) 及几个常用开源项目注解原理简析
不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义. ...
- Android开发面试经——6.常见面试官提问Android题②(更新中...)
版权声明:本文为寻梦-finddreams原创文章,请关注:http://blog.csdn.net/finddreams 关注finddreams博客:http://blog.csdn.net/fi ...
- Android 常用炫酷控件(开源项目)git地址汇总
第一部分 个性化控件(View) 主要介绍那些不错个性化的 View,包括 ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.P ...
- Android开发学习总结(一)——搭建最新版本的Android开发环境
Android开发学习总结(一)——搭建最新版本的Android开发环境(转) 最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Android开发虽然有所了解,但是 ...
- Android开发面试经——5.常见面试官提问Android题①
版权声明:本文为寻梦-finddreams原创文章,请关注:http://blog.csdn.net/finddreams 关注finddreams博客: http://blog.csdn.net/f ...
- SNF快速开发平台MVC-集成了百度开源项目echars
百度开源项目echars图表样式非常丰富,而且开源免费.非常好.所以在我们框架当中也进行了集成echars完成图表任务. 我们进行了两次封装,利于我们开发使用.我也看到过有些架构师 按echars里的 ...
- android开发环境搭建(ubuntu15.04+jdk8+eclipse+android sdk)
开始学习android开发,首先对其环境对搭建比较重要.平台可以选择window/linux/mac等,这里,我选择ubuntu系统,方法比较原始,当然也可以直接用google提供的android s ...
- Android开发学习---使用Intelij idea 13.1 进行android 开发
1.为什么放弃eclipse?太卡!! 实在受不了eclipse的卡了,运行WEB项目还好,但android开发实在太慢,太慢!经常卡死,CPU经常被占满! 看网上很多人都说比Intelij idea ...
- Android开发利器之Data Binding Compiler V2 —— 搭建Android MVVM完全体的基础
原创声明: 该文章为原创文章,未经博主同意严禁转载. 前言: Android常用的架构有:MVC.MVP.MVVM,而MVVM是唯一一个官方提供支持组件的架构,我们可以通过Android lifecy ...
随机推荐
- [UVa10296]Jogging Trails
题目大意: 中国邮递员问题. 给你一个无向带权连通图,求经过所有边并返回起点的最短路径. 思路: Edmonds-Johnson算法. 显然,当原图为欧拉图时,答案即为其欧拉回路的长度. 考虑原图不存 ...
- 开源中国上抓取的content-type
开源中国上抓取的content-type类型,来源:http://www.cnblogs.com/smallyard/p/5632608.html { ".*": "ap ...
- centos7安装kafka_2.11-1.0.0 新手入门
系统环境 1.操作系统:64位CentOS Linux release 7.2.1511 (Core) 2.jdk版本:1.8.0_121 3.zookeeper版本:zookeeper-3.4.9. ...
- 客户端程序获取自己的ip、isp、地理位置等信息
@ 比如说你需要收集用户信息,又或者要通过这些信息让用户登陆合适的服务器(北京联通用户登陆北京联通服务器). @ 淘宝和新浪都提供了类似的API,你只需要发送一个http请求,它就返回一个json格式 ...
- hint.css使用说明
GitHub:http://liu12fei08fei.github.io/html/1hint.html hint.css使用说明 用途 快速实现tooltips提示样式 相关资源 官方网站GitH ...
- WP8.1 VS iOS VS Android全方面大比拼
众所周知,苹果的OS和谷歌的Android系统都有着相对成熟的设计和较好的用户体验,而随着WP8.1的发布,微软WP系统在交互方面也有了很多改进和提升,而今天小编便为大家全面对比一下这三大系统. ...
- Bootstrap 3之美04-自定义CSS、Theme、Package
本篇主要包括: ■ 自定义CSS■ 自定义Theme■ 自定义Package 自定义CSS 有时候,需要自定义或重写Bootstrap默认的CSS.→在css文件夹下创建一个site.css→假 ...
- JDBC 连Sql Server 接数据库--The TCP/IP connection to the host localhost, port 1433 has failed
原文:https://blog.csdn.net/qq_39241986/article/details/80848855 这样的错误,你有遇到过吗? The TCP/IP connection to ...
- msgpack和protobuf的对比
msgpack和protobuf的对比 msgpack的序列化速度比protobuf要快一些,但反序列化要比protobuf要慢一些,但总体都接近msgpack可以直接序列化类对象,但protobuf ...
- Sublime Text2安装emmet(原名Zen Coding)总结
首先,安装好Sublime( 我用的是版本号2),之后注冊好.Sublime Text2.0.2注冊码:http://xionggang163.blog.163.com/blog/static/376 ...