简体   繁体   中英

uploading a video using retrofit in android where parameter is file

I have been following various tutorials and trying to upload video to my server using retrofit in android. The only parameters I need is as shown in figure below 在此处输入图片说明

I keep on get the timeout exception even though I have increased the timeout. This is my upload video code.

final OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .readTimeout(60, TimeUnit.SECONDS)
            .connectTimeout(60, TimeUnit.SECONDS)
            .build();
    Log.v("test_get", "get the file");
    //MultipartBody.Part vFile = MultipartBody.Part.createFormData("video", videoFile.getName(), videoBody);
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://xxxx:xxx/")
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build();

    SmileVideoAPI service = retrofit.create(SmileVideoAPI.class);
    MediaType MEDIA_TYPE = MediaType.parse("video/mp4");
    File videoFile = new File(pathToVideoFile);
    RequestBody videoBody = RequestBody.create(MEDIA_TYPE, videoFile);
    Log.v("test_get", "before uploading");
    Call<ResponseBody> call = service.uploadVideo("desc", videoBody);
    Log.v("test_get", "after uploading");
    call.enqueue(new Callback<ResponseBody>(){
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            if (response.isSuccessful())
            {
                Log.i("mok","S");
                ResponseBody rb = response.body();
                Log.i("mok",rb.toString());
            }
            else {
                Log.i("mok", "F");
                ResponseBody rb = response.errorBody();
            }
        }
        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            t.printStackTrace();
            Log.i("mok",t.getCause()+"");
            Log.i("mok","T");
            finish();
        } 
    });
    return msg;

    I have been trying taking reference from this post : 

upload video using Retrofit 2

If you wish to upload files (any type) here is a PHP approach for Android that works well.

You need a script on the server to receive files:

uploadfile.php

<?php
$fname = $_POST['filename'];
$target_path = "/yourserverpath/".$fname;
$upload_path = $_FILES['uploadedfile']['tmp_name'];
If (move_uploaded_file($upload_path, $target_path)) {
    echo "Moved";
} else {
    echo "Not Moved";
}
?>

You can test out your uploadfile.php script on the server with the following HTML tester file on the server from a browser:

Uploadfile.html:

<form enctype="multipart/form-data" action="uploader.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="100000" />
Choose a file to upload: 
<input name="uploadedfile" type="file" /><br />
Filename on server:
<input name="filename" type="text" /><br />
<br />
<input type="submit" value="Upload File" />
</form>

Once you get the server side working to upload files from the browser, then the Android part is pretty straightforward:

Uploader handles the uploading of files. This class calls the uploadfile.php script on the server.

Uploading files can be tricky, but we have a secret weapon that makes it much easier. We are going to use the DefaultHttpClient, which gives us access to MultipartEntity method. This method is not available when using HttpUrlConnection. The fileUpload class is placed in the AsyncTask. The selectedPicName in my example is simply your filename. The postURL is the full URL of the script mentioned earlier.

private class fileUpload extends AsyncTask<Void, String, Void> {
    protected Void doInBackground(Void... unused) {
        // upload new picture to the server        
        String postURL = uploadFilesScript;
        File file = new File(path2, selectedPicName);
        // upload the new picture
        Uploader(postURL, file, selectedPicName);
    } 
}

The Uploader class is as follows: (Important to note that "uploadedfile" name has to match the variable in the PHP script the receives uploads.)

public static void Uploader(String postURL, File file, String fname) {
    try {
        DefaultHttpClient httpclient = new DefaultHttpClient();
        httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, 
                                            HttpVersion.HTTP_1_1);
        HttpPost httppost = new HttpPost(postURL);
        // the boundary key below is arbitrary,
        // it just needs to match the MPE so it can decode multipart correctly
        httppost.setHeader("Content-Type", "multipart/form-data; boundary=--32530126183148");
        MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,
                                                       "--32530126183148", 
                                                       Charset.forName("UTF-8"));
            mpEntity.addPart("uploadedfile", new FileBody((file), "application/txt"));
            mpEntity.addPart("MAX_FILE_SIZE", new StringBody("100000"));
            mpEntity.addPart("filename", new StringBody(fname));
        }
        httppost.setEntity(mpEntity);
        HttpResponse response;
        response = httpclient.execute(httppost);
        HttpEntity resEntity = response.getEntity();
          if (resEntity != null) {
                resEntity.consumeContent();
                Log.v("UPLOAD", "resEntity=" + resEntity.toString());
            }
        httpclient.getConnectionManager().shutdown();
    } catch (Throwable e) {
    }
}

MultipartEntity allows us to simply specify the file name and the file contents using the addPart method. In the example below, the variable names match with those expected by the receiving PHP script on the server.

If we had to accomplish this uploading functionality using the HttpUrlConnection class, it would be complicated, as we would have to create our own file handling wrapper. MultipartEntity also allows us to specify character set and maximum file size. A unique, but arbitrary, boundary string needs to be provided which must match the server script.

I have been using this approach in my production apps and it works really well.

Full disclosure- I wrote a book called Android Software Developement: A Collection of Practical Projects and uploading is covered in a Server Spinner App in Chapter 5, but this should be all you need to upload videos.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM