I was trying to open a file for reading.
When using: Scanner input = new Scanner(filename); the file could not be found
but when I used:
InputStream in = openFileInput(filename);
Scanner input = new Scanner(in);
It worked. Why was the first line of code wrong?
Files are stored on the device in a specific, application-dependent location, which is what I suppose openFileInput adds at the beginning of the file name. The final result (location + file name) is constructed as follows:
/data/data/<application-package>/files/<file-name>
Note also that the documentation states that the openFileInput parameter cannot contain path separators.
To avoid hard-coding the location path, which could in principle even be different from device to device, you can obtain a File object pointing to the storage directory by calling getFilesDir, and use it to read whatever file you would like to. For example:
File filesDir = getFilesDir();
Scanner input = new Scanner(new File(filesDir, filename));
Note that constructing a Scanner by passing a String as a parameter would result in the scanner working on the content of the string, i.e. interpreting it as the actual content to scan instead of as the name of a file to open.
This drove me crazy couple of minutes ago. I forgot to add this line to manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I would expect a permission denied message. But just got a file not found...
In your case: openFileInput opens a file in your private app data directory (/data/data/your.package/filename). This never fails. But the scanner tries to open it on the root path. So when you want to read a file from SD card than you would use Environement.getExternalStorageDirectory().getAbsolutePath() + "/" + filename.
Scanner sc = new Scanner(new File(filename));
Related
I have a list of arrays of data in my app that I would now like to write to a file (csv) and use a 3rd party app (such as email) to share this csv file. I have had no luck finding any helpful resources for creating, finding the file path for, and appending to a file in Kotlin. Does anyone have experience with this or have examples to point to? Just to get started I'm trying to write the header and close the file so I can see that it is correctly writing.
This is what I have for now:
val HEADER = "ID, time, PSI1, PSI2, PSI3, speed1, speed2, temp1, temp2"
val filename = "export.csv"
var fileOutStream : FileOutputStream = openFileOutput(filename,Context.MODE_PRIVATE)
try {
fileOutStream.write(HEADER.toByteArray())
fileOutStream.close()
}catch(e: Exception){
Log.i("TAG", e.toString())
}
It doesn't throw the exception, but I cannot find the file in the file system. I'm using a physical tablet for testing/debug. I've checked the com.... folder for my app.
I cannot find the file in the file system
Use Android Studio's Device File Explorer and look in /data/data/.../files/, where ... is your application ID.
Also, you can write your code a bit more concisely as:
try {
PrintWriter(openFileOutput(filename,Context.MODE_PRIVATE)).use {
it.println(HEADER)
}
} catch(e: Exception) {
Log.e("TAG", e.toString())
}
use() will automatically close the PrintWriter, and PrintWriter gives you a more natural API for writing out text.
It appears there are many ways to create a file and append to it, depending on the minimum API version you are developing for. I am using minimum Android API 22. The code to create/append a file is below:
val HEADER = "DATE,NAME,AMOUNT_DUE,AMOUNT_PAID"
var filename = "export.csv"
var path = getExternalFilesDir(null) //get file directory for this package
//(Android/data/.../files | ... is your app package)
//create fileOut object
var fileOut = File(path, filename)
//delete any file object with path and filename that already exists
fileOut.delete()
//create a new file
fileOut.createNewFile()
//append the header and a newline
fileOut.appendText(HEADER)
fileOut.appendText("\n")
/*
write other data to file
*/
openFileOutput() creates a private file, likely inside of app storage. These files are not browsable by default. If you want to create a file that can be browsed to, you'll need the WRITE_EXTERNAL_STORAGE permission, and will want to create files into a directory such as is provided by getExternalFilesDir()
I'm trying to retrieve the file that the user wants to share via, for example, the Photo Gallery App. So, when they tap on the share button, and select my application, I'm retrieving the File's Uri through the method Uri fileUri = (Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM);. This works fine.
Then, I try to get the File whose Uri is the one I have. I do that this way:
File file = new File(fileUri.getPath());
But, afterwards, when I try to open it and read it, I get the java.io.FileNotFoundException ENOENT (No such file or directory). Furthermore, when I execute the file.exists() method, it returns false. So I don't know where the problem is.
Here is the code:
Uri fileUri = (Uri) getIntent().getExtras().get(Intent.EXTRA_STREAM);
File file = new File(fileUri.getPath());
FileInputStream imageInFile = new FileInputStream(file);
What am I doing wrong?
EDIT:
I already have the <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> tag in my manifest.
I must also add that the uri of the file which I retrieve is something like: "/0/1/content:/media/external/images/media/9412/ACTUAL/1989334571". As you can see, the file doesn't have any extension at all, so that might be the problem. Nevertheless, I don't know how to solve it.
EDIT 2:
It seems as it is a problem that started since KitKat...
I'm writing an airplane simulator program and want the user to be able create model files seperately using XML. Then, in the app they can select which model (XML file) to load. I have the XML files in a subdirectory on my SD card and can read it with my BLU phone but not my Motorola Photon II. With the Motorola I get a file not found when initializing the input stream. I have the following code...
In the Manifest I have set read external storage permission...
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Here's the code to open the XML file...
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/SimFiles/Vehicles/" + "myModel.xml");
InputStream in = new BufferedInputStream(new FileInputStream(file));
It's pretty straight forward. So, why on one and not the other? Is it a permissions thing- one more strict than the other? Thanks.
Try using this...
File file = new File(Environment.getExternalStorageDirectory() + "/SimFiles/Vehicles/" + "myModel.xml");
InputStream in = new BufferedInputStream(new FileInputStream(file));
In Android, I want to create a pointer that points to already existing file by way of its filepath.
For example, my pseudo-code:
String path = "file/directory/filename";
File ptr = File's pointed to by the path
The Android documentation only provides methods with which one can create a new file through a file path, but I just want a File object that only points to an already existing File.
How do I do that?
Use:
String path = "file/directory/filename";
File ptr = new File(path);
// check If file exists.
if(ptr.exists()) {
// Your code Here if file exists
}
File f = new File(path);
f points to a virtual file , if the file doesnt exist, writing anything to it, will either create it or cause a system crash , depending on the type of content you are writing to it.
deleting a file that doesnt exist will also fail, so any operation with files must be encapsulated with try catch for IOException
see http://developer.android.com/reference/java/io/File.html
also on android's new Kitkat you explicity have to request the permission to READ_EXTRANL_STORAGE if you want to read, and WRITE_EXTERNAL_STORAGE if you want to write
I have a routed device and when I do this
adb shell cat /data/misc/bluetooth/dynamic_auto_pairing.conf
it prints the content of this file.
But in my code when I write something like this, it says that the file does not exist. Well from the console I see it I know is there, but from code I can't read it. My question is what is the problem , am I missing some permission or what is the problem ? can someone provide me with some code to read the content from this file.
Thanks
File pa = new File("/data/misc/bluetooth/","dynamic_auto_pairing.conf");
//this doesn't works also
//File pa = new File("/data/misc/bluetooth","dynamic_auto_pairing.conf");
//File pa = new File("/data/misc/bluetooth/dynamic_auto_pairing.conf");
if(pa.exists()){
Log.v("tag", "does exists");
}else{
Log.v("tag", "does NOT exist");
}
If the file is on sdcard, try:
File pa = new File(Environment.getExternalStorageDirectory() + "/data/misc/bluetooth/dynamic_auto_pairing.conf");
Also try to add:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
outside <application></application> in your manifest file.
EDIT
If the file is in internal memory: Your app can read only from a special folder in internal memory. The path to that folder is returned by:
getFilesDir().getAbsolutePath()
So put the file there and read it with openFileInput().
More info:
http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
From the docs for File...
public File (String dirPath, String name)
Constructs a new File using the specified directory path and file name, placing a path separator between the two.
In your code you are using...
File pa = new File("/data/misc/bluetooth/","dynamic_auto_pairing.conf");
...and because your dirPath ends with a separator "/data/misc/bluetooth/" it will result in two separators. In other words, effective path will be...
/data/misc/bluetooth//dynamic_auto_pairing.conf
Note the // after 'bluetooth`
If you are using android 6.0 or higher. You must request permission in code.