Android 通过form表单上传文字,图片,视频等(通过key值)以及问题分析
来源:互联网 发布:手机扫描ip软件 编辑:程序博客网 时间:2024/05/16 08:52
Android 通过form表单上传文字,图片,视频等(通过key值)以及问题分析
最近做到上传的时候,弄了一段时间,也遇到了一些问题和解决方案,在这里就和大家分享一下,希望对你们有用,谢谢。
好了,思想+代码
上传类Java代码:
/** * Created by aierJun on 2017/3/9. */public class UploadUtils { private static String BOUNDARY = UUID.randomUUID().toString(); //边界标识 随机生成 private static String PREFIX = "--", LINE_END = "\r\n"; private static String CONTENT_TYPE = "multipart/form-data"; //内容类型 private static final String TAG = "uploadFile"; private static final int TIME_OUT = 10 * 1000; //超时时间 private static final String CHARSET = "utf-8"; //设置编码 private static int state; /** * @category 上传文件至Server的方法 * @param uploadUrl 上传路径参数 * @author ylbf_dev */ public static boolean uploadFile(final ArrayList<File> imagefiles,final ArrayList<File> videofiles, final String uploadUrl,final ArrayList<String> name,final ArrayList<Object> values) { new Thread(new Runnable() { @Override public void run() { 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"); //请求方式 conn.setRequestProperty("Charset", CHARSET); //设置编码 conn.setRequestProperty("connection", "keep-alive"); conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY); 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.png */ if (name!=null&&name.size()>0) for (int i=0;i<name.size();i++){ addText(name.get(i),values.get(i)+"",dos); } addImage(imagefiles,dos); addVedio(videofiles,dos); // 读取服务器返回结果 InputStream isBack = conn.getInputStream(); InputStreamReader isr = new InputStreamReader(isBack, "utf-8"); BufferedReader br = new BufferedReader(isr); String result = br.readLine(); Log.d("Jun",result); dos.close(); JSONObject jsonObject =new JSONObject(result); state=jsonObject.optInt("State"); } catch (Exception e) { e.printStackTrace(); } } }).start(); if (state==1){ return true; }else{ return false; } } private static void addText(String name,Object value,DataOutputStream output) { StringBuilder sb = new StringBuilder(); sb.append(PREFIX + BOUNDARY + LINE_END); sb.append("Content-Disposition: form-data; name=\""+name+"\"" + LINE_END); sb.append(LINE_END); sb.append(value + LINE_END); sb.append(PREFIX + BOUNDARY + LINE_END); try { output.writeBytes(sb.toString());// 发送表单字段数据 } catch (IOException e) { throw new RuntimeException(e); } } private static void addImage(ArrayList<File> files, DataOutputStream output) { if (files.size()<1||files==null) return; try { StringBuilder sb = new StringBuilder(); sb.append(PREFIX + BOUNDARY + LINE_END); sb.append("Content-Disposition: form-data; name=\"image\"; filename=\"" + files.get(0).getName() + "\"" + LINE_END); sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END); sb.append(LINE_END); output.write(sb.toString().getBytes()); InputStream is = new FileInputStream(files.get(0)); byte[] bytes = new byte[1024]; int len = 0; Log.d("Jun","开始上传"); while ((len = is.read(bytes)) != -1) { output.write(bytes, 0, len); } is.close(); output.write(LINE_END.getBytes()); byte[] end_data = (PREFIX + BOUNDARY + LINE_END).getBytes(); output.write(end_data); }catch (Exception e){ throw new RuntimeException(e); } } private static void addVedio(ArrayList<File> files, DataOutputStream output) { if (files==null||files.size()<1) return; try { StringBuilder sb = new StringBuilder(); sb.append(PREFIX + BOUNDARY + LINE_END); sb.append("Content-Disposition: form-data; name=\"video\"; filename=\"" + files.get(0).getName() + "\"" + LINE_END); sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END); sb.append(LINE_END); output.write(sb.toString().getBytes()); InputStream is = new FileInputStream(files.get(0)); byte[] bytes = new byte[1024]; int len = 0; final int headerSize = sb.length(); Log.d("Jun","开始上传"); while ((len = is.read(bytes)) != -1) { output.write(bytes, 0, len); } is.close(); output.write(LINE_END.getBytes()); byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes(); output.write(end_data); Log.d("Jun",output+""); }catch (Exception e){ throw new RuntimeException(e); } }}
注意:上面的为封装方法。有text,Image,video。
对上面的分析在下面的问题里会有说明。
java调用方法:
public ArrayList<File> files=new ArrayList<>(); private ArrayList<String> names=new ArrayList<>(); private ArrayList<Object> values=new ArrayList<>();//添加数据boolean state=UploadUtils.uploadFile(files,null, APIManger.PUSH_STORY, names, values);
注意这里的添加数据name和values是一一对应的关系,小心数据乱了name.add()后values.add();或者再用Arraylist,保证对应就行。
遇到的问题分析:
一.text可以上传,image可以上传,但video不能上传
1.起初,我调试的时候发现视频总是服务器端接收不到,但后,我把image的添加给注销掉了,用video直接上传,发现视频是可以上传的,但就是一起不能实现,然后debug
2.
3.
4.
5.
6,最后问题找到了,开始标签和结束标签的问题。修改为上面的图4和图5,好了。一般的开始–xxx,结束–xxx,最后一次的开始–xxx,结束–xxx–,注意换行我省略了。
二,视频选取和视频路径不是绝对的问题
1,image解决方法
Uri uri = data.getData(); Cursor cursor = PushVedioActivity.this.getContentResolver().query(uri, null, null, null, null); cursor.moveToFirst(); String imgNo = cursor.getString(0); // 图片编号 String imgPath = cursor.getString(1); // 图片文件路径 filesImage.add(new File(imgPath)); String imgSize = cursor.getString(2); // 图片大小 String imgName = cursor.getString(3); // 图片文件名 cursor.close();
2,最终完美解决方案
/** * Created by aierJun on 2017/3/13. */public class UriAllUriUtils { /** * 专为Android4.4设计的从Uri获取文件绝对路径,以前的方法已不好使 */ @SuppressLint("NewApi") public static String getPath(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; // DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { // ExternalStorageProvider if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } // TODO handle non-primary volumes } // DownloadsProvider else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); final Uri contentUri = ContentUris.withAppendedId( Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } // MediaProvider else if (isMediaDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[] { split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) { return getDataColumn(context, uri, null, null); } // File else if ("file".equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return null; } /** * Get the value of the data column for this Uri. This is useful for * MediaStore Uris, and other file-based ContentProviders. * * @param context * The context. * @param uri * The Uri to query. * @param selection * (Optional) Filter used in the query. * @param selectionArgs * (Optional) Selection arguments used in the query. * @return The value of the _data column, which is typically a file path. */ public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = "_data"; final String[] projection = { column }; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int column_index = cursor.getColumnIndexOrThrow(column); return cursor.getString(column_index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * @param uri * The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } /** * @param uri * The Uri to check. * @return Whether the Uri authority is DownloadsProvider. */ public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } /** * @param uri * The Uri to check. * @return Whether the Uri authority is MediaProvider. */ public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); }}
注意:封装方法
三,文字text编码格式问题
/** * Created by aierJun on 2017/3/13. */public class GetFormStringUTF8Utils { public static String getUTF8String(String string){ String s=null; try { s= new String(string.getBytes("UTF-8"),"ISO8859-1"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return s; }}
注意:封装方法
编码详细请点击此连接
以上,为个人上传的总结,希望对你们有用,如有错误和误解请指教,谢谢。
如需转载,请注明出处http://blog.csdn.net/aierJun/article/details/61916699,谢谢
0 0
- Android 通过form表单上传文字,图片,视频等(通过key值)以及问题分析
- 通过表单上传视频
- android通过xutils上传图片。通过apx.net接收问题
- Android视频编辑器(一)通过OpenGL预览、录制视频以及断点续录等
- Android通过HTTP协议上传图片(multipart/form-data格式)
- SSM框架form表单上传图片接不到值问题
- 使用form表单上传图片问题
- android通过http上传文件(图片)
- JavaEE_Mybatis_SpringMVC_(通过表单form)SpringMVC的文件上传
- 通过传统的form表单提交的方式上传文件
- 通过Ajax提交form表单来提交上传文件
- 关于第三方应用(Android平台)通过微信分享文字、图片的问题研究。
- WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)
- WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)
- WebAPI通过multipart/form-data方式同时上传文件以及数据(含HttpClient上传Demo)
- javascript构造可以上传文件的form表单(通过js修改enctype)
- javascript构造可以上传文件的form表单(通过js修改enctype)
- javascript构造可以上传文件的form表单(通过js修改enctype)
- Linux环境下配置搭建Redis分布式集群
- 【MyBatis学习04】mapper代理方法开发dao
- 【MyBatis学习04】mapper代理方法开发dao
- linux shell dash&bash
- BZOJ P2241[sdoi2011]打地鼠
- Android 通过form表单上传文字,图片,视频等(通过key值)以及问题分析
- C++标准库之<iomanip>
- 在线免费生成IntelliJ IDEA 15.0(16.+)注册码
- 封装webview
- typeof返回值
- 火狐浏览器和谷歌浏览器主页被篡改恢复方法
- Longest Ordered Subsequence POJ
- 【MyBatis学习05】SqlMapConfig.xml文件中的配置总结
- CentOS 7.2 下使用yum命令安装MariaDB的记录