PravinCG
PravinCG

Reputation: 7708

Share Intent does not work for uploading video to youtube

I am trying to share a video that is being created and stored on external sdcard whose path has been obtained by.

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath()

I am using SEND_INTENT as follows:

Intent shareIntent = new Intent(Intent.ACTION_SEND);                         
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
shareIntent.setType("video/mp4");
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "My Subject");
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT,"My Text");
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(video_path));
startActivityForResult(Intent.createChooser(shareIntent, "Share Your Video"),SHARE_INTENT);

Problem: While I share through gmail, it shows me compose window with video attached. But no size being shown of the video and when you either send or cancel the window, gmail will crash with inputstream NPE on contentresolver.

In case of youtube, it says you cannot upload videos from cloud service, my video clearly resides on the device.

In case of facebook, it is silently discarded. This works fine with wassup. :-)

Any ideas how to get this to work?

EDIT:

Video Path: /storage/emulated/0/Movies/MyFolder/my-video_1378253389208.mp4

UPDATE

By adding file:/// suffix, gmail and facebook works fine. Youtube is still cribbing about "Videos cannot be uploaded from cloud services".

Upvotes: 3

Views: 7194

Answers (7)

Abhishek Kumar
Abhishek Kumar

Reputation: 4808

Here is the working solution for sharing videos, (code is in kotlin)

startActivity(
        Intent.createChooser(
            Intent().setAction(Intent.ACTION_SEND)
                .setType("video/*")
                .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                .putExtra(
                    Intent.EXTRA_STREAM,
                    getVideoContentUri(this, File(currentVideo.videoPath))
                ), resources.getString(R.string.share_video)
        )
    )

don't forget to add the following method,

/**
     * Return the URI for a file. This URI is used for
     * sharing of video.
     * NOTE: You cannot share a file by file path.
     *
     * @param context Context
     * @param videoFile File
     * @return Uri?
     */
    fun getVideoContentUri(context: Context, videoFile: File): Uri? {
        var uri: Uri? = null
        val filePath = videoFile.absolutePath
        val cursor = context.contentResolver.query(
            MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
            arrayOf(MediaStore.Video.Media._ID),
            MediaStore.Video.Media.DATA + "=? ",
            arrayOf(filePath), null)

        if (cursor != null && cursor.moveToFirst()) {
            val id = cursor.getInt(cursor
                .getColumnIndex(MediaStore.MediaColumns._ID))
            val baseUri = Uri.parse("content://media/external/video/media")
            uri = Uri.withAppendedPath(baseUri, "" + id)
        } else if (videoFile.exists()) {
            val values = ContentValues()
            values.put(MediaStore.Video.Media.DATA, filePath)
            uri = context.contentResolver.insert(
                MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values)
        }

        closeCursor(cursor)
        return uri
    }

Happy Codng :)

Upvotes: 0

Muhammad Hassaan
Muhammad Hassaan

Reputation: 1017

The best and easy method method to Share video on youtube, Use Provider to get Video Uri in Devices with Api >=24

 private void VideoShareOnYoutube(String videoPath) {
        try {
           String csYoutubePackage = "com.google.android.youtube";
            Intent intent = getPackageManager().getLaunchIntentForPackage(csYoutubePackage);

            if (intent != null && !videoPath.isEmpty()) {

                Intent share = new Intent(Intent.ACTION_SEND);
                share.setPackage(csYoutubePackage);
                Uri contentUri;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    contentUri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".my.package.name.provider",  new File(videoPath));

                }
                else
                {
                    contentUri = Uri.fromFile(new File(videoPath));

                }
                share.setType("video/*");
                share.putExtra(Intent.EXTRA_STREAM, contentUri);

                startActivity(share);

            } else {
                Common.showToast("Youtube app not installed!", activty);
            }
        } catch (Exception e) {
            Log.e(TAG, "Youtubeexeption() :" + e.getMessage());
        }
    }

Upvotes: 2

WallyHale
WallyHale

Reputation: 408

Just a heads up as this caught me out when trying to share a video to Facebook via Intent Chooser that worked fine with Gmail and a few other Intents - If there are spaces or other characters that get encoded to %20 for space for example, Facebook won't find the video if you try to play it.

I was using Video - 27 Apr 2016 - 16:59 pm.mp4 for instance, and spaces and colons were replaced, breaking the link inside Facebook. A thumbnail of the video would show when composing the share in Facebook, so I thought it was OK, but if you clicked to play it, it would say the file could not be found / played.

No such problem with Gmail, it sent and was playable once retrieved from email.

Upvotes: 0

with this code you can try.

 public void makeVideo(String nameVideo){
    String type = "video/*";
   // /storage/emulated/0/nameVideo.mp4
   // if you have other path is necessary you change the path

    String mediaPath = Environment.getExternalStorageDirectory() + File.separator + nameVideo;

    createIntent(type, mediaPath);
}

private void createIntent(String type, String mediaPath) {

    // Create the new Intent using the 'Send' action.
    Intent share = new Intent(Intent.ACTION_SEND);

    // Set the MIME type
    share.setType(type);

    // Create the URI from the media
    File media = new File(mediaPath);
    Uri uri = Uri.fromFile(media);

    // Add the URI to the Intent.
    share.putExtra(Intent.EXTRA_STREAM, uri);

    // Broadcast the Intent.
    startActivity(Intent.createChooser(share, "Share to"));
}

more information https://instagram.com/developer/mobile-sharing/android-intents/

Upvotes: 0

Hem Shrestha
Hem Shrestha

Reputation: 479

Based on Johan vdH's answer, the following code works on many sharing apps including Youtube, Facebook, WhatsApp and so on.

Path should be absolute path of video file. for eg. "/mnt/sdcard/DCIM/foo/vid_20131001_123738.3gp"

public void shareVideo(final String title, String path) {
        MediaScannerConnection.scanFile(getActivity(), new String[] { path },
                null, new MediaScannerConnection.OnScanCompletedListener() {
                    public void onScanCompleted(String path, Uri uri) {
                        Intent shareIntent = new Intent(
                                android.content.Intent.ACTION_SEND);
                        shareIntent.setType("video/*");
                        shareIntent.putExtra(
                                android.content.Intent.EXTRA_SUBJECT, title);
                        shareIntent.putExtra(
                                android.content.Intent.EXTRA_TITLE, title);
                        shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
                        shareIntent
                                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                        context.startActivity(Intent.createChooser(shareIntent,
                                getString(R.string.str_share_this_video)));

                    }
                });
    }

Upvotes: 3

repkap11
repkap11

Reputation: 787

In addition to Johan vdH's answer, the Uri used in

shareIntent.putExtra(Intent.EXTRA_STREAM, uri);

Must be the one obtained from

public void onScanCompleted(String path, Uri uri)

Getting the Uri by

Uri  uri = Uri.fromFile(new File(video_path));

Will not work. Youtube seems to like content:// but not file://

Upvotes: 1

Johan vdH
Johan vdH

Reputation: 394

The reason Youtube fails and others work is because it checks to see if it is a media file. It only thinks it is a media file if it has been scanned. Run the code below and it should work. It will also show up in the gallery. How to upload a temp file I do not know.

void publishScan() {

    //mVidFnam: "/mnt/sdcard/DCIM/foo/vid_20131001_123738.3gp" (or such)
    MediaScannerConnection.scanFile(this, new String[] { mVidFnam }, null,
            new MediaScannerConnection.OnScanCompletedListener() {
                public void onScanCompleted(String path, Uri uri) {
                    Log.d(TAG, "onScanCompleted uri " + uri);


                }
            });
}

Upvotes: 7

Related Questions