WARNING: File.mkdir() is ignored - android

I've created a basic Audio Recording App using Media Recorder API's. I'm trying to create a folder in the SD card and to save my recorded files to that folder. I'm getting this warning with following code.
File.mkdir() is ignored
// Assign random number to avoid audio file from overwriting
Long tsLong = System.currentTimeMillis()/1000;
// Specify a Location for the recorded file to be stored in the SD card
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/AudioRecordTest/";
File path = new File(mFileName);
if(!path.exists()) {
path.mkdir();
}
mFileName += "/AudioRecordTest_" + tsLong.toString() + ".mp3";
How to solve this warning message. Feel free to modify the code if there is any other mistake.

Correct me if I'm wrong, but I expect that the (compilation) warning message really says this:
Result of File.mkdir() is ignored
... or something like that. It is telling you that you are ignoring the result of the mkdir() call that tells you whether or not a directory was created.
One way to avoid the warning would be to test the result and act appropriately. Another would be to simply assign the result to a temporary variable, ignore it, and (potentially) crash later because the directory wasn't created when it should have been.
(Guess which solution is better ...)
Feel free to modify the code if there is any other mistake.
Since you asked ... it is BAD STYLE to use Hungarian notation for Java variable names. Java is a strongly typed language where all variables have a clear declared types. You should not need the mental crutches of some ghastly identifier convention to tell you what a variable's type is intended to be.

As #Stephen C suggests, i handled in these ways
1)
boolean isDirectoryCreated= path.mkdir();
and ignore 'isDirectoryCreated'
2) (Recommended)
boolean isDirectoryCreated=path.exists();
if (!isDirectoryCreated) {
isDirectoryCreated= path.mkdir();
}
if(isDirectoryCreated) {
// do something
}
3)
if (!path.exists()) {
if(path.mkdir()){
// do something
}
}

If you want to ignore this warning, add this on the method:
#SuppressWarnings("all")

I created a utility function:
#SuppressWarnings("unused")
private static void IGNORE_RESULT(boolean b) {}
And then to use:
IGNORE_RESULT(path.mkdir());
I like this solution because it is self documenting. You are explicitly stating that you know there is a result and you are intentionally ignoring it. It should also optimize out to a NOP during compilation so there is no unnecessary test at runtime just to suppress a useless warning.

Related

Processing Android: java.lang.IllegalArgumentException: File contains a path sepator

Im currently trying to save some values in a text file in Processing Android (APDE). I want to later use this in another context, so it's important to use a complete file path. From Processing documentation for loadStrings():
... Alternatively, the file maybe be loaded from anywhere on the local
computer using an absolute path (something that starts with / on Unix
and Linux, or a drive letter on Windows)
So it must be possible.
I already searched for a answer, but never found something for Processing.
So my code is:
String[] saveData;
int score;
void setup(){
saveData=loadStrings("/storage/emulated/0/dataP/hi.txt");
score=parseInt(saveData[0]);
fullScreen();
frameRate(60);
noStroke();
noSmooth();
textAlign(CENTER);
textSize(height/20);
}
void draw(){
background(0);
fill(255) ;
text(score, width/2,height/2);
}
void mousePressed(){
score--;
saveData[0]=str(score);
println(saveData[0]);
saveStrings("/storage/emulated/0/hi.txt" ,saveData);
}
and I get the following error:
java.lang.IllegalArgumentException: File
/storage/emulated/0/dataP/hi.txt contains a path separator
I believe the confusion stems from the fact that loadStrings() method works differently for Java mode and Android mode. In Java mode, it is definitely possible to give loadStrings() an absolute Path with included separators, but in Android mode, loadStrings() will only work if you only specify a name without any separator (assumes by default to be looking into the data folder). Therefore, having any separator inside loadStrings() will throw the error.
One simple workaround you can try is to first create a separate path variable:
String path = "/storage/emulated/0/dataP/hi.txt";
And then give that as parameter to the loadStrings() method:
saveData = loadStrings(path);
If you were to use an SD card for storage, for example, you could do something like:
String SDCARD = Environment.getExternalStorageDirectory().getAbsolutePath();
File file = new File(SDCARD + File.separator + "mytext.txt");
String[] s = loadStrings(file.getPath());
As explained in the link in the comment I posted, loadStrings() and saveStrings() does not take absolute path as argument. What it means is that it can only access files with path "name.txt" and not "folder/name.txt". You have to do it using a FileInputStream and FileOutputStream if you must use absolute path. There are many examples of both these files on StackOverflow.

(Ionic) Cordova-file-plugin error when trying to read file

So, I'm currently trying to read an Audio file I just saved on the App's directory (Android) through the cordova file-plugin, but I keep getting the same error code 5, which stands for "ENCODING_ERR".
This is how I create the file and start recording
start() {
this.filename = this.file.externalDataDirectory.replace(/file:\/\//g, '');
this.mediaobject = this.media.create(this.filename + 'audioprofile' + '.3gp');
this.mediaobject.startRecord();
}
This is how I stop recording and save the file
stop() {
this.mediaobject.stopRecord();
this.mediaobject.release();
...
And this is where I'm stuck: right after saving it, I need to have it as a String, so I'm try to read it ( alert(content) should show me that string)
stop() {
this.mediaobject.stopRecord();
this.mediaobject.release();
this.storage.get("uid").then((id) => {
try{
this.file.readAsDataURL(this.filename,'audioprofile'+'.3gp').then((filecontent)=>{
alert(filecontent);
},(err)=>{
alert(err.code);
})
} `
After some research I found out it PROBABLY means I'm not giving the right path for it, but I've tried everything, any combinations of 'filename' and 'filepath' were made, even adding the prefix removed on start().
I want to know if someone managed to read a file with this cordova plugin and if you did, please help me out.
Thanks in advance, this is my first post here \o/ (although I've always used the website, love u guys).
i had the same problem. I solved it giving this path:
this.media.create(this.file.externalDataDirectory + this.nameFile);
I dont know why but this.file.readAsDataURL cant read the file if u save it deleting /file:
Remember change the path in all your methods.
Well i managed to do this with the File-Path Plugin, it resolves the Path for your file in a way the File Plugin understands and is able to reach the file, then you just have to manipulate it the way you want.

FileObserver -> onEvent(event, path): path is NULL

I want to know when a file is finished writing, and to do that I'm trying to use FileObserver. I'm doing it like this:
FileObserver observer = new FileObserver(imageUri.getPath()) {
#Override
public void onEvent(int event, String path) {
if(event == FileObserver.CLOSE_WRITE)
Log.d(TAG, "FILE: "+path);
}
};
observer.startWatching();
imageUri is a valid Uri. When the file is closed I get the following log entry:
FILE: null
Why is it null? It's possible that the user writes several files, so I need to know which one is triggering the event.
Thanks!
According to the documentation of onEvent():
The path, relative to the main monitored file or directory, of the file or directory which triggered the event
So I guess when path is null it is the the specified file or directory...
You need to keep track of the original path yourself. And append the path of onEvent() to this path to get the full path (unless you are tracking a file and its value is always null):
FileObserver observer = new FileObserver(imageUri.getPath()) {
public String basePath;
#Override
public void onEvent(int event, String path) {
String fullPath = basePath;
if(path != null) {
// Eventually add a '/' in between (depending on basePath)
fullPath += path;
}
Log.d(TAG, "FILE: "+fullPath);
}
};
observer.basePath = imageUri.getPath();
observer.startWatching();
I tried to keep the example as close to your code snippet as possible. But, it is much better to create a full-blown class extending FileObserver, so you can add an constructor to store the basePath and are not required to access the public field from outside the class/instance!
I just encountered something like this today. I had a FileObserver monitoring a folder for new files, which I then attempted to do something with the downloaded images. When I went to access the images by BitmapFactory.decodeFile(ImgPath), I would get sometimes get a NULL result. This seemed to happen on newer and faster devices, and never in debug when stepping through the event. I came to the conclusion that the file was still in use or not completely finished yet and I had to wait until the system unleashed its claws from the file.
I'm new to Android development and am not familiar with the proper way to do this yet, but avoided the NULL issue for the moment by inserting a Thread.sleep. I know this is terrible, but it worked as a temp solution for me.

Deleting file from private storage on android

I'm trying to delete a file that I earlier created in my android app.
The problem I'm having is that the file won't go away. Even though everything seems to work.
I've looked at several post here on stackoverflow, but still not solution. The garbage collections was one of the hints I've found.
System.gc();
System.out.println("Exists: "+file.exists());
System.out.println("Read: "+file.canRead());
System.out.println("Write: "+file.canWrite());
System.out.println("Deleting: " + file);
boolean r = file.delete();
System.out.println("Result of deletion: "+r);
System.gc();
And the result in the log
Exists: true
Read: true
Write: true
Deleting: data/data/no.ntnu.kpro.app/files/kprothales/XOMessage/8
Result of deletion: true
Does anyone have any idea as to why it isn't removed?
EDIT:
Lucifer: Yeah, I have set WRITE_EXTERNAL_STORAGE permission in the manifest.
ShineDown: No, it is just a file without an extension. For now it is containing xml, but this is going to change over time, hence why I have not called it .xml. Could this be a problem?
chintan khetiya: I believe this line is allready included in the code above.
check the answer here:
Android: how to delete internal image file
which is basically suggesting to call deleteFile:
if(activity.deleteFile(imageName))
Log.i(TAG, "Image deleted.");

Write to txt file, but not overwrite

I got a little problem, it seems simple (personally I think it is), but I couldn't find a answer. But atleast I don't know how to fix it.
I write some lines to a .txt file when I hit the button Save.
Then after that, when I type something else, and hit Save again, it overwrites my first lines.
But I want that it writes at a new line. Also when I close and restart the app again, and hit save again, it must save the text on a new line again.
So basically: How can I write text to a .txt file, without overwriting previous lines.
I can write to a file, so that is not the problem, but only how to NOT overwrite.
This is the "little" part of my code:
public void Data_save_contacts(View v) {
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
try {
writer_contact = new BufferedWriter(new FileWriter(root + "/Save/Contacten.txt"));
writer_contact.write("Perceel "+str_boer_teler_nummer+" = "+str_boer_teler);
writer_contact.newLine();
} catch (IOException e) {
System.err.println(e);
}
}
Please put me in the good directions.
Thanks already, Bigflow
You have to do
writer_contact = new BufferedWriter(new FileWriter(root + "/Save/Contacten.txt",true));
Just as said in java documentation:
FileWriter
public FileWriter(File file,
boolean append)
throws IOException
Constructs a FileWriter object given a File object. If the second argument is true, then bytes will be written to the end of the file rather than the beginning.
Parameters:
file - a File object to write to
append - if true, then bytes will be written to the end of the file rather than the beginning
try:
public FileWriter (File file, boolean append)
set the append to true
Well given this is just a little of your code (and I'm assuming you chunked it out so as to not reveal other parts) what I suspect is going on is that you're opening the file root + "/Save/Contacten.txt" in a non-append mode. The first time you call it the file is created and written to. Subsequent times you call it, it finds the file, and recreates (or deletes content) and then writes to it.
Try using:
writer_contact = new BufferedWriter(new FileWriter(root + "/Save/Contacten.txt", true));
Of course the first time you open/create the file you'll want it to be false (unless you ALWAYS want to append if the file already exists).
Give that a spin.
you can check for if file exits or not ?
or you can also append old file.
If not exits then and then only create new one.

Categories

Resources