标签:
Activity
/**实际开发涉及文件上传、下载都不会自己写这些代码,一般会集成第三方库来完成,比如android-async-http,okhttp,xUtils等*/public class UploadFileActivity extends ListActivity {private ImageView imageView;private TextView tv_info;public static final int uid = 10415362;private String session_id = "若看到此内容,说明你还没登录";//每次登录都不一样public static final String path = Environment.getExternalStorageDirectory().getPath() + File.separator;private Bitmap bitmap;/**裁剪图片后的返回码*/public static final int REQUEST_CROP_IMG_CODE_TRUE = 100;public static final int REQUEST_CROP_IMG_CODE_FALSE = 101;public static final int MSG_WHAT_BITMAP = 1;@SuppressLint("HandlerLeak")private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case MSG_WHAT_BITMAP:imageView.setImageBitmap((Bitmap) (msg.obj));break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);String[] array = { "加载我的头像", "使用相机拍照并【获取】照片", "使用相机拍照并【裁剪】照片", "从图库获取并裁剪照片", "从图库获取并裁剪照片2", //"使用AsyncHttpClient上传图片", "通过HttpUrlCon拼接或HTTP协议(失败)" };for (int i = 0; i < array.length; i++) {array[i] = i + "、" + array[i];}imageView = new ImageView(this);getListView().addFooterView(imageView);tv_info = new TextView(this);tv_info.setTextColor(Color.BLUE);tv_info.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);tv_info.setPadding(20, 10, 20, 10);getListView().addFooterView(tv_info);setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new ArrayList<String>(Arrays.asList(array))));//初始化if (MyApplication.getApplication().getUser() != null) session_id = MyApplication.getApplication().getUser().getuSessionId();tv_info.setText("session_id=" + session_id);}@Overrideprotected void onListItemClick(ListView l, View v, int position, long id) {switch (position) {case 0:loadMyImg();break;case 1:startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE), 11);//调用系统相机拍照break;case 2:Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(path + "temp.png")));//将返回的数据保存到指定位置startActivityForResult(intent, 12);break;case 3:Intent intent3 = new Intent(Intent.ACTION_PICK);intent3.setType("image/*");startActivityForResult(intent3, 13);break;case 4:Intent intent4 = new Intent(Intent.ACTION_PICK);intent4.setType("image/*");startActivityForResult(intent4, 14);break;case 5:asyncUploadFile();break;case 6:httpURLConUploadFile();break;}}/**加载我的头像,也即刚上传的图片*/private void loadMyImg() {if (MyApplication.getApplication().getUser() != null) {new Thread(new Runnable() {@Overridepublic void run() {String imgUrl = MyApplication.getApplication().getUser().getuAvatarUrl();//头像存放位置InputStream inputStream = HttpUrlClientUtils.getInputStreamFromUrl(imgUrl);Bitmap bitmap = BitmapFactory.decodeStream(inputStream);mHandler.sendMessage(Message.obtain(mHandler, MSG_WHAT_BITMAP, bitmap));}}).start();}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);switch (requestCode) {case 11:// 数据通过onActivityResult中的Intent返回。返回的并非原图,照片会自动进行压缩!if (data == null) return;bitmap = (Bitmap) data.getExtras().get("data");imageView.setImageBitmap(bitmap);tv_info.setText("返回的Bitmap尺寸为" + bitmap.getWidth() + " * " + bitmap.getHeight());break;case 12://数据通过指定的Uri返回。注意,由于数据已返回到其他地方(这里是保存到了SD卡中),所以这里返回的data == nulltv_info.setText("照片已保存到指定的Uri中-" + (data == null));cropImageReturnTrue(this, Uri.fromFile(new File(path + "temp.png")), 72 * 4, 72 * 4);break;case 13://数据通过系统默认的Uri返回。data.getData()的结果为【content://media/external/images/media/15767】if (data == null) return;tv_info.setText("18-已获取保存在Uri中的照片,Uri=:" + data.getData());cropImageReturnTrue(this, data.getData(), 72 * 4, 72 * 4);break;case 14://数据通过系统默认的Uri返回if (data == null) return;tv_info.setText("19-已获取保存在Uri中的照片,Uri=:" + data.getData());cropImageReturnFalse(this, data.getData(), 72 * 4, 72 * 4);break;case REQUEST_CROP_IMG_CODE_TRUE: // 裁剪后的图片通过onActivityResult中的Intent返回bitmap = (Bitmap) data.getParcelableExtra("data");imageView.setImageBitmap(bitmap);tv_info.setText("1、裁剪后的尺寸为:" + bitmap.getWidth() + " * " + bitmap.getHeight());break;case REQUEST_CROP_IMG_CODE_FALSE: //裁剪后的图片通过指定的Uri返回(这里是保存到SD上)try {bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), Uri.fromFile(new File(path + "temp.png")));imageView.setImageBitmap(bitmap);tv_info.setText("2、裁剪后的尺寸为:" + bitmap.getWidth() + " * " + bitmap.getHeight());} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}break;}}//******************************************************************************************************************************************// 获取图片//******************************************************************************************************************************************/*** 调出图库APP的裁剪图片功能,将指定Uri中的图片裁剪为指定大小*/public static void cropImageReturnTrue(Activity context, Uri uri, int desWidth, int desHeight) {if (uri == null) return;//指定action是使用系统图库裁剪图片Intent intent = new Intent("com.android.camera.action.CROP");intent.setDataAndType(uri, "image/*");//设置在开启的Intent中,显示的VIEW可裁剪intent.putExtra("crop", "true");//设置裁剪比例及裁剪图片的具体宽高intent.putExtra("aspectX", 1);intent.putExtra("aspectY", 1);intent.putExtra("outputX", desWidth);intent.putExtra("outputY", desHeight);//设置是否允许拉伸intent.putExtra("scale", true);intent.putExtra("scaleUpIfNeeded", true);//设置输出格式intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());//设置是否需要人脸识别,默认不需要设置intent.putExtra("noFaceDetection", true);//设置是否返回数据。如果要在给定的uri中返回图片,则必须设置为false;如果设置为true,那么便不会在给定的uri中获取到裁剪的图片//这里我们直接将数据返回到了onActivityResult中的intent中了,不需要返回到给定的uri中,所以设为trueintent.putExtra("return-data", true);context.startActivityForResult(intent, REQUEST_CROP_IMG_CODE_TRUE);}/*** 调出图库APP的裁剪图片功能,将指定Uri中的图片裁剪为指定大小.方式二*/public static void cropImageReturnFalse(Activity context, Uri uri, int desWidth, int desHeight) {if (uri == null) return;Intent intent = new Intent("com.android.camera.action.CROP");intent.setDataAndType(uri, "image/*");intent.putExtra("crop", "true");intent.putExtra("aspectX", 1);intent.putExtra("aspectY", 1);intent.putExtra("outputX", desWidth);intent.putExtra("outputY", desHeight);intent.putExtra("scale", true);// intent.putExtra("scaleUpIfNeeded", true);intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());intent.putExtra("noFaceDetection", true);intent.putExtra("return-data", false);//这里是唯一不同的地方//将数据返回到指定的uri中。注意:若裁减时打开图片的uri与保存图片的uri相同,会产生冲突,导致裁减完成后图片的大小变成0Byte。intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(path + "temp.png")));context.startActivityForResult(intent, REQUEST_CROP_IMG_CODE_FALSE);}//******************************************************************************************************************************************// AsyncHttpClient//******************************************************************************************************************************************/*** 采用AsyncHttpClient上传图片,只能是post方式*/private void asyncUploadFile() {if (bitmap == null) {Toast.makeText(this, "还没设置图片呢", Toast.LENGTH_SHORT).show();return;}ByteArrayOutputStream baos = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);//质量压缩RequestParams params = new RequestParams();//add方法可以给同一个key值传多个value,它会存在一个list里面;而put方法只能给同一个key传唯一的一个value,如果传多个,后一个会替换掉前一个params.put("uid", uid);params.put("session_id", session_id);params.put("image", new ByteArrayInputStream(baos.toByteArray()), "headImg", "image/*");//核心代码//params.put("image", new String(Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT)));//具体是以哪种方式发给服务器,需要和服务器商议确定ProgressDialogUtil.showProgressDialog(this, "", "提交中...");AsyncXiuHttpHelper.post(UrlOfServer.RQ_MSG_EDIT, params, new OnHttpListener<JSONObject>() {@Overridepublic void onHttpListener(boolean httpSuccessed, JSONObject obj) {ProgressDialogUtil.dismissProgressDialog();tv_info.setText(JsonFormatTool.formatJson(obj.toString()));if (httpSuccessed) {Toast.makeText(UploadFileActivity.this, "成功", Toast.LENGTH_SHORT).show();reLogin();} else Toast.makeText(UploadFileActivity.this, "失败", Toast.LENGTH_SHORT).show();}});}/**重新登录*/protected void reLogin() {Bundle loginBundle = new Bundle();loginBundle.putString("account", "103468");loginBundle.putString("password", "103468");Intent intent = new Intent(this, LoginActivity.class);intent.putExtras(loginBundle);startActivity(intent);imageView.setImageResource(R.drawable.ic_launcher);}//******************************************************************************************************************************************// HttpURLConn//******************************************************************************************************************************************/*** 采用HttpURLConn上传图片,未成功*/private void httpURLConUploadFile() {final File file = new File(Environment.getExternalStorageDirectory(), "a.png");if (!file.exists() || file.length() == 0) {Toast.makeText(this, "文件不存在", Toast.LENGTH_SHORT).show();return;}//普通参数final Map<String, String> strMap = new HashMap<String, String>();strMap.put("session_id", session_id);strMap.put("uid", uid + "");//文件参数final Map<String, File> fileMap = new HashMap<String, File>();fileMap.put("image", file);final String url = "http://" + AsyncXiuHttpHelper.SERVER_URL + UrlOfServer.RQ_MSG_EDIT;ProgressDialogUtil.showProgressDialog(this, "", "申请中...", false, null);new Thread(new Runnable() {@Overridepublic void run() {try {HttpUploadFilesUtils.post(url, strMap, fileMap);} catch (Exception e) {e.printStackTrace();}final String str = HttpUploadFilesUtils.post(url, strMap, fileMap);runOnUiThread(new Runnable() {@Overridepublic void run() {ProgressDialogUtil.dismissProgressDialog();try {tv_info.setText(JsonFormatTool.formatJson(new JSONObject(str).toString()));} catch (JSONException e) {e.printStackTrace();}}});}}).start();}}
上传文件工具类
/** 上传文件工具类,千万不要花太多时间再这上面,实际开发中不可能用这种方式的! */public class HttpUploadFilesUtils {public static final String BOUNDARY = UUID.randomUUID().toString(); //边界标识,随机生成public static final String PREFIX = "--";public static final String LINEND = "\r\n";//是【"\r\n"】不是【"/r/n"】public static final String MULTIPART_FROM_DATA = "multipart/form-data";public static final String CHARSET = "UTF-8";protected static final String TAG = "HttpUploadFilesUtils";/*** 通过拼接的方式构造请求内容,实现参数传输以及文件传输*/public static String post(String actionUrl, Map<String, String> params, Map<String, File> files) {try {URL uri = new URL(actionUrl);HttpURLConnection conn = (HttpURLConnection) uri.openConnection();conn.setConnectTimeout(5000);conn.setReadTimeout(3000);conn.setDoInput(true);// 允许输入conn.setDoOutput(true);// 允许输出conn.setUseCaches(false); // 不允许使用缓存conn.setRequestMethod("POST");conn.setRequestProperty("Connection", "Keep-Alive");conn.setRequestProperty("Charsert", "UTF-8");conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA + ";boundary=" + BOUNDARY);// 首先组拼String类型的参数StringBuilder sb = new StringBuilder();for (Map.Entry<String, String> entry : params.entrySet()) {sb.append(PREFIX + BOUNDARY + LINEND);sb.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"" + LINEND);sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);sb.append("Content-Transfer-Encoding: 8bit" + LINEND);sb.append(LINEND);sb.append(entry.getValue());sb.append(LINEND);}//将java基本数据类型写入【数据输出流DataOutputStream】中,并可以通过【数据输入流DataInputStream】将数据读入DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());//创建一个将数据写入指定输出流OutputStream的数据输出流outStream.write(sb.toString().getBytes());//将数据写入上述构造方法中传入的输出流//然后组拼File类型的参数if (files != null) {for (Map.Entry<String, File> file : files.entrySet()) {StringBuilder sb1 = new StringBuilder();sb1.append(PREFIX + BOUNDARY + LINEND);// name是post中传参的键,filename是文件的名称sb1.append("Content-Disposition: form-data; name=\"file1\"; filename=\"" + file.getKey() + "\"" + LINEND);sb1.append("Content-Type: multipart/form-data" + LINEND);sb1.append(LINEND);outStream.write(sb1.toString().getBytes());InputStream is = new FileInputStream(file.getValue());byte[] buffer = new byte[1024];int len = 0;while ((len = is.read(buffer)) != -1) {outStream.write(buffer, 0, len);}is.close();outStream.write(LINEND.getBytes());}// 请求结束标志byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();outStream.write(end_data);outStream.flush();// 得到响应码int res = conn.getResponseCode();Log.i("bqt", "++++++" + res);//500,服务器异常InputStream inputStream = conn.getInputStream();Log.i("bqt", "++++++" + 3);if (res == 200) {int ch;StringBuilder sb2 = new StringBuilder();while ((ch = inputStream.read()) != -1) {sb2.append((char) ch);}Log.i("bqt", "++++++" + sb2.toString());return sb2.toString();}outStream.close();conn.disconnect();return "响应失败" + res;}} catch (MalformedURLException e) {e.printStackTrace();return "MalformedURLException";} catch (ProtocolException e) {e.printStackTrace();return "ProtocolException";} catch (FileNotFoundException e) {e.printStackTrace();return "FileNotFoundException";} catch (IOException e) {e.printStackTrace();return "IOException";}return "失败";}/*** 直接通过HTTP协议提交数据到服务器,实现如下面表单提交功能:*/public static boolean uploadFiles(String path, Map<String, String> params, FormFileBean[] files) throws Exception {final String BOUNDARY = "---------------------------7da2137580612"; //数据分隔线final String endline = "--" + BOUNDARY + "--\r\n";//数据结束标志int fileDataLength = 0;if (files != null && files.length != 0) {for (FormFileBean uploadFile : files) {//得到文件类型数据的总长度StringBuilder fileExplain = new StringBuilder();fileExplain.append("--");fileExplain.append(BOUNDARY);fileExplain.append("\r\n");fileExplain.append("Content-Disposition: form-data;name=\"" + uploadFile.getParameterName() + "\";filename=\"" + uploadFile.getFilname() + "\"\r\n");fileExplain.append("Content-Type: " + uploadFile.getContentType() + "\r\n\r\n");fileExplain.append("\r\n");fileDataLength += fileExplain.length();if (uploadFile.getInStream() != null) {fileDataLength += uploadFile.getFile().length();} else {fileDataLength += uploadFile.getData().length;}}}StringBuilder textEntity = new StringBuilder();if (params != null && !params.isEmpty()) {for (Map.Entry<String, String> entry : params.entrySet()) {//构造文本类型参数的实体数据textEntity.append("--");textEntity.append(BOUNDARY);textEntity.append("\r\n");textEntity.append("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"\r\n\r\n");textEntity.append(entry.getValue());textEntity.append("\r\n");}}//计算传输给服务器的实体数据总长度int dataLength = textEntity.toString().getBytes().length + fileDataLength + endline.getBytes().length;URL url = new URL(path);int port = url.getPort() == -1 ? 80 : url.getPort();Socket socket = new Socket(InetAddress.getByName(url.getHost()), port);OutputStream outStream = socket.getOutputStream();//下面完成HTTP请求头的发送String requestmethod = "POST " + url.getPath() + " HTTP/1.1\r\n";outStream.write(requestmethod.getBytes());String accept = "Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n";outStream.write(accept.getBytes());String language = "Accept-Language: zh-CN\r\n";outStream.write(language.getBytes());String contenttype = "Content-Type: multipart/form-data; boundary=" + BOUNDARY + "\r\n";outStream.write(contenttype.getBytes());String contentlength = "Content-Length: " + dataLength + "\r\n";outStream.write(contentlength.getBytes());String alive = "Connection: Keep-Alive\r\n";outStream.write(alive.getBytes());String host = "Host: " + url.getHost() + ":" + port + "\r\n";outStream.write(host.getBytes());//写完HTTP请求头后根据HTTP协议再写一个回车换行outStream.write("\r\n".getBytes());//把所有文本类型的实体数据发送出来outStream.write(textEntity.toString().getBytes());//把所有文件类型的实体数据发送出来if (files != null && files.length != 0) {for (FormFileBean uploadFile : files) {StringBuilder fileEntity = new StringBuilder();fileEntity.append("--");fileEntity.append(BOUNDARY);fileEntity.append("\r\n");fileEntity.append("Content-Disposition: form-data;name=\"" + uploadFile.getParameterName() + "\";filename=\"" + uploadFile.getFilname() + "\"\r\n");fileEntity.append("Content-Type: " + uploadFile.getContentType() + "\r\n\r\n");outStream.write(fileEntity.toString().getBytes());if (uploadFile.getInStream() != null) {byte[] buffer = new byte[1024];int len = 0;while ((len = uploadFile.getInStream().read(buffer, 0, 1024)) != -1) {outStream.write(buffer, 0, len);}uploadFile.getInStream().close();} else {outStream.write(uploadFile.getData(), 0, uploadFile.getData().length);}outStream.write("\r\n".getBytes());}}//下面发送数据结束标志,表示数据已经结束outStream.write(endline.getBytes());BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));String codeString = reader.readLine();outStream.flush();outStream.close();reader.close();socket.close();if (codeString.indexOf("200") == -1) {//读取web服务器返回的数据,判断请求码是否为200,如果不是200,代表请求失败return false;}return true;}//**************************************************************************************************************************//通过HttpURLConnection手动完成浏览器帮我们做的事,对传输的数据进行规范化的拼接public static String uploadByHttpURLConnection(String filePath, String strUrl) {int TIME_OUT = 5 * 1000; //超时时间String CHARSET = "utf-8"; //设置编码String result = null;//返回响应的内容String BOUNDARY = UUID.randomUUID().toString(); //边界标识,随机生成String PREFIX = "--", LINE_END = "\r\n";String CONTENT_TYPE = "multipart/form-data"; //内容类型try {URL url = new URL(strUrl);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"); //请求方式conn.setRequestProperty("Charset", CHARSET); //设置编码conn.setRequestProperty("connection", "keep-alive");conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY);//conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");// conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//当文件不为空,把文件包装并且上传File file = new File(filePath);if (file.exists() && file.length() > 0) {DataOutputStream dos = new DataOutputStream(conn.getOutputStream());StringBuffer sb = new StringBuffer();sb.append(PREFIX);sb.append(BOUNDARY);sb.append(LINE_END);//这里重点注意:name里面的值为服务器端需要key,只有这个key 才可以得到对应的文件,filename是文件的名字,包含后缀名的sb.append("Content-Disposition: form-data; name=\"img\"; filename=\"" + file.getName() + "\"" + 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(file);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();Log.e(TAG, "response code:" + res);if (res == 200) {Log.e(TAG, "成功");InputStream input = conn.getInputStream();StringBuffer sb1 = new StringBuffer();int ss;while ((ss = input.read()) != -1) {sb1.append((char) ss);}result = sb1.toString();Log.e(TAG, "result : " + result);} else Log.e(TAG, "失败");} else Log.e(TAG, "文件不存在" + filePath);} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return result;}//**************************************************************************************************************************//采用第三方异步框架AsynchHttpClient上传文件public static void uploadByAsyncHttpClient(String filePath, String strUrl) {File file = new File(filePath);if (file.exists() && file.length() > 0) {AsyncHttpClient asyncHttpClient = new AsyncHttpClient();RequestParams requestParams = new RequestParams();try {requestParams.put("profile_picture", file);} catch (FileNotFoundException e) {e.printStackTrace();}asyncHttpClient.post(strUrl, requestParams, new AsyncHttpResponseHandler() {@Overridepublic void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {Log.e(TAG, "成功");}@Overridepublic void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {Log.e(TAG, "失败");}});} else Log.e(TAG, "文件不存在" + filePath);}}
标签:
原文地址:http://www.cnblogs.com/baiqiantao/p/5559329.html