I am trying to develop a program which creates a file in a specific directory (.txt file) and stores some data in it (Strings for example). I also want that the file can be accessed by the user (If I go to file explorer I can view the file I've created and maybe edit it with another program or something).
I've tried many things, but I cant manage this to work.
Here is the code I am using atm:
public void createFile(View view) throws IOException {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd");
Date now = new Date();
String fileName = formatter.format(now) + ".txt";
String filepath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Sonda Drive Test";
File mypath = new File(filepath);
if(!mypath.exists()) {
mypath.mkdir();
}
//now the mkdir returns true isntead of false
File myfile = new File(mypath, fileName);
try{
if(!myfile.exists()){
txtDebug.setText("Não existe ficheiro!");
myfile.createNewFile();
}
else{
txtDebug.setText("Já existe ficheiro!");
}
}catch (Exception e){
txtDebug.setText("Erro!");
}
}
I've also added the permissions bellow:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
The problem is that when I do
myfile.createNewFile();
The application stops and closes.. But if I comment that line, it also won't create any file...
What am I doing wrong?
EDIT: I Manage to make this work for API 22. How can i do it for API 25?
you are putting the mypath as the path but you define the mypath as file
i need to save an image from camera on android.
i used the write external storage permission in manifest and i am using this code
File dir = new File(Environment.getExternalStorageDirectory(), "Test");
if (!dir.exists() || !dir.isDirectory())
dir.mkdirs();
String path = dir.getAbsolutePath();
Log.d(TAG, path); //log show the path
File file = new File(dir.getAbsolutePath() + "/Pic.jpg");
Log.d(TAG, file.getAbsolutePath()); //again path is shown here
outStream = new FileOutputStream(file);
outStream.write(bytes);
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + bytes.length); //fail here
} catch (FileNotFoundException e) {
Log.d(TAG, "not done"); //error is here (this exception is thrown)
} catch (IOException e) {
Log.d(TAG, "not");
} finally { }
i also tried mkdir() instead of mkdirs() same result.
any idea what went wrong in the code?
thanks
For those not as experienced like me. I fought this issue, lost hair for some time. I am targeting api 21 (for compatibility sake) and it worked on lollipop but on marshmallow it would not create the directory. I did have the "uses" permission in the manifest but it still would not work. Apparently in Marshmallow when you install with Android studio it never asks you if you should give it permission it just quietly fails, like you denied it. You must go into Settings, apps, select your application and flip the permission switch on.
Some one like me who was trying in Android10. Please use below API in manifest:
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
Latest Update From Google:
After you update your app to target Android 11, the system ignores the requestLegacyExternalStorage flag.
Did you put
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in your AndroidManifest? If you are using android M you must request user permission to write on sd, look here an example
IDIOT ME! i have used the Manifest Permission but when installed the app on phone i didnt grant permission for storage!... i understand a negative on this question... but i hope if someone else face the same..check your phone permission. sorry all for inconvenience.
you have created directory, not file. Create new file with following code
File file = new File(dir.getAbsolutePath() + "/Pic.jpg");
file.createNewFile()
if you are testing on android M, you should probably check Settings > App > Permission to see if permission to access storage is granted. This saved me.
if you already allowed R/W permission(Runtime Permission too) and still doesn't work add this below mentioned line in your AndroidManifest.xml
<application
........
........
android:requestLegacyExternalStorage="true">
Note: this must required if you'r targeting Android 10+
Starting from API 30 you can only write in your app-specific files
File dir = new File(context.getFilesDir(), "YOUR_DIR");
dir.mkdirs();
or in the external storage of your app Android/data
File dir = new File(myContext.getExternalFilesDir("FolderName"),"YOUR_DIR");
UPDATE
this answer provided another solution https://stackoverflow.com/a/65744517/8195076
UPDATE
another way is to grant this permission in manifest
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
like this answer https://stackoverflow.com/a/66968986/8195076
Try this. Provide runtime permission for marshmallow it is perfectly work in my Application code :
private String getFilename(String strFileName) {
String filepath = Environment.getExternalStorageDirectory().getPath();
File fileBase = new File(filepath, "Test");
if (!fileBase.exists()) {
fileBase.mkdirs();
}
return (file.getAbsolutePath() + "/" + strFileName + file_exts[currentFormat]);
}
new File(getFilename(edt.getText().toString().trim()))
outputFile = new File(apkStorage + "/" + downloadFileName );
//Create Output file in Main File
//Create New File if not present
if (!outputFile.exists()) {
isExternalStorageWritable();
outputFile.getParentFile().mkdirs();
outputFile.createNewFile();
Log.e(TAG, "File Created");
OutputStream fos = new FileOutputStream(outputFile);//Get OutputStream for NewFile Location
InputStream fis = c.getInputStream();//Get InputStream for connection
byte[] buffer = new byte[1024];//Set buffer type
int len1 = 0;//init length
while ((len1 = fis.read(buffer)) >0) {
fos.write(buffer, 0, len1);//Write new file
}
//Close all connection after doing task
fos.close();
fis.close();
I wrote this code for creating a file, but it is not working in android 11
when writing code for android API 29 and above use the following permission in your application manifest (AndroidManifest.xml)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
Adjust your code to read like the following
ActivityCompat.requestPermissions(this, new String[]
{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},
PackageManager.PERMISSION_GRANTED);
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
file = new File(Environment.getExternalStorageDirectory().getPath(), "TestDirectory/Document/");
if (!file.exists()) {
try {
file.mkdirs();
} catch (Exception e) {
e.printStackTrace();
}
}
I'm currently using this code to store a file in Android:
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/invoices";
File file = new File(dir, "Invoice.pdf");
This works perfectly fine in Genymotion emulator because ? but when I deploy the app to an Android phone, it doesn't work.
Can anyone explain why this maybe, or hint me to the right direction please, thanks in advance.
Add Permission in manifest file <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And Try This to Save File/Image
You should post all you did because from your code nobody can understand what you are exactly doing. However, take a look at the following links:
1. http://codetheory.in/android-saving-files-on-internal-and-external-storage/.
At the link mentioned above it explains you how to save in both internal and external SDcard.
2. http://developer.android.com/training/basics/data-storage/files.html.
Second link is from Google and it is a small brief about what you should do.
In all the cases don't forget about the permissions.
EDIT:
Below I attached a piece of code that it can help you:
public static File getNewFile(String fileName) throws IOException {
File file = null;
if (name == null) {
name = "temp_folder";
}
if (getInternalFilesDir() == null || !getInternalFilesDir().isDirectory()) {
file = null;
} else {
file = new File(getInternalFilesDir() + File.separator + TEMP_FOLDER + File.separator + fileName);
if (file.getParentFile() != null && ! file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
if (file exists()) {
file.delete();
}
file.createNewFile();
if (! file.exists()) {
throw new IOException("Unable to create file " + name);
}
}
return file;
}
getInternalFilesDir is exactly that:
Save files in internal directory
//in the manifest now:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
other stuff
</manifest>
i have a very small problem. I am writing a file to sdcard. I'l show you two code, one code works and other doesn't. It looks like this:
First one,
new FileOutputStream("/sdcard/HelloWorld.txt")
This works fine and creates a HelloWorld.txt file in sdcard.
Now second one,
new FileOutputStream(android.os.Environment.getExternalStorageDirectory()+java.io.File.separator + "filetest" + java.io.File.separator + "HelloWorld.txt")
This throws error "/mnt/sdcard/filetest/HelloWorld.txt (No such file or directory)".
I want to know why because i have mnt/sdcard path on my device, is it that it cannot find filetest folder if yes then isn't it supposed to create filetest folder if its not created before.
Thanks.
First Make a directory of filetest if its not available,
File file = new File(android.os.Environment.getExternalStorageDirectory()+java.io.File.separator + "filetest");
file.mkdir();
Then execute your code...
OR
File f = new File(android.os.Environment.getExternalStorageDirectory()+java.io.File.separator + "filetest" + java.io.File.separator + "HelloWorld.txt");
if (!f.getParentFile().exists());
{
f.getParentFile().mkdir();
}
Yes........ filetest folder are not there so you need to create it manually or programatically.and try that code...so you get success.
you can also create dir like this ::
File wallpaperDirectory = new File("/sdcard/filetest/");
// have the object build the directory structure, if needed.
wallpaperDirectory.mkdirs();
// create a File object for the output file
File outputFile = new File(wallpaperDirectory, filename);
// now attach the OutputStream to the file object, instead of a String representation
FileOutputStream fos = new FileOutputStream(outputFile);
Use Permission :::
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I am using setReadOnly method to make my app's directory stored on my SD card 'Read-only'. However this method when called is returning 'false' even though I have provided the app with android.permission.WRITE_EXTERNAL_STORAGE permission in the manifest.
Here's my code :
is.close();
fos.close();
Decompress d = new Decompress(productDirectory + "/downloadedfile.zip", productDirectory + "/unzipped/");
d.unzip();
File zipfile = new File(productDirectory + "/downloadedfile.zip");
zipfile.delete();
productDirectory = new File(Environment.getExternalStorageDirectory().toString() + "/zipfiledemo");
boolean isWriteLocked = productDirectory.setReadOnly();
Log.v("Writing access locked",">>>>>>>>>>>>>>>>>>>" + isWriteLocked);
You should define permission android.permission.MOUNT_UNMOUNT_FILESYSTEMS in AndroidManifest.xml, it means you can create file and delete file on the SDCard.