3

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".

4

7 回答 7

6

Youtube 失败而其他人工作的原因是因为它检查它是否是媒体文件。如果它已经被扫描,它只会认为它是一个媒体文件。运行下面的代码,它应该可以工作。它也将出现在画廊中。如何上传临时文件我不知道。

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);


                }
            });
}
于 2013-10-01T23:18:59.060 回答
3

根据 Johan vdH 的回答,以下代码适用于许多共享应用程序,包括 Youtube、Facebook、WhatsApp 等。

路径应该是视频文件的绝对路径。例如。“/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)));

                    }
                });
    }
于 2015-02-13T05:43:42.873 回答
1

除了 Johan vdH 的回答之外,Uri 中使用的

shareIntent.putExtra(Intent.EXTRA_STREAM, uri);

必须是从

public void onScanCompleted(String path, Uri uri)

获取 Uri

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

不管用。Youtube 似乎喜欢 content:// 但不喜欢 file://

于 2014-06-10T18:44:32.903 回答
1

在 youtube 上共享视频的最佳且简单的方法,使用 Provider 在 Api >=24 的设备中获取 Video Uri

 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());
        }
    }
于 2018-09-03T06:52:29.940 回答
0

只是提醒一下,因为当我尝试通过 Intent Chooser 将视频分享到 Facebook 时,这让我意识到了这一点,该视频与 Gmail 和其他一些 Intent 配合得很好——例如,如果有空格或其他字符被编码为 %20 作为空格,Facebook如果您尝试播放视频,将找不到该视频。

例如,我使用的是Video - 2016 年 4 月 27 日 - 16:59 pm.mp4,并且替换了空格和冒号,从而破坏了 Facebook 内部的链接。在 Facebook 中撰写分享时会显示视频的缩略图,所以我认为没问题,但如果您单击播放它,它会说找不到/播放文件。

Gmail 没有这样的问题,一旦从电子邮件中检索到,它就会发送并可以播放。

于 2016-04-27T16:03:09.470 回答
0

这是共享视频的工作解决方案,(代码在 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)
        )
    )

不要忘记添加以下方法,

/**
     * 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
    }

快乐的 Codng :)

于 2020-08-26T14:59:22.880 回答
0

使用此代码,您可以尝试。

 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);
}

私人无效createIntent(字符串类型,字符串媒体路径){

    // 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"));
}

更多信息https://instagram.com/developer/mobile-sharing/android-intents/

于 2015-11-27T21:12:55.367 回答