9

I am using intent for record video.

so i use following code on recordVideo button's click

Videofilepath = "";
Intent intent = new Intent(android.provider.MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(intent,REQUEST_VIDEO_CAPTURED);

and in onActivityResult

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
            case IMAGE_PICK:
                this.imageFromGallery(resultCode, data);
                break;
            case IMAGE_CAPTURE:
                this.imageFromCamera(resultCode, data);
                break;
            case REQUEST_VIDEO_CAPTURED:
                this.videoFromCamera(resultCode, data);

                break;
            default:
                break;
            }
        }
    }


private void videoFromCamera(int resultCode, Intent data) {
        uriVideo = data.getData();


        uploadedFileName="";
        Constant.IS_FILE_ATTACH = true;

        Toast.makeText(PDFActivity.this, uriVideo.getPath(), Toast.LENGTH_LONG)
        .show();
        String[] filePathColumn = { MediaStore.Video.Media.DATA };

        Cursor cursor = getContentResolver().query(uriVideo, filePathColumn,
                null, null, null);
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String filePath = cursor.getString(columnIndex);
        Videofilepath = filePath;
        System.out.println("Videofilepath filepath from camera : "
                + Videofilepath);
        cursor.close();
        File f = new File(filePath);
        System.out.println("file created ? : " + f.exists());

        Bitmap bMap = null;
        do {
            try {
                // Simulate network access.
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } while (!f.exists());
        bMap = ThumbnailUtils.createVideoThumbnail(filePath,
                MediaStore.Video.Thumbnails.MICRO_KIND);
        do {
            try {
                // Simulate network access.
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } while (bMap == null);
        imageOrVideo = "video";
        attachmentvalue.setImageBitmap(bMap);
    }

This code is working fine with samsung galaxy Tab. But not working with Nexus 7. May be Nexus 7 have front camera. but i got resultant data intent is null onActivityResult.

so in my Logcat i got the following exception :-

08-08 12:51:31.160: E/AndroidRuntime(10899): FATAL EXCEPTION: main
08-08 12:51:31.160: E/AndroidRuntime(10899): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=200, result=-1, data=Intent {  }} to activity {com.example.activity/com.example.PDFActivity}: java.lang.NullPointerException
Praveen Sharma
  • 4,326
  • 5
  • 25
  • 45

3 Answers3

8

Finally I resolved this issue. Nexus 7 Stores the videos in DCIM directory but onActivityResults it returns null. Its an documented issue with Nexus 7 device.

so fix this issue with intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
the code is as :-

code on record button click:-

  intent = new Intent(android.provider.MediaStore.ACTION_VIDEO_CAPTURE);    
   fileUri = getOutputMediaFile(MEDIA_TYPE_VIDEO);  // create a file to save the video in specific folder (this works for video only)
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high

    // start the Video Capture Intent
    startActivityForResult(intent, REQUEST_VIDEO_CAPTURED_NEXUS);

code inside switch - case block of onActivityResult :-

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
    case REQUEST_VIDEO_CAPTURED_NEXUS:
    this.videoFromCameraNexus(resultCode, data);
    break;

default:
                break;
            }
        }
    }

// videoFromCameraNexus method

private void videoFromCameraNexus(int resultCode, Intent data) {

        if(fileUri != null) {
            Log.d(TAG, "Video saved to:\n" + fileUri);
            Log.d(TAG, "Video path:\n" + fileUri.getPath());
            Log.d(TAG, "Video name:\n" + getName(fileUri)); 
    // use uri.getLastPathSegment() if store in folder
    //use the file Uri.
        }
    }

Get the output Media file uri with the following Method

public Uri getOutputMediaFile(int type)
    {
        // To be safe, you should check that the SDCard is mounted

        if(Environment.getExternalStorageState() != null) {
            // this works for Android 2.2 and above
            File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES), "SMW_VIDEO");

            // This location works best if you want the created images to be shared
            // between applications and persist after your app has been uninstalled.

            // Create the storage directory if it does not exist
            if (! mediaStorageDir.exists()) {
                if (! mediaStorageDir.mkdirs()) {
                    Log.d(TAG, "failed to create directory");
                    return null;
                }
            }

            // Create a media file name
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
            File mediaFile;
           if(type == MEDIA_TYPE_VIDEO) {
                mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                "VID_"+ timeStamp + ".mp4");
            } else {
                return null;
            }

            return Uri.fromFile(mediaFile);
        }

        return null;
    }

Its works for me.

Praveen Sharma
  • 4,326
  • 5
  • 25
  • 45
  • 2
    The problem I have with this answer is that if you pass EXTRA_OUTPUT location to the video capture intent then most of the other phone's camera apps don't behave properly. On some older samsung devices the camera app will crash when saving, on a galaxy note 1 with android 4.1 the camera app will save the file but won't give the user the button to accept the photo, it just stays in the app (they have to press the back button which isn't obvious). Mixed results with other apps/phones as well. This means we will need to have logic to detect the phone or camera app... – Matt Wolfe Nov 15 '13 at 18:05
  • if people putting down vote, then please put a comment here, so that i can correct my mistake. – Praveen Sharma Dec 04 '13 at 05:01
  • I have the same issue on an Nexus 7 but I also have to support older Android versions... Is there a workaround to make it work on both Nexus 7 and older Android Versions (2.3)? – Georg Feb 18 '14 at 14:31
  • ` Its an documented issue with Nexus 7 device` Can you share the link of this? – Shivam Pokhriyal May 17 '21 at 04:09
2

Thanks for the workaround!

Here is more brushed and copy-paste usable code:

/**
 * Create intent to take video.
 */
public static Intent createTakeVideoIntent() {
    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
    Uri uri = getOutputVideoUri();  // create a file to save the video in specific folder
    if (uri != null) {
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
    }
    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high

    return intent;
}


@CheckForNull
private static Uri getOutputVideoUri() {
    if (Environment.getExternalStorageState() == null) {
        return null;
    }

    File mediaStorage = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "YOUR_APP_VIDEO");
    if (!mediaStorage.exists() &&
            !mediaStorage.mkdirs()) {
        Log.e(YourApplication.TAG, "failed to create directory: " + mediaStorage);
        return null;
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
    File mediaFile = new File(mediaStorage, "VID_" + timeStamp + ".mp4");
    return Uri.fromFile(mediaFile);
}

Tested on Nexus 4 v4.3 JWR66Y

oxied
  • 1,773
  • 19
  • 14
0

Made a fork and fixed the problem by storing to a permanent directory which will still be available after the result has been received.

https://github.com/pencilcheck/cordova-plugin-media-capture

Pencilcheck
  • 2,664
  • 3
  • 25
  • 14