Android: Get video from Gallery uri

4.7k views Asked by At

I'm trying to get a video from the Android Gallery and get the full path, so I can upload the video in an app...

I'm displaying the gallery like this:

Intent intent = new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
activity.startActivityForResult(Intent.createChooser(intent, context.getResources().getString(R.string.popup_menu_share_video_title)), Const.PICK_VIDEO_REQUEST);

I then extract the uri:

Uri selectedUri = data.getData();
String selectedPath = getRealPathFromURI(this, selectedUri);

And attempt to get the path:

public String getRealPathFromURI(Context context, Uri contentUri) {
    Cursor cursor = null;
    try {
        String[] proj = { MediaStore.Video.Media.DATA };
        cursor = context.getContentResolver().query(contentUri,  proj, null, null, null);
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}

But I can't seem the get the path...

I can see all the videos if I do this:

public static void dumpVideos(Context context ) {
    Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
    String[] projection = { MediaStore.Video.Media.DATA };
    Cursor c = context.getContentResolver().query(uri, projection, null, null, null);
    int vidsCount = 0;
    if (c != null) {
        vidsCount = c.getCount();
        while (c.moveToNext()) {
            Log.d("VIDEO", c.getString(0));
        }
        c.close();
    }
    Log.d("VIDEO", "Total count of videos: " + vidsCount);
}

So I'm thinking there must be some real simple step, that I'm missing...

2

There are 2 answers

2
CommonsWare On

I'm trying to get a video from the Android Gallery

First, there is no "Android Gallery". There are many apps that might be considered "gallery" apps. There are thousands of device models, and they will ship with a wide variety of "gallery" apps, in addition to those that the user installs.

Second, ACTION_GET_CONTENT is not somehow magically limited to "gallery" apps. Any app can elect to support ACTION_GET_CONTENT for video/*.

and get the full path

That is impossible. You have no way of knowing what app the user chooses to handle your ACTION_GET_CONTENT request. You have no way of knowing what sort of Uri you will get back. You have no way of knowing where the content identified by that Uri will be stored, as it does not have to be a file on the filesystem that you can access.

so I can upload the video in an app

Use openInputStream() on ContentResolver to get an InputStream on the content identified by the Uri. Then, either:

  • Use that stream directly with your preferred HTTP client API to upload the content, or

  • Use that stream to make a local file copy of the content, then use that file with your preferred HTTP client

And attempt to get the path:

At best, that code will work in very limited circumstances:

  • The app that the user chooses to handle your ACTION_GET_CONTENT request happens to return a content Uri from the MediaStore

  • That content happens to be on external storage, not removable storage

Since that will not cover all of your scenarios, get rid of that code.

I can see all the videos if I do this

No, you can get paths for some videos:

  • Not every video accessible via ACTION_GET_CONTENT will be known to the MediaStore

  • Not every video in the MediaStore will be on external storage, where you might be able to access it via filesystem APIs

0
HannahCarney On

you can solve this issue by using ACTION_PICK instead of ACTION_GET_CONTENT. I believe unless you need the functionality of adding pictures/videos from Dropbox etc. it's not worth it.If all you need is to get stuff from the gallery use this code:

 if (Build.VERSION.SDK_INT < 19) {
           final Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
           photoPickerIntent.setType("image/* video/*");
           startActivityForResult(photoPickerIntent, PICK_PHOTO_ACTIVITY_REQUEST_CODE);
 } else {
           final Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
           photoPickerIntent.setType("*/*");
           photoPickerIntent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"image/*", "video/*"});
           startActivityForResult(photoPickerIntent, PICK_PHOTO_ACTIVITY_REQUEST_CODE);
 }

I just tried the code you posted with ACTION_PICK and it works perfectly!