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
Related
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!
we have 2 memories for store files:
1- phone memory
2- sd card memory
now :
I can access to files and roots in sdcard memory with Environment.getExternalStorageDirectory ... and return : /storage/sdcard0 this is ok.
but :
When i store files and media (music,pic, ...) in phone memory, how can to get path phone memory?
There are different ways of storing and retrieving application data; SharedPreferences, Internal Storage, External Storage.
- SharedPreferences basically restricts other apps from accessing the data.
- Internal Storage basically stores the data in Phone memory
- External Storage basically stores the data in any other memory cards which can be mounted or unmounted.
If I understand your question properly, then you are interested in External Storage - Public files which basically stores the files in External storage and allows any other apps / user to access the file.
For example:
File sample = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
For app's internal file directory, use
getFilesDir();
For external storage, use
Environment.getExternalStorageDirectory();
Okay, I usually use this helper class to save my media files:
/**
* This class create, name given the timestamp and save a multimedia file in the Environment.DIRECTORY_PICTURES folder
* This location works best if you want the created images to be shared
* between applications and persist after your app has been uninstalled.
*/
public class FileManager {
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
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){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), VideoRecordingActivity.TAG);
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;
}
}
Then to use it I will just do:
File currentFile= FileManager.getOutputMediaFile(2);
Note: The media file will be created in sdcard/Pictures/AppName but to be able to see them with your file browser make sure to update your mediaScanner:
MediaScannerConnection.scanFile(getApplicationContext(), new String[]{file.getPath()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, final Uri fileUri) {
//Eventually some UI updates
}
});
I'm getting this error "Cannot resolve constructor 'Date()'" and i don't know why.
If someone could explain why i'm getting it, i would be grateful.
Thank you
Code:
/** Create a File for saving an image or video */
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_HHmm").format(new Date());
File mediaFile;
String mImageName="camera_wiki"+ timeStamp +".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName);
return mediaFile;
}
The issue is resolved by using a correct Date class: java.util.Date.
I uploaded my app to google play and after this I found that my application has not been working in all devices that i checked except my own...
I believe that the problem is a result of the file save location, I use the following code:
But what happens in devices without SD Card?
in the logcat i recieve error "failed to create directory"
// Step 4: Set output file
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO)
.toString());
outputFileName = getOutputMediaFile(MEDIA_TYPE_VIDEO).toString();
/** 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_MOVIES),
"Your_voice");
// 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("Your_voice_App", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("ddMMyy_HHmmss")
.format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "Your_voice" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
You can then review, edit and quickly share them without needing to boot up your PC. It'll also allow you to watch videos stored on the card, meaning you don't need to clog up your precious internal storage with huge video files.
http://resultplanet.org/
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