I have an activity that allows you to record a video if you open a dialog and click on an icon.
The problem is that after I stop recording it throws a NullPointerException even though the video is saved properly. According to Log Cat the error is not in my code so I tried to place "checkpoints" in my code and I found out that even the onActivityResult of my activity is executed properly so now I'm out of idea what to do.
Here is the Log Cat:
Code:
these are from my dialog that invokes the camera app
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);
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
((Activity)context).startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
private static Uri getOutputMediaFileUri(int type)
{
return Uri.fromFile(getOutputMediaFile(type));
}
private static File getOutputMediaFile(int type)
{
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()+"/Movies", "MyCameraApp");
// 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("MyCameraApp", "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() + "/" +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + "/" +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
This code was more or less copied from the android developers site.
As I mentioned even the onActivityResult of my activity is executed properly(where I dismiss the dialog) after this.
Try this:
private static File getOutputMediaFile(int type)
{
File mediaStorageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = "IMG_"+ timeStamp + ".jpg";
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = "VID_"+ timeStamp + ".mp4";
} else {
return null;
}
return new File(mediaStorageDir, mediaFile);
}
The getExternalStorageDirectory method returns a File object, not a string you can append a subdirectory to.
It also wonder if the directory returned by that method would be available to a service. The Android specs say:
On devices with multiple users (as described by UserManager), each
user has their own isolated external storage. Applications only have
access to the external storage for the user they're running as.
LOL!!!! Just realized this question was asked 2 years ago! Did you find the answer yet?? LOL
Related
I am building an app which record videos with camera API. I followed a tutorial from android developers site after the video records, It is saved in an external storage directory. How do I save in internal storage instead of external storage.
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "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 mediaFile;
}
All you need is in the official android dev site: https://developer.android.com/guide/topics/data/data-storage.html#filesInternal
I'm using MediaRecorder to create videos in my Camera app; in the "prepare method" I set the output file with recorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()); while the getOutputMediaFile method is the following
private void observeVideo(String mediaFilePath){
observer = new FileObserver(mediaFilePath, FileObserver.CLOSE_WRITE) {
#Override
public void onEvent(int event, String path) {
stopWatching();
Toast.makeText(context, path + " saved correctly", Toast.LENGTH_LONG);
}
};
observer.startWatching();
}
private File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
if (!Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {
return null;
}
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// 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("MyCameraApp", "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");
observeVideo(mediaFile.toString());
} else {
return null;
}
return mediaFile;
}
The problem is that onEvent isn't called. I checked if the path (of the video recordered) that I pass to the FileObserver is null, but there isn't this problem and Log show me the right pathname of video. Why?
Since this is the most recent question of the ones to show in google i am adding my input in here:
possible problem 1:
the path given to the observer is wrong, missing a / or the file does not exist
possible problem 2:
missing grant access to the path like android.permisison.READ_STORAGE or its not using a FileProvider as required
possible problem 3:
android 6 fileObserver bug, it wont work and the only work around is to do a looper that check every X seconds
I have a permission exception when I try (I think) to create a file in my physical device's external storage (nexus 5 android 6.0), whereas it works fine with a 4.3 emulated device.
My permissions are fine, but I get this error :
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.VIDEO_CAPTURE flg=0x3 cmp=com.google.android.GoogleCamera/com.android.camera.VideoCamera clip={text/uri-list U:file:///storage/emulated/0/Pictures/MyCameraApp/VID_20151216_145322.mp4} (has extras) } from ProcessRecord{5dab894 22712:com.***} (pid=22712, uid=10199) with revoked permission android.permission.CAMERA
any idea ?
I'll add a little more information :
My media utils is basic copy/paste from google video tutorial :
public class MediaUtils {
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
public static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
public static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// 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("MyCameraApp", "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;
}
return mediaFile;
}
}
And my intent :
Uri fileUri = MediaUtils.getOutputMediaFileUri(MediaUtils.MEDIA_TYPE_VIDEO);
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(takeVideoIntent, ACTION_TAKE_VIDEO);
There is a new permission system on API 23 and higher.
The permission is requested at run time.
You should read this How to manage permission on Android 6.0 and this Android request permission
Hello I'm developing an app which uses the camera2 API. I used the Caemra2Video sample provided by Google, and during the modification I changed the file storage directory.
The original code is like this:
mMediaRecorder.setOutputFile(getVideoFile(activity).getAbsolutePath());
...
private File getVideoFile(Context context) {
return new File(context.getExternalFilesDir(null), "video.mp4");
}
I changed it in this way:
private File getVideoFile(Context context) {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "camera2Video");
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d(TAG, "failed to create directory");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File videoFile;
videoFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
return videoFile;
}
If I record a video, there is indeed a file with the correct name inside the folder. However, whenever I open the app and start the camera activity, there will be a .mp4 file generated (no matter whether I actually record the video or not) with the size of 0. How can I modify it to avoid this? Thanks!
I use the following code to call existed camera :
// New intent to Camera feature
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
Uri fileUri = Uri.fromFile((new File((new Date()).toString()))); // 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);
I can capture photo, but can not record the video, I received the error Warning : Camera failed
I try to do something related to some solutions but can not receive good result. (Although reset the phone)
Please tell me how to fix this,
Thanks,
P/s : Device - Samsung Galaxy Tab 7 2.2.1
EDIT :
I use the following code to receive the response, and response the result resultCode == RESULT_CANCELED
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_SHORT).show();
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the video capture
Toast.makeText(this, "User cancelled the video capture", Toast.LENGTH_SHORT).show();
} else {
// Video capture failed, advise user
Toast.makeText(this, "Warning : Camera failed", Toast.LENGTH_SHORT).show();
}
I compared your code with Android Guide. The only difference is the file uri. You can try the Google's sample code to get the file uri:
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// 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("MyCameraApp", "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;
}
return mediaFile;
}