Android上传图片到本地服务器
2015-08-15 17:19
441 查看
先把客户端代码给贴上
下面是服务器端的程序
package com.example.administrator.myapplication; import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.provider.MediaStore; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; public class SecondActivity extends ActionBarActivity { private Button photoButton = null; private Button uploadButton = null; private ImageView imageView = null; private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100; private static final int MEDIA_TYPE_IMAGE = 1; private static final String LOG_TAG = "CameraActivity"; private Uri fileUri = null; public static File mediaFile; private Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); photoButton = (Button) findViewById(R.id.photoButton); uploadButton = (Button) findViewById(R.id.uploadButton); imageView = (ImageView) findViewById(R.id.imageView); TakePicListener captureListener = new TakePicListener(); photoButton.setOnClickListener(captureListener); UploadListener ul = new UploadListener(); uploadButton.setOnClickListener(ul); handler = new Handler() { @Override public void handleMessage(Message msg) { String result = msg.obj.toString(); if (result.equals(FileImageUpload.SUCCESS)) { Toast.makeText(SecondActivity.this, "上传成功!", Toast.LENGTH_SHORT).show(); } else if (result.equals(FileImageUpload.FAILURE)) { Toast.makeText(SecondActivity.this, "上传失败!!", Toast.LENGTH_SHORT).show(); } } }; } //监听拍照 class TakePicListener implements View.OnClickListener { @Override public void onClick(View v) { System.out.println("Take picture Button Click"); //调用系统自带的相机 Intent takePic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); fileUri = Uri.fromFile(getOutPutMediaFile(MEDIA_TYPE_IMAGE)); //下面这段使得照片存储到指定的位置 takePic.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); //跳转到系统相机,并且返回相片数据,在OnActivityForResult方法中处理数据 startActivityForResult(takePic, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); } } //监听上传 class UploadListener implements View.OnClickListener { @Override public void onClick(View v) { System.out.println("Upload Button clicked!"); //文件上传需要消耗很多时间,需要在WorkerThread中进行,否则UI线程会阻塞 UploadThread ut = new UploadThread(mediaFile); ut.start(); } } //新建一个WorkerThread,在uploadButton中要连接服务器,不能在UI线程中连接 class UploadThread extends Thread { //需要上传的文件 private File mUploadFile; public UploadThread(File file) { this.mUploadFile = file; } @Override public void run() { String flag = FileImageUpload.uploadFile(mUploadFile.getName()); Message msg = handler.obtainMessage(); msg.obj = flag; handler.sendMessage(msg); } } private File getOutPutMediaFile(int type) { //检查sd卡状态 String sdStatus = Environment.getExternalStorageState(); if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { System.out.println("SD Card is not available!"); return null; } File mediaStorageDir = null; try { //在sd卡目录下面新建一个文件夹 mediaStorageDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyPicture"); System.out.println("Successfully created mediaStorageDir: " + mediaStorageDir); } catch (Exception e) { e.printStackTrace(); System.out.println("Error int Creating mediaStorageDir: " + mediaStorageDir); } //检查目录是否创建成功 if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { //在sd卡上穿件目录需要权限 System.out.println("failed to create directory, check if you have the WRITE_EXTERNAL_STORAGE permission"); return null; } } //创建图片名字,图片名字不要太长,原因不明。。。 String timeStamp = new SimpleDateFormat("hhmmss").format(new Date()); //在mediaStorageDir目录下创建图片文件 mediaFile = new File(mediaStorageDir.getPath() + File.separator + "image" + timeStamp + ".jpg"); System.out.println("图片存放地址: " + mediaFile.getAbsolutePath()); return mediaFile; } /** * * @param requestCode 可以根据这个requestCode知道是哪个东西(例如拍照或者录像)请求数据 * @param resultCode 请求是否成功 * @param data 返回的数据 */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.d(LOG_TAG, "onActivityResult: requestCode: " + requestCode + " ,resultCode: " + resultCode); if (CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE == requestCode) { if (resultCode == Activity.RESULT_OK) { //检测sd卡状态 String sdStatus = Environment.getExternalStorageState(); if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { System.out.println("SD卡可用!"); return; } //data = null代表数据已经存储到指定的位置,如果data不为空即代表你没有指定存储目录,而是存在了默认的位置 if (data == null) { Log.d(LOG_TAG, "data is null , file saved on target position"); int width = imageView.getWidth(); int height = imageView.getHeight(); //BitmapFactory.Optins是BitmapFactory的内部类,用于配置图片的缩放设置 //因为每个android app只有16mb内存的限制(不一定的,有的手机更大), // 图片太大,用java处理就会破了16mb BitmapFactory.Options factoryOptions = new BitmapFactory.Options(); //inJustDecodeBounds设置成true之后通过decodeFile只会得出图片的宽高避免内存溢出 factoryOptions.inJustDecodeBounds = true; BitmapFactory.decodeFile(fileUri.getPath(), factoryOptions); //获取图片的原始宽高 int imageWidth = factoryOptions.outWidth; int imageHeight = factoryOptions.outHeight; //计算缩放比例 int scaleFactory = Math.min(imageHeight / height, imageWidth / width); //设置inJustDecodeBounds为false,获取缩放后的图片 factoryOptions.inJustDecodeBounds = false; //设置缩放比例 factoryOptions.inSampleSize = scaleFactory; // 如果 inPurgeable 设为True的话表示使用BitmapFactory创建的Bitmap //用于存储Pixel的内存空间在系统内存不足时可以被回收 factoryOptions.inPurgeable = true; Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(), factoryOptions); imageView.setImageBitmap(bitmap); } } } } } /** * 文件上传类 */ class FileImageUpload{ private static final int TIME_OUT = 10 * 1000000; private static final String CHARSET = "UTF-8"; public static final String SUCCESS = "1"; public static final String FAILURE = "2"; private static final String uploadUrl = "http://192.168.2.101:8080/Test/server/upload"; public static String uploadFile(String file){ String BOUNDARY = UUID.randomUUID().toString();//边界标示 随机生成 String PREFIX = "--"; String LINE_END = "\r\n"; String CONTENT_TYPE = "multipart/form-data"; try{ URL url = new URL(uploadUrl); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); conn.setReadTimeout(TIME_OUT); conn.setConnectTimeout(TIME_OUT); conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); conn.setRequestMethod("POST");//设置setDoOutput为true默认把方法设成POST conn.setRequestProperty("Charset", CHARSET); conn.setRequestProperty("connection", "keep-alive"); conn.setRequestProperty("Content-type",CONTENT_TYPE + ";boundary=" + BOUNDARY); //上面的请求设置必须正确 if(file != null){ //如果file不为空,把文件包装并上传 DataOutputStream dos = new DataOutputStream(conn.getOutputStream()); StringBuffer sb = new StringBuffer(); sb.append(PREFIX); sb.append(BOUNDARY); sb.append(LINE_END); /** * name为服务器端需要的key,只有这个key才可以得到对应的文件 * filename是文件的名字,比如abc.jpg */ sb.append("Content-Disposition: form-data; name=\"upload\";filename=\"" + file + "\"" + LINE_END); sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END); sb.append(LINE_END); dos.write(sb.toString().getBytes()); InputStream is = new FileInputStream(SecondActivity.mediaFile); byte[] bytes = new byte[1024]; int len = 0; while((len = is.read(bytes)) != -1){ dos.write(bytes, 0, len); } is.close(); dos.write(LINE_END.getBytes()); byte [] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes(); dos.write(end_data); dos.flush(); /** * 获取响应吗 200 = 成功 * 当响应成功,获取响应的流 */ int res = conn.getResponseCode(); System.out.println("response code: " + res); if(res == 200){ return SUCCESS; } } } catch(MalformedURLException e){ e.printStackTrace(); } catch(Exception e){ e.printStackTrace(); System.out.println("上传失败"); } return FAILURE; } }
下面是服务器端的程序
<pre name="code" class="java">import java.util.*; import java.io.*; import javax.management.loading.PrivateClassLoader; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.tomcat.util.*; import org.apache.tomcat.util.http.fileupload.*; import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory; import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload; import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext; import org.omg.CORBA.PRIVATE_MEMBER; public class UploadServlet extends HttpServlet { private String filePath; private String tempFilePath; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException ,IOException { doPost(request, response); }; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //临时目录,这里必须手动在你的webapps/服务器目录/手动创建一个temp文件夹 tempFilePath = request.getSession().getServletContext().getRealPath("/temp"); response.setContentType("text/plain"); System.out.println(tempFilePath); try{ //创建一个基于硬盘的FileItem工厂,这个工厂可以讲request里面的每个项目转换成DiskFileItem(FileItem接口的实现) DiskFileItemFactory factory = new DiskFileItemFactory(); //设置项硬盘写数据时所用的缓冲区大小,单位为字节 factory.setSizeThreshold(4 * 1024); //设置临时目录 factory.setRepository(new File(tempFilePath)); //创建一个文件上传处理器 ServletFileUpload upload = new ServletFileUpload(factory); //设置允许上传的文件的最大尺寸,此处为10M upload.setSizeMax(10 * 1024 * 1024); ServletRequestContext requestContext = new ServletRequestContext(request); List<FileItem> items = upload.parseRequest(requestContext); Iterator iter = items.iterator(); while(iter.hasNext()){ FileItem item = (FileItem)iter.next(); String fileName = item.getName(); int index = fileName.lastIndexOf("/"); //获取文件名 fileName = fileName.substring(index + 1, fileName.length()); //下面的代码必须注意,要保存的目录必须用StringBuffer连接起来,否则系统会找不到这个文件 StringBuffer sb = new StringBuffer(); sb.append("/upload/"); sb.append(fileName); filePath = request.getSession().getServletContext().getRealPath(sb.toString()); if(item.isFormField()){ processFormField(item); } else{ processUploadFile(item); } } }catch(Exception e){ System.out.println("can not find the file"); e.printStackTrace(); } } private void processFormField(FileItem item) throws Exception{ //获取表单名 String name = item.getFieldName(); String value = item.getString("UTF-8"); System.out.println("Field name: " + name); System.out.println("Value: " + value); } private void processUploadFile(FileItem item) throws Exception{ File uploadedFile = new File(filePath); System.out.println(uploadedFile); item.write(uploadedFile); } }
相关文章推荐
- Android Studio设置字体 编码格式
- 配置android studio环境-Hello world
- Android studio的快捷键
- android profile memory usage(2)
- android 音频策略介绍
- 配置android studio环境2
- Android基础入门教程——4.2.2 Service进阶
- 配置android studio环境
- Android Studio 的下载及安装
- Android性能优化之布局优化
- Android组件之Activity讲解
- Android中的DVM和Java中的JVM的异同点?
- AndroidTouch事件总结
- android中使用JSOUP如何解析网页数据详述
- Android编码规范
- AIDL进程间传递复杂数据类型—AIDL传递android.os.Parcelable接口
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- android windowSoftInputMode说明
- Android之——ContentProvider操作XML
- 安卓学习笔记(一)自定义控件1