So I have a frame view I stream the camera view using SurfaceView.
I want to save the taken image to a new folder DCIM/ZES which does not exists yet. In the code below Im getting the right path and after the first atempt mkdirs() return true. the thing is the directory DOES NOT get created no matter what even though exists() method will return true
after the first attempt on the same dir.
getting the output file name the creating the directory:
private static File getOutputMediaFile(int type){
// getting the 'MES' folder route
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM), "MES");
Log.i("CAMERA", "SAVING IMAGE TO FILE");
// 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 == MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getAbsolutePath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
saving the image:
Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera c) {
File pictureFile = getOutputMediaFile(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d("CAMERA", "Error creating media file, check storage permissions");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
Log.i("FILE", "File was saved in " + pictureFile.getName());
} catch (FileNotFoundException e) {
Log.e("CAMERA", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.e("CAMERA", "Error accessing file: " + e.getMessage());
}
}
};
I then use the pictureCallback in takePicture() method and that works fine
What is not working is: no picture is saved. no directory is created (that I can see). checking if the directory exists using exists() return true after first try.
Looked for the whole day for a solution online but no success,
Tried to use MediaStore.Images.Media.insertImage() method but cant configure the directory images are saved so its no good.
Really frustrated with this one
Thanks for the help
Related
I have an app where user can upload file with additional info about it, such as description.
Now what i do is:
predefine the PATH where the files are stored ( so for example for server it will be at /files/ or for AWS url to aws )
user uploads file
file is saved, at location PATH/userId/uploaded file name
service that saves file returns whole path
the informations about file ( including path where it was stored ) is stored in DB.
So smth like this:
#Service
public class DiskSaveFileService implements SaveFileService {
#Value("${file.path}")
private String path;
#Override
public String saveFile(String fileName, byte[] bytes) {
Path targetLocation = Paths.get(path + "/" + fileName);
try {
Files.createDirectories(targetLocation.getParent());
Files.write(targetLocation, bytes);
} catch (IOException e) {
throw new SaveFileException("Saving file failed", e);
}
return targetLocation.toString();
}
#Override
public boolean safeDeleteFile(String fileName) throws SaveFileException {
Path targetLocation = Paths.get(path + "/" + fileName);
try {
Files.delete(targetLocation);
} catch (IOException e) {
return false;
}
return true;
}
}
And service:
UserEntity user = userUtilService.getLoggedUser();
String fileName = file.getOriginalFilename();
String path = user.getId() + "/" + fileName;
try{
String location = saveFileService.saveFile(path, uploadedFile.getBytes());
FileEntity fileEntity = new FileEntity();
fileEntity.setPath(location);
....
fileRepository.save(fileEntity);
} catch (UsernameNotFoundException | SaveFileException | IOException e) {
deleteFile(path);
throw new RecipeServiceException("Error creating recipe!", e);
}
However if user wanted to upload two separate files, that happens to have same name, this would overwritte them, as both files would be saved in the same path.
What is the best way to determine where exactly to store path? I first wanted to save the file as
PATH/userId/id of entity/name of the file
However in that case i would need to save info about file to database, then save the file ( so i will have generated ID of row ), and then update entity of location. So i would have extra database hit.
What are some best ways to decide the path then? Methods that would actually makes sense.
I have a camera that I am grabbing values pixel-wise and I'd like to write them to a text file. The newest updates for Android 12 requires me to use storage access framework, but the problem is that it isn't dynamic and I need to keep choosing files directory. So, this approach it succesfully creates my files but when writting to it, I need to specifically select the dir it'll save to, which isn't feasible to me, as the temperature is grabbed for every frame and every pixel. My temperature values are in the temperature1 array, I'd like to know how can I add consistently add the values of temperature1 to a text file?
EDIT: I tried doing the following to create a text file using getExternalFilesDir():
private String filename = "myFile.txt";
private String filepath = "myFileDir";
public void onClick(final View view) {
switch (view.getId()){
case R.id.camera_button:
synchronized (mSync) {
if (isTemp) {
tempTureing();
fileContent = "Hello, I am a saved text inside a text file!";
if(!fileContent.equals("")){
File myExternalFile = new File(getExternalFilesDir(filepath), filename);
FileOutputStream fos = null;
try{
fos = new FileOutputStream(myExternalFile);
fos.write(fileContent.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
Log.e("TAG", "file: "+myExternalFile);
}
isTemp = false;
//Log.e(TAG, "isCorrect:" + mUVCCamera.isCorrect());
} else {
stopTemp();
isTemp = true;
}
}
break;
I can actually go all the way to the path /storage/emulated/0/Android/data/com.MyApp.app/files/myFileDir/ but strangely there is no such file as myFile.txt inside this directory, how come??
Working Solution:
public void WriteToFile(String fileName, String content){
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
File newDir = new File(path + "/" + fileName);
try{
if (!newDir.exists()) {
newDir.mkdir();
}
FileOutputStream writer = new FileOutputStream(new File(path, filename));
writer.write(content.getBytes());
writer.close();
Log.e("TAG", "Wrote to file: "+fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean moveFilesToSentPath(Context context, String type, String filePath, String fileName) {
String folderPath = getFolderPath(type);
File dir;
/* if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
dir = new File(Environment.DIRECTORY_MOVIES *//*+ "/" + fileName*//*);
}else {*/
dir = new File(this.context.getFilesDir().toString() + "/" + folderPath); // }
if (!dir.exists()) {
dir.mkdirs();
File nomediaFile = new File(dir.getAbsoluteFile(), ".nomedia");
try {
if (!nomediaFile.exists()) {
nomediaFile.createNewFile();
}
} catch (IOException e) {
e.printStackTrace();
}
}
File from = new File(filePath);
File to = new File(dir + "/" + fileName);
Log.v(TAG, "moveFilesToSentPathFrom= " + from);
Log.v(TAG, "moveFilesToSentPathTo= " + to);
if (from.exists()) {
try {
FileUtils.copyFile(from, to);
return true;
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
I want to copy video file from its original location to my own created destination i.e. like (Environment.DIRECTORY_MOVIES + "/" + "video" + "/"+fileName) and then access the file from destination. And also plz elaborate the media store api usage for saving file at specific location
The above code is for api level lower than 30, but need solution for android 11 api level 30 as we can't access storage due to security reasons but instead they provide with media store api, I don't have much idea with media store api. Thanks in advance for the help.
The application is working in every phone except one. And that phone shows this error.
In other phones the image path seems like this /storage/emulated/0/Android/data/com.example.x/files/x/Photos/x_20200415111325.jpg and works well.
Here is the image creation function
File storageDir = getExternalFilesDir("Photos");
File image = new File(storageDir.getAbsolutePath() + File.separator + photoName);
try {
image.createNewFile();
} catch (IOException e) {
CustomUtility.showAlert(this, "Image Creation Failed. Please contact administrator", "Error");
}
currentPhotoPath = image.getAbsolutePath();
Log.e("image path",currentPhotoPath);
return image;
Here are things I have done:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
and
public void createMyFolder(){
File directory = new File(Environment.getExternalStorageDirectory().getPath() + "/myfolder/");
directory.mkdir(); //I had also tried mkdirs()
File file= new File(Environment.getExternalStorageDirectory().getPath() + "/t1.dat");
try {
file.createNewFile();
} catch (IOException e) {}
}
I tested 3 devices and one of them threw exception:
java.io.IOException: Cannot create dir /mnt/sdcard/myfolder
t1.dat was created successfully in /mnt/sdcard/ but myfolder was not.
The device is Xperia Ion with Android version 4.0.4. What's wrong about it and how can I fix it?
Edit: I had tried to create folders by some applications, like File Manager.
And they also failed to create although the sdcard is writable and readable.
I think my phone has some "protections" which do not allow me to create folders in sd card.
But it's funny that my phone allows me to create files instead.
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/* Checks if external storage is available to at least read */
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) ||
Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
Replace Environment.getExternalStorageDirectory() with directory and also "/myfolder" will be "/myfolder"
public void createMyFolder(){
File directory = new File(Environment.getExternalStorageDirectory().getPath() + "/myfolder");
directory.mkdir(); //I had also tried mkdirs()
File file= new File(directory.getPath() + "/t1.dat");
try {
file.createNewFile();
} catch (IOException e) {}
}