【问题标题】:Share Intent does not work for uploading video to youtube共享意图不适用于将视频上传到 youtube
【发布时间】:2013-09-07 08:26:20
【问题描述】:

我正在尝试分享一个正在创建并存储在外部 sdcard 上的视频,该视频的路径已被获取。

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

我使用 SEND_INTENT 如下:

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

问题: 当我通过 gmail 分享时,它会显示带有视频的撰写窗口。但是没有显示视频的大小,当您发送或取消窗口时,gmail 将在 contentresolver 上使用 inputstream NPE 崩溃。

如果是 youtube,它说您无法从云服务上传视频,我的视频显然驻留在设备上。

如果是 facebook,它会被默默地丢弃。这适用于 wassup。 :-)

任何想法如何让它工作?

编辑:

视频路径: /storage/emulated/0/Movies/MyFolder/my-video_1378253389208.mp4

更新

通过添加file:/// 后缀,gmail 和 facebook 可以正常工作。 Youtube 还在讥讽“无法从云服务上传视频”。

【问题讨论】:

  • 我怀疑video_pathform 不正确。您可以记录它(对于任何视频文件)并将其作为评论发布吗?
  • path 在我看来是正确的,因为它与 wassup 一起使用。在上面的问题中添加。
  • 尝试在video_path 前加上"file://"。或者只是为了测试目的对路径进行硬编码:String video_path = "file:///storage/emulated/0/Movies/MyFolder/my-video_1378253389208.mp4";
  • 您的解决方案使其适用于 gmail 和 facebook。只有 youtube 待定。谢谢!
  • 我刚试过你的代码。 Youtube 确实出现在选择器中。您可以尝试另一件事:创建文件 ==> File video_file = new File("/storage/emulated/0/Movies/MyFolder/my-video_1378253389208.mp4");。并使用Uri.fromFile(video_file) 而不是Uri.parse(String)

标签: android facebook video android-intent youtube


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      Gmail 没有这样的问题,它发送并从电子邮件中检索后即可播放。

      【讨论】:

        【解决方案4】:

        你可以试试这个代码。

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

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

          【解决方案6】:

          除了 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://

          【讨论】:

            【解决方案7】:

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

            【讨论】:

            • 完美运行。解决 Youtube 问题的最佳解决方案
            • 这甚至解决了 gmail 问题.. 在 android 11 及更低版本上工作!
            猜你喜欢
            • 2017-04-15
            • 2013-04-27
            • 2014-10-13
            • 1970-01-01
            • 1970-01-01
            • 2015-02-15
            • 1970-01-01
            • 1970-01-01
            • 2012-01-12
            相关资源
            最近更新 更多