Как выбрать видео из галереи в новейшем API? - PullRequest
0 голосов
/ 06 ноября 2019

Я пытаюсь найти путь к видео в галерее, но 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 голосов
/ 07 ноября 2019

Используйте ниже разрешенный в файле манифеста, и если ваше устройство зефир и выше, то также дайте разрешение времени выполнения.

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

0 голосов
/ 06 ноября 2019

добавить ниже зависимости в build.gradle (App):

implementation 'com.droidninja:filepicker:2.2.0'

установить список щелчков виджетов и создать массив 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])
                    )
                }

передача surveyImagesParts в вызове API ... надеюсь, это поможет вам ...!

0 голосов
/ 06 ноября 2019

Сборка не является проблемой, вы получаете 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 FileDescriptor, который можно передать большинству операций ввода-вывода Java.

@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
                }
            }
        }
    }

0 голосов
/ 06 ноября 2019

Это позволит вам выбрать видео из галереи:

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

Читать это для получения дополнительной информации о intents и MediaStore.

...