INTENT.ACTION_VIDEO_CAPTURE未将文件保存到自定义位置Uri

4

我创建了一个类似这样的应用程序。它有一个按钮,点击按钮会开始视频捕获。

现在我有一个像这样的代码:

public class VideoCaptureComponentActivity extends Activity implements View.OnClickListener {
    VideoView vv;
    ImageButton ib;
    TextView tv;
    Intent i;
    final static int cameraData=0;
    File path = null;
    Uri myVideo;

    private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
    private Uri fileUri;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main);

        vv= (VideoView) findViewById(R.id.vvVideoCapture);
        ib=(ImageButton) findViewById(R.id.btnVideo);
        ib.setOnClickListener(this);
        tv= (TextView) findViewById(R.id.tvFilePath);
    }

    @Override
    public void onClick(View v) {               
        switch(v.getId())
        {
            case R.id.btnVideo:
                Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
                fileUri = getOutputMediaFileUri();  // create a file to save the video
                intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);  // set the image file name
                intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); // set the video image quality to high

                // start the Video Capture Intent
                startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
                break;
        }

    }

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
     if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) 
     {
            if (resultCode == RESULT_OK) 
            {
                myVideo= data.getData();
                tv.setText(myVideo.toString());
                vv.setVideoURI(myVideo);
                vv.setMediaController(new MediaController(this));
                vv.requestFocus();
                vv.start(); 
            }           
    }
}


/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri()
{
      return Uri.fromFile(getOutputMediaFile());
}

/** Create a File for saving an image or video */
private static File getOutputMediaFile()
{
    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
              Environment.DIRECTORY_PICTURES), "MyCameraApp");

    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            Log.d("MyCameraApp", "failed to create directory");
            return null;
        }
    }
    File mediaFile;
    mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "VID_CAPTURED" + ".mp4");
   return mediaFile;
}


}

现在我捕获视频后,应用程序崩溃了。

07-06 17:12:09.447: E/AndroidRuntime(2917): FATAL EXCEPTION: main
07-06 17:12:09.447: E/AndroidRuntime(2917): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=200, result=-1, data=Intent {  }} to activity {com.optimus.mobile.survey/com.optimus.mobile.survey.VideoCaptureComponentActivity}: java.lang.NullPointerException
07-06 17:12:09.447: E/AndroidRuntime(2917):     at android.app.ActivityThread.deliverResults(ActivityThread.java:3712)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:3754)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at android.app.ActivityThread.access$2800(ActivityThread.java:135)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2162)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at android.os.Looper.loop(Looper.java:143)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at android.app.ActivityThread.main(ActivityThread.java:4914)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at java.lang.reflect.Method.invokeNative(Native Method)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at java.lang.reflect.Method.invoke(Method.java:521)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at dalvik.system.NativeStart.main(Native Method)
07-06 17:12:09.447: E/AndroidRuntime(2917): Caused by: java.lang.NullPointerException
07-06 17:12:09.447: E/AndroidRuntime(2917):     at com.optimus.mobile.survey.VideoCaptureComponentActivity.onActivityResult(VideoCaptureComponentActivity.java:82)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at android.app.Activity.dispatchActivityResult(Activity.java:3931)
07-06 17:12:09.447: E/AndroidRuntime(2917):     at android.app.ActivityThread.deliverResults(ActivityThread.java:3708)
07-06 17:12:09.447: E/AndroidRuntime(2917):     ... 11 more

基本上问题在于,在代码中
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri();  
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);  
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0); 

这里出现了问题,无法将文件保存到设定的位置,我不知道问题出在哪里。 我从这个链接中获取了这段代码 http://developer.android.com/guide/topics/media/camera.html


请提供您代码的第82行!!! - Muhannad A.Alhariri
是的,我提供了写外部存储权限这一行。 - Aditya Pratap Singh
请提供你代码的第82行! - Muhannad A.Alhariri
你是在模拟器上测试吗? - Muhannad A.Alhariri
@AdityaPratap 我同意你的看法。我也在处理音频和视频,但是在自定义位置没有看到任何视频。但是当同样的操作应用于简单相机时,它却可以工作!那么你找到了解决这个奇怪问题的方法吗? - Mohit
显示剩余3条评论
3个回答

5

如果您正在使用putExtra(MediaStore.EXTRA_OUTPUT, fileUri);传递Uri来保存图像或视频,则始终会在onActivityResult中收到NULL作为data.getData();。因此,请使用意图传递的图像或视频的Uri

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
     if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) 
     {
            if (resultCode == RESULT_OK) 
            {
              //  myVideo= data.getData();
                tv.setText("Video"); 
                vv.setVideoURI(fileUri);//set Uri here which you passed with Intent
                vv.setMediaController(new MediaController(this));
                vv.requestFocus();
                vv.start(); 
            }           
    }
}

这并不能解决问题,仍然显示相同的错误,也许你可以帮我一下,如何将通过我的视频活动捕获的视频文件保存到自定义位置。 - Aditya Pratap Singh
首先确保SD卡上是否已创建视频? - ρяσѕρєя K

2
private static String FILE_NAM1  = "video_one";

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == VIDEO_ACTIVITY) {
        Uri videoFileUri = data.getData();
        String outputfile = getFilesDir() + File.separator+FILE_NAM1+"_tmp.mp4";

        try {
            InputStream in = getContentResolver().openInputStream(videoFileUri);
            MainActivity.createFileFromInputStream(in, outputfile);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("saved uri is "+videoFileUri.toString());
        Intent intent = new Intent(getBaseContext(), VideoActivity.class);
        intent.putExtra("video_uri",videoFileUri);
        startActivity(intent);
    }
}

private static File createFileFromInputStream(InputStream inputStream, String fileName) {

   try{
      File f = new File(fileName);
      f.setWritable(true, false);
      OutputStream outputStream = new FileOutputStream(f);
      byte buffer[] = new byte[1024];
      int length = 0;

      while((length=inputStream.read(buffer)) > 0) {
        outputStream.write(buffer,0,length);
      }

      outputStream.close();
      inputStream.close();

      return f;
   }catch (IOException e) {
       System.out.println("error in creating a file");
       e.printStackTrace();
   }

   return null;
}

从意图中删除 intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);


2
“ACTION_VIDEO_CAPTURE” 没有记录在文档中,无法通过 “onActivityResult()” 返回 “Uri”。依赖第三方应用程序执行未记录的操作并不是一个好计划。 - CommonsWare

0
我使用这段代码进行视频的录制和保存:
private String name_vid; 
private static int REC_VIDEO = 1;
public void rec_vid(View v) {
    //set name & path to vid
    name_vid = Environment.getExternalStorageDirectory()+"/videos/myvid.mp4";
    //check if folder exists, else, create it
    File path = new File(Environment.getExternalStorageDirectory()+"/videos/");
    if (!path.exists())
    path.mkdirs();
    //create the intent
    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
    int code = REC_VIDEO;
    Uri output = Uri.fromFile(new File(name_vid));
    //Add extra to save video
    intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
    startActivityForResult(intent, code);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REC_VIDEO) {
        if (resultCode == -1) {
            //create a MediaScanner to save the vid into the indicate path
            new MediaScannerConnectionClient() {
                private MediaScannerConnection msc = null;
                {
                    msc = new MediaScannerConnection(
                            getApplicationContext(), this);
                    msc.connect();
                }

                public void onMediaScannerConnected() {
                    msc.scanFile(name_vid, null);
                }

                public void onScanCompleted(String path, Uri uri) {
                    msc.disconnect();

                }
            };
            Toast.makeText(this,"Video saved succesfull",
                    Toast.LENGTH_SHORT).show();
        }

    }
}

请记得在清单文件中设置权限使用:

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

这段代码将一个视频存储在给定的路径中。但是存储的视频无法播放。它会在AlertDialogBox中显示“错误,抱歉,无法播放此视频”。请帮忙解决。 - Jagan
你应该检查两件事情,安卓设备记录视频为mp4格式,而其他设备则为3gp格式,尝试将此格式更改为name_vid。当你在VideoView中设置videopath时,它不必获取“mnt/”路径,所以我会删除name:vid变量的这部分名称。请参考以下代码:VideoView vv = (VideoView) findViewById(R.id.videoView1); //cut the "mnt/" in the video_name vv.setVideoPath(name_vid.substring(4, name_vid.length())); //create the media controllers vv.setMediaController(new MediaController(this)); //start to play the vid vv.start(); - Leonardo Sapuy
在Toast之后,将此添加到onActivityResult中:视频保存成功。 - Leonardo Sapuy
但是我手动进入SD卡存储位置,找到了视频并尝试播放,但是视频无法播放。 - Jagan
对我来说,这将创建一个大小为0的文件。 - Yar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接