如何使用最新的API从图库中挑选视频?

时间:2019-11-06 08:33:55

标签: android video gallery pick

我正在尝试获取图库中视频的路径,但是URI给了我类似“ / document / video:xxxx”的信息。当我使用getPath()时,我总是为空。

我已经设置了FileProvider并授予了所有权限,但是没有任何作用。

    //Start intent

    Intent intent = new Intent();
    intent.setType("video/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent,"Select Video"), 1);

    //Turn URI to Path

    String getPath(Uri uri) {

    String[] projection = { MediaStore.Video.Media.DATA };
    Cursor cursor = getContentResolver().query(uri, projection, null, null, null);

    if (cursor != null) {
        // HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL. THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } else {
        return null;
    }

    }

4 个答案:

答案 0 :(得分:0)

这将允许您从图库中选择视频:

 Intent intent = new Intent(Intent.ACTION_PICK,   MediaStore.Video.Media.EXTERNAL_CONTENT_URI);

阅读this,以获取有关intentsMediaStore的更多信息。

答案 1 :(得分:0)

在build.gradle(App)中添加以下依赖项:

implementation 'com.droidninja:filepicker:2.2.0'

设置小部件clicklistener并创建File的数组imgbase64:

private var imageBase64 = ArrayList<File>()

imgVideo.setOnClickListener {
            val intent1 = Intent(this, VideoPickActivity::class.java)
            intent1.putExtra(ImagePickActivity.IS_NEED_CAMERA, false)
            intent1.putExtra(Constant.MAX_NUMBER, 1)
            intent1.putExtra(BaseActivity.IS_NEED_FOLDER_LIST, false)
            startActivityForResult(intent1, Constant.REQUEST_CODE_PICK_VIDEO)
        }

ovverride onActivityResult(),

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (data != null) {
            try {
                imageBase64.clear()
                when (requestCode) {
                    AppConstants.REQUEST_CODE_PICK_VIDEO -> {
                        if (resultCode == Activity.RESULT_OK && data != null) {
                            val list = data.getParcelableArrayListExtra<VideoFile>(AppConstants.RESULT_PICK_VIDEO)
                            for (item in list) {
                                imageBase64.add(File(item.path))
                                FILE_TYPE = 2
                            }
                        }
                    }
                }

            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

创建多部分的surveyImagesParts数组,

val surveyImagesParts: Array<MultipartBody.Part?> = arrayOfNulls(imageBase64.size)
                for (index in imageBase64.indices) {
                    surveyImagesParts[index] = MultipartBody.Part.createFormData(
                        "message", imageBase64[index].name,
                        RequestBody.create(MediaType.parse("*/*"), imageBase64[index])
                    )
                }

在API调用中通过SurveyImagesParts ... 希望对您有帮助...!

答案 2 :(得分:0)

选择部分不是问题,您将获得一个URI。问题是默认情况下,路径无意义,因为您将无法访问它。

MediaStore.Video.Media.DATA

  

此常量在API级别29中已弃用。   应用程序可能没有文件系统权限来直接访问此路径。应用程序不应尝试直接打开此路径,而应使用ContentResolver#openFileDescriptor(Uri,String)获得访问权限。

请参阅 https://developer.android.com/reference/android/provider/MediaStore.MediaColumns.html#DATA

即使您能够获取路径,默认情况下您也没有使用它的权限,您需要使用ContentResolver#openFileDescriptor(Uri, String)来获得访问权限。

https://developer.android.com/reference/android/content/ContentResolver#openFileDescriptor(android.net.Uri,%20java.lang.String)

我建议您阅读https://developer.android.com/training/data-storage/files/external-scoped以使用最新的API进行存储

已更新:添加了有关如何处理Intent调用结果并获取可传递给大多数Java IO操作的Java FileDescriptor的示例。

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent resultData) {
        super.onActivityResult(requestCode, resultCode, resultData);

        Uri uri = null;

        // The `requestCode` was `1` in the code in the question
        if (requestCode == 1 && resultCode == RESULT_OK) {
            if (resultData != null) {
                uri = resultData.getData();
                try {
                    // Open for Read
                    ParcelFileDescriptor pfd =
                            this.getContentResolver().
                                    openFileDescriptor(uri, "r");

                    FileDescriptor fileDescriptor = pfd.getFileDescriptor();

                    // Now do something fileDescriptor like read the input Stream
                    FileInputStream fileInputStream =
                            new FileInputStream(
                                    fileDescriptor);

                    ....


                } catch (Exception e) {
                    // Do something with Exceptions
                }
            }
        }
    }

答案 3 :(得分:0)

在清单文件中使用以下权限,如果您的设备是棉花糖,则在运行时允许。

         <uses-permission  android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>