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
原创粉丝点击