zoukankan      html  css  js  c++  java
  • Android使用OKHttp库实现视频文件的上传到服务器

    目录

    1 服务器接口简介

    2 Android端代码实现

    2.1 xml布局文件

    2.2 Activity类

    2.3 Okhttp网络通信类


    1 服务器接口简介

    此处我使用的服务器接口是使用Flask编写,具体实现代码:

     

    # -*- coding: utf-8 -*-
    from flask import Flask, render_template, jsonify, request
    import time
    import os
    import base64
    
    app = Flask(__name__)
    UPLOAD_FOLDER = 'E:myuploadpicture'
    app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
    basedir = os.path.abspath(os.path.dirname(__file__))
    ALLOWED_EXTENSIONS = set(['txt', 'png', 'jpg', 'xls', 'JPG', 'PNG', 'xlsx', 'gif', 'GIF','mp4'])
    
    
    # 用于判断文件后缀
    def allowed_file(filename):
        return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
    
    
    # 上传文件
    @app.route('/api/upload', methods=['POST'], strict_slashes=False)
    def api_upload():
        file_dir = os.path.join(basedir, app.config['UPLOAD_FOLDER'])
        if not os.path.exists(file_dir):
            os.makedirs(file_dir)
        f = request.files['myfile']  # 从表单的file字段获取文件,myfile为该表单的name值
        if f and allowed_file(f.filename):  # 判断是否是允许上传的文件类型
            fname = f.filename
            print fname
            ext = fname.rsplit('.', 1)[1]  # 获取文件后缀
            unix_time = int(time.time())
            new_filename = str(unix_time) + '.' + ext  # 修改了上传的文件名
            f.save(os.path.join(file_dir, new_filename))  # 保存文件到upload目录
            print new_filename
            token = base64.b64encode(new_filename)
            print token
    
            return jsonify({"errno": 0, "errmsg": "上传成功", "token": token})
        else:
            return jsonify({"errno": 1001, "errmsg": "上传失败"})
    
    
    if __name__ == '__main__':
        app.run(debug=True)

    参考文章:https://www.cnblogs.com/mosson/p/6163233.html

     附加使用PostMan测试上传文件的操作方法:http://blog.csdn.net/u013420865/article/details/69665180


    2 Android端代码实现

    代码分三部分:

    分别是xml布局文件,Activity类,和Okhttp网络通信类。

    2.1 xml布局文件

    activity_video_upload.xml:
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_height="60dp"
            android:layout_marginTop="80dp"
            android:orientation="horizontal">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:layout_gravity="center_vertical"
                android:gravity="center"
                android:text="视频名称:"
                android:textColor="@color/black2"
                android:textSize="18dp"/>
    
            <EditText
                android:id="@+id/upload_video_name"
                android:layout_width="280dp"
                android:layout_height="50dp"
                android:layout_gravity="center_vertical"
                android:hint="请输入上传视频名称"
                android:layout_marginLeft="5dp"
                android:textSize="18dp"
               />
    
    
        </LinearLayout>
    
        <Button
            android:id="@+id/video_select"
            android:layout_width="match_parent"
            android:layout_height="44dp"
            android:layout_marginLeft="100dp"
            android:layout_marginRight="100dp"
            android:layout_marginTop="80dp"
            android:background="@drawable/exit_btn_blue"
            android:text="选择视频"
            android:textStyle="bold"
            android:textColor="@android:color/white"
            android:textSize="20sp"/>
    
        <Button
            android:id="@+id/video_upload"
            android:layout_width="match_parent"
            android:layout_height="44dp"
            android:layout_marginLeft="100dp"
            android:layout_marginRight="100dp"
            android:layout_marginTop="40dp"
            android:background="@drawable/exit_btn_blue"
            android:text="点击上传"
            android:textStyle="bold"
            android:textColor="@android:color/white"
            android:textSize="20sp"/>
    
        <TextView
            android:id="@+id/post_text"
            android:layout_marginTop="40dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="0" />
    
        <ProgressBar
            android:id="@+id/post_progress"
    
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:max="100" />
    
    </LinearLayout>

    2.2 Activity类

    VideoUploadActivity类:

    package com.liu.dance.video;
    
    import android.app.Activity;
    import android.content.ContentResolver;
    import android.content.Context;
    import android.content.Intent;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Environment;
    import android.provider.MediaStore;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import com.liu.dance.R;
    import com.liu.dance.util.HttpUtil;
    import com.liu.dance.util.ProgressListener;
    
    import java.io.File;
    import java.net.URI;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import okhttp3.Call;
    import okhttp3.Callback;
    import okhttp3.Response;
    
    public class VideoUploadActivity extends AppCompatActivity {
        public static final String TAG = VideoUploadActivity.class.getName();
        public  final static int VEDIO_KU = 101;
        private String path = "";//文件路径
        private ProgressBar post_progress;
        private TextView post_text;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_video_upload);
            getSupportActionBar().setTitle("视频上传");
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            final EditText video_name = (EditText)findViewById(R.id.upload_video_name);
            post_progress = (ProgressBar) findViewById(R.id.post_progress);
            post_text = (TextView) findViewById(R.id.post_text);
            findViewById(R.id.video_select).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    seleteVedio();
                    video_name.setText(path);
                }
            });
            findViewById(R.id.video_upload).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    //                Toast.makeText(VideoUploadActivity.this, "路径:"+basePath, Toast.LENGTH_LONG).show();
                    if(path.equals(""))
                        Toast.makeText(VideoUploadActivity.this, "请选择视频后,再点击上传!", Toast.LENGTH_LONG).show();
                    else {
                        File file = new File( path);
                        String postUrl = "http://120.79.82.151/api/upload";
    
                        HttpUtil.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);
    
                    }
    
                }
            });
    
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case android.R.id.home:
                    finish();
                    break;
                default:
                    break;
            }
            return super.onOptionsItemSelected(item);
        }
    
        public void seleteVedio() {
            // TODO 启动相册
            Intent intent = new Intent();
            intent.setType("video/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            startActivityForResult(intent,VideoUploadActivity.VEDIO_KU);
        }
    
        /**
         * 选择回调
         */
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            switch (requestCode) {
                // TODO 视频
                case VideoUploadActivity.VEDIO_KU:
                    if (resultCode == Activity.RESULT_OK) {
                        try {
                            Uri uri = data.getData();
                            uri = geturi(this, data);
                            File file = null;
                            if (uri.toString().indexOf("file") == 0) {
                                file = new File(new URI(uri.toString()));
                                path = file.getPath();
                            } else {
                                path = getPath(uri);
                                file = new File(path);
                            }
                            if (!file.exists()) {
                                break;
                            }
                            if (file.length() > 100 * 1024 * 1024) {
    //                            "文件大于100M";
                                break;
                            }
                            //视频播放
    //                        mVideoView.setVideoURI(uri);
    //                        mVideoView.start();
                            //开始上传视频,
    //                        submitVedio();
                        } catch (Exception e) {
                            String  a=e+"";
                        } catch (OutOfMemoryError e) {
                            String  a=e+"";
                        }
                    }
                    break;
            }
    
        }
    
        public static Uri geturi(Context context, android.content.Intent intent) {
            Uri uri = intent.getData();
            String type = intent.getType();
            if (uri.getScheme().equals("file") && (type.contains("image/"))) {
                String path = uri.getEncodedPath();
                if (path != null) {
                    path = Uri.decode(path);
                    ContentResolver cr = context.getContentResolver();
                    StringBuffer buff = new StringBuffer();
                    buff.append("(").append(MediaStore.Images.ImageColumns.DATA).append("=")
                            .append("'" + path + "'").append(")");
                    Cursor cur = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                            new String[] { MediaStore.Images.ImageColumns._ID },
                            buff.toString(), null, null);
                    int index = 0;
                    for (cur.moveToFirst(); !cur.isAfterLast(); cur.moveToNext()) {
                        index = cur.getColumnIndex(MediaStore.Images.ImageColumns._ID);
                        // set _id value
                        index = cur.getInt(index);
                    }
                    if (index == 0) {
                        // do nothing
                    } else {
                        Uri uri_temp = Uri
                                .parse("content://media/external/images/media/"
                                        + index);
                        if (uri_temp != null) {
                            uri = uri_temp;
                            Log.i("urishi", uri.toString());
                        }
                    }
                }
            }
            return uri;
        }
    
        private String getPath(Uri uri) {
            String[] projection = {MediaStore.Video.Media.DATA};
            Cursor cursor = managedQuery(uri, projection, null, null, null);
            int column_index = cursor
                    .getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        }
    }

    2.3 Okhttp网络通信类

    HttpUtil类:
    package com.liu.dance.util;
    
    import android.util.Log;
    
    import java.io.File;
    import java.util.concurrent.TimeUnit;
    
    import okhttp3.MediaType;
    import okhttp3.MultipartBody;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.RequestBody;
    
    /**
     * Created by 舞动的心 on 2018/3/5.
     */
    
    public class HttpUtil {
        private static OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(10000, TimeUnit.MILLISECONDS)
                .readTimeout(10000,TimeUnit.MILLISECONDS)
                .writeTimeout(10000, TimeUnit.MILLISECONDS).build();
        public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8");public static void postFile(String url,  final ProgressListener listener, okhttp3.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("myfile",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);
        }
    
    
    }
     ProgressListener接口:
    package com.liu.dance.util;
    
    /**
     * Created by 舞动的心 on 2018/3/8.
     */
    
    public interface ProgressListener {
        void onProgress(long currentBytes, long contentLength, boolean done);
    }
    ProgressModel类:
    package com.liu.dance.util;
    
    import android.os.Parcel;
    import android.os.Parcelable;
    
    /**
     * Created by 舞动的心 on 2018/3/8.
     */
    
    public class ProgressModel implements Parcelable {
    
        private long currentBytes;
        private long contentLength;
        private boolean done = false;
    
        public ProgressModel(long currentBytes, long contentLength, boolean done) {
            this.currentBytes = currentBytes;
            this.contentLength = contentLength;
            this.done = done;
        }
    
        public long getCurrentBytes() {
            return currentBytes;
        }
    
        public void setCurrentBytes(long currentBytes) {
            this.currentBytes = currentBytes;
        }
    
        public long getContentLength() {
            return contentLength;
        }
    
        public void setContentLength(long contentLength) {
            this.contentLength = contentLength;
        }
    
        public boolean isDone() {
            return done;
        }
    
        public void setDone(boolean done) {
            this.done = done;
        }
    
        private static final Creator<ProgressModel> CREATOR = new Creator<ProgressModel>() {
            @Override
            public ProgressModel createFromParcel(Parcel parcel) {
                return new ProgressModel(parcel);
            }
    
            @Override
            public ProgressModel[] newArray(int i) {
                return new ProgressModel[i];
            }
        };
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel parcel, int i) {
            parcel.writeLong(currentBytes);
            parcel.writeLong(contentLength);
            parcel.writeByte((byte) (done==true?1:0));
        }
    
        protected ProgressModel(Parcel parcel) {
            currentBytes = parcel.readLong();
            contentLength = parcel.readLong();
            done = parcel.readByte()!=0;
        }
    }
     ProgressRequestBody类:

    package com.liu.dance.util;
    
    import android.os.Handler;
    import android.os.Looper;
    import android.os.Message;
    
    import java.io.IOException;
    
    import okhttp3.MediaType;
    import okhttp3.RequestBody;
    import okio.Buffer;
    import okio.BufferedSink;
    import okio.ForwardingSink;
    import okio.Okio;
    import okio.Sink;
    
    /**
     * Created by 舞动的心 on 2018/3/8.
     */
    
    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);
                }
            };
        }
    
    
    }

    界面效果:

    参考文章:http://blog.csdn.net/gary__123456/article/details/74157403

  • 相关阅读:
    通过SSIS监控远程服务器Windows服务并发送邮件报警!
    通过SSIS监控远程服务器磁盘空间并发送邮件报警!
    Jquery和雅虎的YQL服务实现天气预报功能!
    表字段或表名出现Mysql关键字或保留字导致问题 Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have
    Mybatis对象关系映射 one2one,one2many,many2many
    事务的传播属性及隔离级别 Spring
    正整数的二进制表示中1的个数计算(使用移位或者n&(n-1))
    char类型及ASCII码之间比较
    数据表记录包含表索引和数值(int范围的整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出
    写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。(多组同时输入 )
  • 原文地址:https://www.cnblogs.com/liuzhen1995/p/8526972.html
Copyright © 2011-2022 走看看