I am using intent camera to record videos. I have tested my app on Samsung, HTC, LG & Motorola Devices it works smoothly but on Nexus Phones its crashing after video is recorded and the file is selected for compression here is the code I am using to start intent and getting the video recorded file.
case R.id.camera_icon:
Intent videoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
uri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
if (uri == null) {
// display an error
Toast.makeText(MainActivity.this, R.string.error_external_storage,
Toast.LENGTH_LONG).show();
} else {
videoIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
videoIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10);
videoIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
// 0 = lowest res
startActivityForResult(videoIntent, RESULT_CODE_COMPRESS_VIDEO);
}
Creating Storage Location:
private Uri getOutputMediaFileUri(int mediaType) {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
if (isExternalStorageAvailable()) {
// get the URI
// 1. Get the external storage directory
String appName = MainActivity.this.getString(R.string.app_name);
File mediaStorageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
appName);
// 2. Create our subdirectory
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.e(TAG, "Failed to create directory.");
return null;
}
}
String path = mediaStorageDir.getPath() + File.separator;
if (mediaType == MEDIA_TYPE_IMAGE) {
mediaFile = new File(path + "thumb" + ".jpg");
} else if (mediaType == MEDIA_TYPE_VIDEO) {
mediaFile = new File(path + "video" + ".mp4");
} else {
return null;
}
Log.d(TAG, "File: " + Uri.fromFile(mediaFile));
// 5. Return the file's URI
return Uri.fromFile(mediaFile);
} else {
return null;
}
}
Related
I take a photo and save it to external storage :
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photoFile = getPhotoFile();
String authorities = getActivity().getPackageName() + ".fileprovider";
imageUri = FileProvider.getUriForFile(getActivity(), authorities, photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, 1);
It works fine
But what about recording a video
I wrote some code like this but i think it's not correct :
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
File videoFile = getVideoFile();
String authorities = getActivity().getPackageName() + ".fileprovider";
videoUri = FileProvider.getUriForFile(getActivity(), authorities, videoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
startActivityForResult(intent, 2);
What can i do?
EDIT:
And these methods create a dir and return photo and video files
public File getPhotoFile() {
//create a random name
String randomName = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File mainPath = new File(path, "/Images");
if (!mainPath.exists()) {
mainPath.mkdirs();
}
File photoPath = new File(mainPath, randomName + ".jpg");
return photoPath;
}
public File getVideoFile() {
//create a random name
String randomName = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File mainPath = new File(path, "/Videos");
if (!mainPath.exists()) {
mainPath.mkdirs();
}
File photoPath = new File(mainPath, randomName + ".mp4");
return photoPath;
}
To record video use:
startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE);
Here is an example
in your recordVideo.onClick() method add this code
if (checkPermissions(YourActivity.this)) {
captureVideo();
} else {
requestCameraPermission(MEDIA_TYPE_VIDEO);
}
public static boolean checkPermissions(Context context) {
return ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context,
Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED;
}
//in CaptureVideo method
private void captureVideo() {
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
File file = getOutputMediaFile(MEDIA_TYPE_VIDEO);
if (file != null) {
imageStoragePath = file.getAbsolutePath();
}
Uri fileUri = getOutputMediaFileUri(getApplicationContext(), file);
// set video quality
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file
// start the video capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_VIDEO_REQUEST_CODE);
}
/**
* Creates and returns the image or video file before opening the camera
*/
public static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
YourActivity.GALLERY_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.e(YourActivity.GALLERY_DIRECTORY_NAME, "Oops! Failed create "
+ YourActivity.GALLERY_DIRECTORY_NAME + " directory");
return null;
}
}
public static Uri getOutputMediaFileUri(Context context, File file) {
return FileProvider.getUriForFile(YourActivity.this, context.getPackageName() +
".provider", file);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_CAPTURE_VIDEO_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Refreshing the gallery
refreshGallery(getApplicationContext(), imageStoragePath);
// video successfully recorded
showVideo();
} else if (resultCode == RESULT_CANCELED) {
// user cancelled recording
Toast.makeText(getApplicationContext(),
"cancelled video recording", Toast.LENGTH_SHORT)
.show();
} else {
// failed to record video
Toast.makeText(getApplicationContext(),
"Sorry! Failed to record video", Toast.LENGTH_SHORT)
.show();
}
}
}
public static void refreshGallery(Context context, String filePath) {
// ScanFile so it will be appeared on Gallery
MediaScannerConnection.scanFile(context,
new String[]{filePath}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
}
});
}
private void showVideo() {
try {
videoView.setVideoPath(imageStoragePath);
// video playing
videoView.start();
} catch (Exception e) {
e.printStackTrace();
}
}
I am using this code right now but its destroy image quality.
I have issue regarding blur image
if (requestCode == IMAGE_REQUEST_CODE) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// kkkk(data.getData());
picture = (Bitmap) data.getExtras().get("data");//this
// I pass bitmap to function to get watermark
result = mark(picture , sh.getString("BARCODE", null), 10, 50,R.color.colorPrimaryDark, 200, 30, false);
// now i need a file to upload image on dropbox
file = storeImage(result);
}
// here is my function
private File storeImage(Bitmap image) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Log.d("",
"Error creating media file, check storage permissions: ");// e.getMessage());
return null;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
image.compress(Bitmap.CompressFormat.PNG,55, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.d("", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("", "Error accessing file: " + e.getMessage());
}
return pictureFile;
}
private File getOutputMediaFile() {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()
+ "/Android/data/"
+ getApplicationContext().getPackageName()
+ "/Files");
// 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()) {
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmmss").format(new Date());
File mediaFile;
increase++;
String mImageName = sh.getString("BARCODE", null) + "_" + timeStamp + ".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
</i>
}
on capturing image from camera in lollipop and higher versions getting the result data null on onActivityResult.
launchCamera();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
((MyWebViewActivity) context).fileUri = CommonUtils.getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, ((MyWebViewActivity) context).fileUri);
((MyWebViewActivity) context).startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
#Override
onActivityResult(int requestCode, int resultCode, Intent data);
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
if(fileUri!=null){
file_path = fileUri.getPath();
System.out.println("file-path---=" + file_path);
}else{
Toast.makeText(this, "Please try again", Toast.LENGTH_LONG).show();
}
if(!CommonUtils.isEmpty(file_path)){
}
} else if (resultCode == RESULT_CANCELED) {
// "User cancelled image capture",
} else {
// failed to capture image
}
}
getOutputMediaFileUri()
File file = getOutputMediaFile(type);
if (file != null) {
return Uri.fromFile(file);
}
return null;
getOutputMediaFile()
// External sdcard location
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "My Images");
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
File mediaFile;
System.out.println("mediaStorageDir==" + mediaStorageDir);
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".png");
} else if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
It appears like you're starting the activity for result from a fragment. In that case you've to override the OnActivityResult() method in both the fragment and the Activity.
Check out this answer. This should help
https://stackoverflow.com/a/21826858/7659504
when I am using my native app camera to take video, the output file have 3gp extension. I need to intent to camera with ACTION_VIDEO_CAPTURE intent action which will produce a file that has a mp4 file extension. how can I do it?
You can go ahead and try dis code:
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);
This will be called once the capture is completed
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
switch (requestCode) {
case REQUEST_VIDEO_CAPTURED_NEXUS:
this.videoFromCamera(resultCode, data);
break;
default:
break;
}
}
}
private void videoFromCamera(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;
}
This will save the captured video in pure MP4 format.
You can add the following code before start the intent :
videoUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),"fname_" + String.valueOf(System.currentTimeMillis()) + ".mp4"));
intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
I need to record a video within the application using the intent. I think the code is correct, however when I do start the image stops and the file gets 0Bytes. I let down the code I'm using.
The first function called:
protected void makeVideo() {
//create new Intent
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); // create a file to save the video
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high
// start the Video Capture Intent
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
}
getOutputMediaFile function:
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
// Environment.getExternalStorageState();
// File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), Constants.ALBUM.AlbumInPhone);
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), Constants.ALBUM.AlbumInPhone);
// 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(Constants.ALBUM.AlbumInPhone, "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_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_"+ timeStamp + ".mp4");
} else {
return null;
}
File x = mediaFile;
int y=0;
y=1;
return mediaFile;
}
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
and:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Video captured and saved to fileUri specified in the Intent
// Toast.makeText(this, "Video saved to:\n" + data.getData(), Toast.LENGTH_LONG).show();
String uri = fileUri.getPath();
if(TextUtils.isEmpty(uri)){
Log.v(TAG, "Could not get video");
} else {
Log.v(TAG, "video: " + uri);
if(BebeDataBaseManager.addVideoToAlbum(this, uri, albumId)){
Log.v(TAG, "video: added");
this.cursor.requery();
} else {
Log.v(TAG, "video: not added");
}
}
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the video capture
} else {
// Video capture failed, advise user
}
}
...
I'm doing something wrong?