Android中实现OkHttp上传文件到服务器并带进度

在上一讲中 OkHttp下载文件并带进度条 中,我们知道怎样去下载文件了。那上传文件呢

一、编写服务器端

在上一讲服务器下新建UploadFileServlet,代码如下:然后重启服务器!

@WebServlet("/UploadFileServlet") @MultipartConfig public class UploadFileServlet extends HttpServlet { private static final long serialVersionUID = 1L; public UploadFileServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doPost=="); request.setCharacterEncoding("utf-8"); //获取file命名的part,注意要与Android端一样 Part part = request.getPart("file"); // 获取请求头,请求头的格式:form-data; name="file"; filename="snmp4j--api.zip" String header = part.getHeader("content-disposition"); System.out.println(header); String fileName = getFileName(header); // 存储路径 String savePath = "D:/huang/upload"; // 把文件写到指定路径 part.write(savePath + File.separator + fileName); response.setCharacterEncoding("UTF-8"); PrintWriter writer = response.getWriter(); writer.print("上传成功"); } public String getFileName(String header) { /** * header 为 form-data; name="file"; filename="dial.png" * String[] tempArr1 = * header.split(";");代码执行完之后,在不同的浏览器下,tempArr1数组里面的内容稍有区别 * 火狐或者google浏览器下:tempArr1={form-data,name="file",filename= * "snmp4j--api.zip"} * IE浏览器下:tempArr1={form-data,name="file",filename="E:\snmp4j--api.zip"} */ String[] tempArr1 = header.split(";"); /** * 火狐或者google浏览器下:tempArr2={filename,"snmp4j--api.zip"} * IE浏览器下:tempArr2={filename,"E:\snmp4j--api.zip"} */ String[] tempArr2 = tempArr1[2].split("="); // 获取文件名,兼容各种浏览器的写法 String fileName = tempArr2[1].substring(tempArr2[1].lastIndexOf("\\") + 1).replaceAll("\"", ""); return fileName; } }

二、Android端

1.布局,上一讲activity_main代码中添加 :

<Button android:id="@+id/ok_post_file" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="上传文件" /> <TextView android:id="@+id/post_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="0" /> <ProgressBar android:id="@+id/post_progress" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" />

2.OkHttpUtil新增上传文件方法:

public static void postFile(String url, final ProgressListener listener, Callback callback, File...files){ MultipartBody.Builder builder = new MultipartBody.Builder(); builder.setType(MultipartBody.FORM); Log.i("huang","files[0].getName()=="+files[0].getName()); //第一个参数要与Servlet中的一致 builder.addFormDataPart("file",files[0].getName(), RequestBody.create(MediaType.parse("application/octet-stream"),files[0])); MultipartBody multipartBody = builder.build(); Request request = new Request.Builder().url(url).post(new ProgressRequestBody(multipartBody,listener)).build(); okHttpClient.newCall(request).enqueue(callback); }

3.ProgressRequestBody是自定义RequestBody类,用来监听进度:

public class ProgressRequestBody extends RequestBody { public static final int UPDATE = 0x01; private RequestBody requestBody; private ProgressListener mListener; private BufferedSink bufferedSink; private MyHandler myHandler; public ProgressRequestBody(RequestBody body, ProgressListener listener) { requestBody = body; mListener = listener; if (myHandler==null){ myHandler = new MyHandler(); } } class MyHandler extends Handler { //放在主线程中显示 public MyHandler() { super(Looper.getMainLooper()); } @Override public void handleMessage(Message msg) { switch (msg.what){ case UPDATE: ProgressModel progressModel = (ProgressModel) msg.obj; if (mListener!=null)mListener.onProgress(progressModel.getCurrentBytes(),progressModel.getContentLength(),progressModel.isDone()); break; } } } @Override public MediaType contentType() { return requestBody.contentType(); } @Override public long contentLength() throws IOException { return requestBody.contentLength(); } @Override public void writeTo(BufferedSink sink) throws IOException { if (bufferedSink==null){ bufferedSink = Okio.buffer(sink(sink)); } //写入 requestBody.writeTo(bufferedSink); //刷新 bufferedSink.flush(); } private Sink sink(BufferedSink sink) { return new ForwardingSink(sink) { long bytesWritten = 0L; long contentLength = 0L; @Override public void write(Buffer source, long byteCount) throws IOException { super.write(source, byteCount); if (contentLength==0){ contentLength = contentLength(); } bytesWritten += byteCount; //回调 Message msg = Message.obtain(); msg.what = UPDATE; msg.obj = new ProgressModel(bytesWritten,contentLength,bytesWritten==contentLength); myHandler.sendMessage(msg); } }; } }

4.在MainActivity添加上传按钮点击事件,代码如下:

File file = new File(basePath + "/1.mp4"); String postUrl = "http://192.168.0.104:8080/OkHttpServer/UploadFileServlet"; OkHttpUtil.postFile(postUrl, new ProgressListener() { @Override public void onProgress(long currentBytes, long contentLength, boolean done) { Log.i(TAG, "currentBytes==" + currentBytes + "==contentLength==" + contentLength + "==done==" + done); int progress = (int) (currentBytes * 100 / contentLength); post_progress.setProgress(progress); post_text.setText(progress + "%"); } }, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if (response != null) { String result = response.body().string(); Log.i(TAG, "result===" + result); } } }, file);

相关效果图:

上传完成后,在电脑D:\huang\upload下可以看到:

源码下载

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-10-02 05:54:16

Android中实现OkHttp上传文件到服务器并带进度的相关文章

百度云Android版查找最新上传文件方法

给各位百度云软件的用户们来详细的解析分享一下百度云Android版查找最新上传文件的方法. 方法分享: 第一步:点击menu,选择排序. 第二步:选择按时间排序,排在最前面的文件就是这个当前目录中最新上传的文件了.   好了,以上的信息就是小编给各位百度云的这一款软件的用户们带来的详细的百度云Android版查找最新上传文件的方法解析分享的全部内容了,各位看到这里的软件用户们,小编相信大家现在那是非常的清楚查找的方法了吧,那么大家就快去按照小编上面的方法自己去查找的看看吧.

Android 解决WebView无法上传文件的问题

Android 解决WebView无法上传文件的问题 Android原生的WebView并不支持上传文件,需要我们自己实现相应的方法.于是我把工作中的相关代码记录下来.下次直接拿来用就行了.一点一滴都是经验. 1.需要定义三个变量 private ValueCallback<Uri[]> uploadMessageAboveL; private final static int FILE_CHOOSER_RESULT_CODE = 10000; private ValueCallback<

android 上传文件到服务器代码实例

android对于上传文件,还是很简单的,和java里面的上传都是一样的,基本上都是熟悉操作输出流和输入流!还有一个特别重要的就是需要一些content-type这些参数的配置!  如果这些都弄好了,上传就很简单了!   下面是我写的一个上传的工具类:复制代码 代码如下:package com.spring.sky.image.upload.network; import java.io.DataOutputStream;import java.io.File;import java.io.Fi

在Node.js中使用HTTP上传文件的方法

  这篇文章主要介绍了在Node.js中使用HTTP上传文件的方法,作者以windows下的visual studio作为操作node的环境,推荐阅读!需要的朋友可以参考下 开发环境 我们将使用 Visual Studio Express 2013 for Web 作为开发环境, 不过它还不能被用来做 Node.js 开发.为此我们需要安装 Node.js Tools for Visual Studio. 装好后 Visual Studio Express 2013 for Web 就会转变成一

asp.net,VS2012中如何在上传文件时可以一起选择多个不同种类的文件

问题描述 asp.net,VS2012中如何在上传文件时可以一起选择多个不同种类的文件 asp.net,VS2012中如何在上传文件时可以一起选择多个不同种类的文件,求大神解答,新手..,拜托了....

Android上传文件至服务器

本实例实现每隔5秒上传一次,通过服务器端获取手机上传过来的文件信息并做相应处理:采用Android+Struts2技术.            一.Android端实现文件上传 1).新建一个Android项目命名为androidUpload,目录结构如下:           2).新建FormFile类,用来封装文件信息 package com.ljq.utils; import java.io.File; import java.io.FileInputStream; import jav

android 上传文件到服务器

问题描述 android 上传文件到服务器 已知文件存放路径,例如"/sdcard/abc.doc",如何用最简单的语句将其上传到一个网络申请的空间(地址已有),跪求解答,很急!!! 解决方案 Android 上传文件,图片.以及服务器端接收相关. 解决方案二: 不应该先将其变成File对象,完了作为参数传给服务器端吗?服务器端做处理啊..

file-上传框中的名字上传文件怎么改为上传图片

问题描述 上传框中的名字上传文件怎么改为上传图片 上传框中的上传文件怎么改为上传图片,input type="file" name="myfiles"/>请大神们指点.... 解决方案 DEMO.. <!DOCTYPE html> <style> div.file{display:inline-block;width:100px;height:20px;line-height:20px;position:relative;overflo

Android实现上传文件到服务器实例详解_Android

本实例实现每隔5秒上传一次,通过服务器端获取手机上传过来的文件信息并做相应处理:采用Android+Struts2技术. 一.Android端实现文件上传 1).新建一个Android项目命名为androidUpload,目录结构如下: 2).新建FormFile类,用来封装文件信息 package com.ljq.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundExce