Unable to create external file - EACCES (permission denied) - android

When trying to create a simple .txt or .xml external file (NOT on SD card), my app is throwing a FileNotFoundException. If I let the system pick the path (returns /storage/emulated/legacy) it throws EACCES (permission denied). Same as when I set the path manually to "/android/data" (returns /storage/emulated/0/android/data) or "/download" (returns /storage/emulated/0/Download) - both throw EACCES. If I set path to "/document" it throws ENOENT (no such file or directory).
As see below in my code, I do a check before to make sure that external storage is available and not read-only.
I ran this on 2 devices, running 4.4.2 and 4.4.4
I also added
"android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
in the manifest as suggested in SO answers to try and force the device to use it's own file system and not the PC's when running app through USB, but it seems to keep giving me a path derived from /emulated/
I try debugging from the device itself using the developer options and thus eliminating the possibility of the app accessing the PC's storage, but the debugger on the device just hangs trying to attach.
Of course I have as well:
"android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18"
This is very frustrating as there are some similar questions on SO but with very accepted answers.
public static File getExternalStorageDirectory() {
Log.i("EXTERNAL STORAGE DIR", EXTERNAL_STORAGE_DIRECTORY.toString());
return EXTERNAL_STORAGE_DIRECTORY;
}
public static final File EXTERNAL_STORAGE_DIRECTORY = getDirectory("EXTERNAL_STORAGE", "android/data");
public static File getDirectory(String variableName, String defaultPath) {
String path = System.getenv(variableName);
return path == null ? new File(defaultPath) : new File(path);
}
public boolean isExternalStorageReadOnly() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
return true;
}
return false;
}
public boolean isExternalStorageAvailable() {
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
return true;
}
return false;
}
public void writeToSettingsFile(String name, String value){
// File myDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "/settings.txt");
// File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), fileUrl);
// File myDir = getDirectory("EXTERNAL_STORAGE", "android/data");
// File myDir = getExternalStorageDirectory();
// File myDir = new File("download");
File myDir = new File(Environment.getExternalStorageDirectory() + "/android/data");
if(!myDir.exists()){
myDir.mkdirs();
}
try{
String fname = "settings.txt";
File file = new File (myDir, fname);
FileOutputStream fOut = new FileOutputStream(file);
Toast.makeText(context, "you made it, fOut!!!!", Toast.LENGTH_LONG).show();
props.setProperty(name, value);
props.store(fOut, "Settings Properties");
// props.storeToXML(fOut, "Settings Properties");
fOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.e("WTF", "No file found!");
}
catch (IOException e) {e.printStackTrace();
}
}

I think the problem is in your this line
android:maxSdkVersion="18" .
Cause You are testing on 4.4.2. And this device has api level 19.

Okay this is the solution :
public void writeToSettingsFile(String name, String value){
// File myDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "/settings.txt");
// File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), fileUrl);
// File myDir = getDirectory("EXTERNAL_STORAGE", "android/data");
// File myDir = getExternalStorageDirectory();
// File myDir = new File("download");
File myDir = new File(this.getExternalFilesDir(null), name);
if(!myDir.exists()){
myDir.mkdirs();
}
try{
String fname = "settings.txt";
File file = new File (myDir, fname);
FileOutputStream fOut = new FileOutputStream(file);
fOut.write(value.getBytes());
// props.storeToXML(fOut, "Settings Properties");
fOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.e("WTF", "No file found!");
}
catch (IOException e) {e.printStackTrace();
}
}
Try this method. The problem was you cant get internal directory like this
File myDir = new File(Environment.getExternalStorageDirectory() + "/android/data"); // You don't have the permission to do this
if you want to write on internal storage you can get directory like this
File myDir = new File(this.getExternalFilesDir(null), name);
And you can take a look to For more information about saving files

Related

How can you save an audio file to external storage?

I have created a function to save the audio but don't know how to make it work. Would be nice if anybody would help me out?
private void saveAudio(int sound) {
String root = Environment.getExternalStorageDirectory().toString();
if (checkPermissionwrite()) { // check or ask permission
File myDir = new File(root, "/KangleiPdDrums/Sounds");
if (!myDir.exists()) {
myDir.mkdirs();
}
String fname = "Sound1.mp3";
File file = new File(myDir, fname);
if (file.exists()) {
file.delete();
}
try {
file.createNewFile(); // if file already exists will do nothing
FileOutputStream out = new FileOutputStream(file);
out.write(sound);
out.flush();
out.close();
file.setReadable(true, false);
String pathed = file.getPath();
Toast.makeText(getApplicationContext(), "Saved at " + pathed, Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Let me try to explain this
String root = Environment.getExternalStorageDirectory().toString();
In the root variable, he is getting the root reference of the private external storage.
if (checkPermissionwrite()) { }// check or ask permission
Here even this function is not available in your code but this function will use to take the write permission for the user
File myDir = new File(root, "/KangleiPdDrums/Sounds");
if (!myDir.exists()) {
myDir.mkdirs();
}
Here he is creating a directory or folder at the root folder of your external storage and then he is checking if this directory already exists or not if not then create the directory.
String fname = "Sound1.mp3";
File file = new File(myDir, fname);
if (file.exists()) {
file.delete();
}
Here he storage the file name in the name folder and create the file and after that, he checked if the file already exists then delete this file.
try {
file.createNewFile(); // if file already exists will do nothing
FileOutputStream out = new FileOutputStream(file);
out.write(sound);
out.flush();
out.close();
file.setReadable(true, false);
String pathed = file.getPath();
Toast.makeText(getApplicationContext(), "Saved at " + pathed, Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
Here this code is used to write the file/audio at the directory that he created at the start and I think it's simple
Let me provide a link for the Indian and Pakistani users that understand Hindi or Urdu they can understand it through video as well
https://youtu.be/SZPF9KuPIV8

Android: open failed: ENOENT No such file or directory

I know have many question like my question. But It is different. I copy file from folder A to folder B in EXTERNAL_STORAGE use mothod below:
public static String copyFile(String path) {
String fileToName = String.valueOf(System.currentTimeMillis());
File pathFrom = new File(path);
File pathTo = new File(Environment.getExternalStorageDirectory() + "/.noname");
File file = new File(pathTo, fileToName + ".bak");
while (file.exists()) {
fileToName = String.valueOf(System.currentTimeMillis());
file = new File(pathTo, fileToName + ".bak");
}
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(pathFrom);
out = new FileOutputStream(file);
byte[] data = new byte[in.available()];
in.read(data);
out.write(data);
in.close();
out.close();
} catch (FileNotFoundException e) {
Log.e(TAG, e.getMessage());
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return file.getPath();
}
The path param is: "/storage/emulated/0/Download/image_preview.jpg".
When execute this method I got an error: /storage/emulated/0/Download/tree_leaves_sunlight.jpg: open failed: ENOENT (No such file or directory).
Folder .noname have exists.
Is there any suggestion for my problem?
**UPDATE: This file I opening with ImageView. When I not open I can copy. But When I opening I got this error.
PS: I preview the image inImageView. And there have a Button copy image. When click to Button execute method copy this image to other folder.
When you create the File object for the parent directory
File pathTo = new File(Environment.getExternalStorageDirectory() + "/.noname")
Don't forget to actually create this folder
pathTo.mkdirs();
Also try to open file you're trying to copy in the gallery. It can be damaged and Android just can't open it.

How to create files to a specific folder in android application?

In my application, I want to create a text file in the cache folder and first what I do is create a folder in the cache directory.
File myDir = new File(getCacheDir(), "MySecretFolder");
myDir.mkdir();
Then I want to create a text file in that created folder using the following code that doesn't seem to make it there. Instead, the code below creates the text file in the "files" folder that is in the same directory as the "cache" folder.
FileOutputStream fOut = null;
try {
fOut = openFileOutput("secret.txt",MODE_PRIVATE);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String str = "data";
try {
fOut.write(str.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
SO my question is, how do I properly designate the "MySecretFolder" to make the text file in?
I have tried the following:
"/data/data/com.example.myandroid.cuecards/cache/MySecretFolder", but it crashes my entire app if I try that. How should I properly save the text file in the cache/MySecretFolder?
use getCacheDir(). It returns the absolute path to the application-specific cache directory on the filesystem. Then you can create your directory
File myDir = new File(getCacheDir(), "folder");
myDir.mkdir();
Please try this maybe helps you.
Ok, If you want to create the TextFile in Specific Folder then You can try to below code.
try {
String rootPath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/MyFolder/";
File root = new File(rootPath);
if (!root.exists()) {
root.mkdirs();
}
File f = new File(rootPath + "mttext.txt");
if (f.exists()) {
f.delete();
}
f.createNewFile();
FileOutputStream out = new FileOutputStream(f);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Just change
fOut = openFileOutput("secret.txt",MODE_PRIVATE);
to
fOut = openFileOutput(myDir+"/secret.txt",MODE_PRIVATE);
This will make secret.txt under MySecretFolder
getPrivateDir will create a folder in your private area (Context.MODE_WORLD_WRITEABLE- use what suits you from Context.MODE_...)
public File getPrivateDir(String name)
{
return context.getDir(name, Context.MODE_WORLD_WRITEABLE);
}
openPrivateFileInput will create a file if it doesn't exist in your private folder in files directory and return a FileInputStream :
/data/data/your.packagename/files
Your application private folder is in
/data/data/your.packagename
public FileInputStream openPrivateFileInput(String name) throws FileNotFoundException
{
return context.openFileInput(name);
}
If you package name is uno.due.com your app private folder is:
/data/data/uno.due.com
All directories underneath are weather created by you or by android for you. When you create a file as above it will go under:
/data/data/uno.due.com/files
Simple and easy code to create folder, file and write/append into the file
try {
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/newfoldername/"; // it will return root directory of internal storage
File root = new File(path);
if (!root.exists()) {
root.mkdirs(); // create folder if not exist
}
File file = new File(rootPath + "log.txt");
if (!file.exists()) {
file.createNewFile(); // create file if not exist
}
BufferedWriter buf = new BufferedWriter(new FileWriter(file, true));
buf.append("hi this will write in to file");
buf.newLine(); // pointer will be nextline
buf.close();
}
catch (Exception e) {
e.printStackTrace();
}
NOTE: It needs the Android External Storage Permission so add below line in AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

Unable to write to external SD Card in Android

I am trying to write files in the external SD card folder. Even after having set the required permission in the manifest file, I am unable to write on the external SD card.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Code:
String path = "/mnt/extsd/nit.txt";
File myFile = new File(path);
if (!myFile.exists()) {
try {
myFile.createNewFile();
} catch(Exception e)
{
txtText.setText("Failed-" + e.getMessage());
e.printStackTrace();
}
}
try {
FileOutputStream fostream = new FileOutputStream(myFile);
OutputStreamWriter oswriter = new OutputStreamWriter(fostream);
BufferedWriter bwriter = new BufferedWriter(oswriter);
bwriter.write("Hi welcome ");
bwriter.newLine();
bwriter.close();
oswriter.close();
fostream.close();
txtText.setText("success");
} catch(Exception e)
{
txtText.setText("Failed-" + e.getMessage());
e.printStackTrace();
}
On the other hand when I use ES File Explorer and try to create a file, it creates it without any issues.
Don't use the absolute path String path = "/mnt/extsd/nit.txt"; because you never know about android device being used by users. Rather you can get the external storage directory path by using Environment.getExternalStorageDirectory().toString().
You should be able to call Environment.getExternalStorageDirectory() to get the root path to the SD card and use that to create a FileOutputStream. From there, just use the standard java.io routines.
File log = new File(Environment.getExternalStorageDirectory(), "your_file_name.txt");
try {
out = new BufferedWriter(new FileWriter(log.getAbsolutePath(), false));
out.write("any data");
} catch (Exception e) {
}
And don't forget to close the streams.
First check sd-card is available or not.
String state = Environment.getExternalStorageState();
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
if (Environment.MEDIA_MOUNTED.equals(state))
{
File folder = folder = new File(extStorageDirectory, "FolderName");
if(!folder.exists())
{
folder.mkdir();//making folder
}
File file = new File(folder,"Filename");//making file
}
Please try this code, it work in my application.

Android: Can't find generated XML file

I am working on a method that writes an XML file to the device. I've allowed external storage in the manifest file, but I can't find the file at the location it should be.
Here is my code:
public static void write (){
Serializer serial = new Persister();
File sdcardFile = new File("/Prueba/file.xml");
Item respuestas = new Item();
try {
serial.write(respuestas, sdcardFile);
} catch (Exception e) {
// There is the possibility of error for a number of reasons. Handle this appropriately in your code
e.printStackTrace();
}
Log.i(TAG, "XML Written to File: " + sdcardFile.getAbsolutePath());
}
}
Sdcard File path problem. Here is an exaple that write string in file.xml file.
File myFile = new File("/sdcard/file.xml");
try {
File myFile = new File("/sdcard/file.xml");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter =
new OutputStreamWriter(fOut);
myOutWriter.append("encodedString");
myOutWriter.close();
fOut.close();
} catch (Exception e) {
}
You able to get External Storage name by this way,
String root = Environment.getExternalStorageDirectory().toString();

Categories

Resources