Android上传文件到服务端并显示进度条
作者:cc杂货圈 发布时间:2023-06-23 07:48:33
标签:Android,上传,服务端,进度条
最近在做上传文件的服务,简单看了网上的教程。结合实践共享出代码。
由于网上的大多数没有服务端的代码,这可不行呀,没服务端怎么调试呢。
Ok,先上代码。
Android 上传比较简单,主要用到的是 HttpURLConnection 类,然后加一个进度条组件。
private ProgressBar mPgBar;
class UploadTask extends AsyncTask<Object,Integer,Void>{
private DataOutputStream outputStream = null;
private String fileName;
private String uri;
private String mLineEnd = "\r\n";
private String mTwoHyphens = "--";
private String boundary = "*****";
File uploadFile ;
long mTtotalSize ; // Get size of file, bytes
public UploadTask(String fileName,String uri){
this.fileName = fileName;
this.uri = uri;
uploadFile= new File(fileName);
mTtotalSize = uploadFile.length();
}
/**
* 开始上传文件
* @param objects
* @return
*/
@Override
protected Void doInBackground(Object... objects) {
long length = 0;
int mBytesRead, mbytesAvailable, mBufferSize;
byte[] buffer;
int maxBufferSize = 256 * 1024;// 256KB
try{
FileInputStream fileInputStream = new FileInputStream(new File(fileName));
URL url = new URL(uri);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
//如果有必要则可以设置Cookie
// conn.setRequestProperty("Cookie","JSESSIONID="+cookie);
// Set size of every block for post
con.setChunkedStreamingMode(256 * 1024);// 256KB
// Allow Inputs & Outputs
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
// Enable POST method
con.setRequestMethod("POST");
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Charset", "UTF-8");
con.setRequestProperty("Content-Type",
"multipart/form-data;boundary=" + boundary);
outputStream = new DataOutputStream(
con.getOutputStream());
outputStream.writeBytes(mTwoHyphens + boundary + mLineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"" + mLineEnd);
outputStream.writeBytes("Content-Type:application/octet-stream \r\n");
outputStream.writeBytes(mLineEnd);
mbytesAvailable = fileInputStream.available();
mBufferSize = Math.min(mbytesAvailable, maxBufferSize);
buffer = new byte[mBufferSize];
// Read file
mBytesRead = fileInputStream.read(buffer, 0, mBufferSize);
while (mBytesRead > 0) {
outputStream.write(buffer, 0, mBufferSize);
length += mBufferSize;
publishProgress((int) ((length * 100) / mTtotalSize));
mbytesAvailable = fileInputStream.available();
mBufferSize = Math.min(mbytesAvailable, maxBufferSize);
mBytesRead = fileInputStream.read(buffer, 0, mBufferSize);
}
outputStream.writeBytes(mLineEnd);
outputStream.writeBytes(mTwoHyphens + boundary + mTwoHyphens
+ mLineEnd);
publishProgress(100);
// Responses from the server (code and message)
int serverResponseCode = con.getResponseCode();
String serverResponseMessage = con.getResponseMessage();
fileInputStream.close();
outputStream.flush();
outputStream.close();
} catch (Exception ex) {
ex.printStackTrace();
Log.v(TAG,"uploadError");
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress) {
mPgBar.setProgress(progress[0]);
}
}
主要流程为继承AsyncTask,然后使用HttpURLConnection 去上传文件。代码比较简单,就不一一讲解了。
其中要注意的是需要在
outputStream.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileName + "\"" + mLineEnd);
将name 设置为web 请求的参数名,由于我的服务端是将文件设置为file参数,所以我可以直接填file .所以大家可以根据实际情况作相应修改。
那么接着上服务端代码,服务端主要使用status 2框架作请求。那么我们就需要进行封装。
//上传文件集合
private List<File> file;
//上传文件名集合
private List<String> fileFileName;
//上传文件内容类型集合
private List<String> fileContentType;
public List<File> getFile() {
return file;
}
public void setFile(List<File> file) {
this.file = file;
}
public List<String> getFileFileName() {
return fileFileName;
}
public void setFileFileName(List<String> fileFileName) {
this.fileFileName = fileFileName;
}
public List<String> getFileContentType() {
return fileContentType;
}
public void setFileContentType(List<String> fileContentType) {
this.fileContentType = fileContentType;
}
采用了多文件上传的方法,定义了List 集合。
那么处理文件上传的action ,由于是测试方法。这里就定义为testUpload
public String testUpload()throws Exception{
System.out.println("success");
uploadFile(0);
return SUCCESS;
}
到这里就已经才不多完成动作了,现在需要开始写上传的方法 uploadFile(int index),由于定义file 为多文件上传,而我们上传只上传了一个文件,所以这里参数为0
/**
* 上传功能
* @param i
* @return
* @throws FileNotFoundException
* @throws IOException
*/
private String uploadFile(int i) throws FileNotFoundException, IOException {
try {
InputStream in = new FileInputStream(file.get(i));
//String dir = ServletActionContext.getRequest().getRealPath(UPLOADDIR);
String dir = "D://UploadData/";
File uploadFile = new File(dir,StringUtils.getUUID()+getFile( this.getFileFileName().get(i)));
OutputStream out = new FileOutputStream(uploadFile);
byte[] buffer = new byte[1024 * 1024];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.close();
//然后进行计算
return uploadFile.getAbsolutePath();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
上面方法为将缓存区域的文件 然后搞到了D://UploadData/ 文件中,然后以自己的格式进行命名,这里我使用了电脑的UUID和文件名进行组合,确保我复制过来的文件不重复。
最后上传成功之后返回文件的真实地址。
ok,写到这里上传文件的功能基本上做完了。最后只剩下配置action 动作。
ok,我们打开status.xml 文件进行配置
<!-- 系统常量定义,定义上传文件字符集编码 -->
<constant name="struts.i18n.encoding" value="utf-8"></constant>
<!-- 系统常量定义,定义上传文件零时存放路径 -->
<constant name="struts.multipart.saveDir" value="c:\tmp\"></constant>
<constant name="struts.multipart.maxSize" value="10000000" />
这里主要定义上传文件的临时存放位置,然后大小限制。
大家可以根据实际情况进行配置。
最后上传一张效果图。
0
投稿
猜你喜欢
- 一般而言,Android 应用在请求数据时都是以 Get 或 Post 等方式向远程服务器发起请求,那你有没有想过其实我们也可以在 Andr
- feign传输List的坑无法直接传输List错误方法1@RequestMapping(value = "/stat/mercha
- 1. 在原有工程目录右键-> new ->Module->:2. 选择library:3. 一路next,最后finish
- 本文实例讲述了C#启动进程的几种常用方法。分享给大家供大家参考。具体如下:1.启动子进程,不等待子进程结束private void simp
- 需求基于MTK8163 8.1平台定制导航栏部分,在左边增加音量减,右边增加音量加思路需求开始做之前,一定要研读SystemUI Navig
- 上篇介绍了几种图表的公共组件X、Y轴、背景Board的绘制。这章节介绍柱状图表的绘制,相对其它图表而言简单一些,这里主要介绍图表主体的绘制,
- 前言本文将带您了解在 Flutter 中制作翻转卡片动画的两个完整示例。第一个示例从头开始实现,第二个示例使用第三方包。闲话少说,让我们动手
- C# 关于Invoke首先说下,invoke和begininvoke的使用有两种情况:control中的invoke、begininvoke
- 1、取得控制台应用程序的根目录方法方法1、Environment.CurrentDirectory 取得或设置当前工作目录的完整限定路径方法
- 背景后台系统需要接入 企业微信登入,满足企业员工快速登入系统流程图简单代码说明自定义一套 springsecurity 认证逻辑主要就是 根
- 1、前言当提及如何终止一个线程时,部分读者通常立马想到的方法肯定是stop(),但是stop()方法并不被推荐使用(很多规范中是禁止使用的)
- 近日于LeetCode看题遇1114 按序打印,获悉一解法使用了Semaphore,顺势研究,记心得于此。此解视Semaphore为锁,以保
- 最近碰到个需求,是希望在Unity有一个按钮,打开后直接跳转淘宝app,打开商品页面。百度了下没有相关的文章,于是我在此分享下。之前开发游戏
- 本文实例讲述了C#获取网页源代码的方法。分享给大家供大家参考。具体如下:public string GetPageHTML(string u
- 前言为什么用动静态库我们在实际开发中,经常要使用别人已经实现好的功能,这是为了开发效率和鲁棒性(健壮性);因为那些功能都是顶尖的工程师已经写
- 一、获取android工程里面的各种资源的id; 1.1 string型 比如下面: << string name=”OK”&g
- 本文实例讲述了java实现的简单猜数字游戏代码。分享给大家供大家参考。具体代码如下:import java.util.InputMismat
- 前言在使用Java开发接口请求中,我们需要对请求进行进行统一返回值,这时候我们自己封装一个统一的Result返回类,下面就介绍下我用的这种的
- 一直使用Eclipse环境开发Android,也尝鲜使用过Android Studio去开发,各种IDE配合Android SDK及SDK原
- 右击有main方法的类===> Run as===> Run Configurations ===>双击java