0

I have an activity where the user can select an image/video from gallery. For images everything is working fine, however i'm struggling with videos. This is how i call to open the gallery in case of videos:

fun getVideoFromGallery() {
    if (Build.VERSION.SDK_INT < 19) {
        var intent = Intent()
        intent.type = "video/*"
        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
        intent.action = Intent.ACTION_GET_CONTENT
        startActivityForResult(
            Intent.createChooser(intent, "Select Picture")
            , GALLERY_VIDEO
        )
    } else {
        var videopicker = Intent(Intent.ACTION_OPEN_DOCUMENT);
        videopicker.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
        videopicker.addCategory(Intent.CATEGORY_OPENABLE)
        videopicker.type = "video/*"
        startActivityForResult(videopicker, GALLERY_VIDEO);
    }
}

I receive the notification when the user selected the video in:

public override fun onActivityResult(requestCode:Int, resultCode:Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)

if(requestCode == GALLERY_VIDEO)
{
    if (data != null)
    {
        val contentURI = data.data
        try {

            if (data.getData() != null) {

            var videoURI = data.getData()
                val cR = this@EnviarMultimediaActivity.getContentResolver();
                val type = cR.getType(videoURI);
                if(!type.isNullOrEmpty() && type.contains("video/", true)){

                    val videopath = videoURI.getPath()
                    val file = File(videopath)
                    Log.d(TAG, "Video uri: "+videoURI)
                    Log.d(TAG, "Video path: "+file.getAbsolutePath())

                    var videoCopy = File(Environment.getExternalStorageDirectory().absolutePath+ IMAGE_DIRECTORY + ((Calendar.getInstance().getTimeInMillis()).toString() + ".mp4"))
                    //file.copyTo(videoCopy, true)
                    copyVideoFile(file, videoCopy)

                    Glide
                        .with(this@EnviarMultimediaActivity)
                        .asBitmap()
                        .load(videoURI)
                        .into(object : CustomTarget<Bitmap>(){
                            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                                val thumbnail = saveImage(resource)
                                val thumbnailUri = Uri.parse(thumbnail);


                                val videoCopyURI = Uri.parse(videoCopy.getPath())

                                listaFicherosEnviar.add(EnviarMultimediaFichero(null, false, 3,  videoCopyURI, thumbnailUri))
                                adapterEnviarMultimediaImagen.swapData(listaFicherosEnviar)
                            }
                            override fun onLoadCleared(placeholder: Drawable?) {

                            }
                        })

                }
            }
        }
        catch (e: IOException) {
            e.printStackTrace()
            Toast.makeText(this@EnviarMultimediaActivity, "Failed!", Toast.LENGTH_SHORT).show()
        }
    }
}
}

My onActivityResult is bigger but i just pasted the relevant part for videos. If i don't try to make the copy Glide created the thumbnail and is displayed in the view. The problem is that the copy don't work, i tried the File method copyTo and also another method implemented that receive a copy source and copy destination as parameter.

private fun copyVideoFile(sourceFile: File, destFile: File){
        if (!sourceFile.exists()) {
            return;
        }


        val source = FileInputStream(sourceFile).getChannel();
        val destination = FileOutputStream(destFile).getChannel();
        if (destination != null && source != null) {
            destination.transferFrom(source, 0, source.size());
        }
        if (source != null) {
            source.close();
        }
        if (destination != null) {
            destination.close();
        }
    }

The problem is that sourceFile.exists() returns false, so no copy is done. I tried to lod path and uri and is this:

Video uri: content://com.android.providers.downloads.documents/document/36 Video path: /document/36

I'm a bit lost as i don't understand why if the uri is correct (as Glide works) i can't create a File and make a copy to another File.

I requested permission and in my manifest i have:

  • android.permission.WRITE_EXTERNAL_STORAGE
  • android.permission.CAMERA
  • android.permission.INTERNET
  • android.permission.READ_EXTERNAL_STORAGE

Later i have retrofit2 api that creates a post to the server where sends as multipart:

val requestBody: RequestBody = RequestBody.create(MediaType.parse("video/*"), file)
    val multiPart: MultipartBody.Part = MultipartBody.Part.createFormData("file", file.name, requestBody)
    val name = RequestBody.create(MediaType.parse("text/plain"), file.name);

This is why i need an instance of File. As said the copy is just a test, but the File instance i think is required (unless i have a different code in the retrofir2 api to add the file to the post request).

Any help is appreciated.

Miguel
  • 558
  • 6
  • 21
  • `val videopath = videoURI.getPath() val file = File(videopath)` This is nonsense as you will not get a path to a file in that way. Forget about the File class. Use data.getData() directly to open an InputStream on the obtained content scheme. InputStream is = getContentResolver().openInputStream(data.getData()); My question: Why do you wanna make a copy? – blackapps Oct 20 '19 at 19:01
  • `Video path: /document/36`. That is no file system path as you could have seen. – blackapps Oct 20 '19 at 19:06
  • Hi, i'm trying to send the video with Retrofit to a remote server and i need the File class. The idea of create a copy is just for testing. In my retrofit call y detected that is not being triggered as the File i was passing was not correct, so i started to think to create a copy just to investigate, if the copy is done then the retrofit call will work. My retrofit api receive a File parameter and i was sending the val file = File(videopath) but was not working. Updated original post with the retrofit2 api request. That is why i need the File instance. – Miguel Oct 21 '19 at 07:40

0 Answers0