I have a very specific issue - I am trying to write to external storage on an Asus Nexus 7, but it is writing to the emulated directory on the device.
Here is the code I am using:
public static void writeExternalMedia(Context context) {
if(isExternalStorageWritable()) {
String content = "hello world";
File filedir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/test");
filedir.mkdir();
File file;
FileOutputStream outputStream;
try {
file = new File(filedir, "test.txt");
if (!file.exists()) {
file.createNewFile();
}
outputStream = new FileOutputStream(file);
outputStream.write(content.getBytes());
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Whenever I restart the device, the directories appear under the device when plugged in, which is what I would expect to happen when the function above gets executed.
I have tried searching for a solution and cannot find the answer to my question.
I made two methods. One for creating a file and one for appending to it. I think the issue is that you're not calling createNewFile.
private File CreateFile(String fileName)
{
File file = new File(this.getFilesDir(), fileName);
try
{
if(!file.exists())
{
file.createNewFile();
}
}
catch (IOException e)
{
e.printStackTrace();
}
return file;
}
private void appendToFile(String file, String content)
{
try
{
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(this.openFileOutput(file, this.MODE_APPEND));
outputStreamWriter.append(content + "\n");
outputStreamWriter.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
Alright after much searching and testing I finally came across a solution, linked via one of the other answers.
https://stackoverflow.com/a/28448843/979220
The solution was to scan the media files, which causes the files to propagate to the external storage, rather than staying in the emulated storage.
Related
I searched and tried a lot before asking this.
But all the code that I'm trying is not working.
I want the file to be stored in the download folder and be accessible from the user also if he uninstalls the app.
I also tried using opencsv library. Could you provide a tested way to create a csv or txt file and store to download folder?
Save to to publicDir(Downloads folder) you first need permission.WRITE_EXTERNAL_STORAGE
check docs
Note this won't work without permmissions
private void saveData(){
String csv_data = "";/// your csv data as string;
File root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
//if you want to create a sub-dir
root = new File(root, "SubDir");
root.mkdir();
// select the name for your file
root = new File(root , "my_csv.csv");
try {
FileOutputStream fout = new FileOutputStream(root);
fout.write(csv_data.getBytes());
fout.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
boolean bool = false;
try {
// try to create the file
bool = root.createNewFile();
} catch (IOException ex) {
ex.printStackTrace();
}
if (bool){
// call the method again
saveData()
}else {
throw new IllegalStateException("Failed to create image file");
}
} catch (IOException e) {
e.printStackTrace();
}
}
I want to save a file to app-specific storage, like shown in documentation:
String filename = "myfile.txt";
String fileContents = "Hello world!";
try (FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE)) {
fos.write(fileContents.toByteArray());
}
Unfortunately, every time I restart the application all data are lost.
How to prevent data from being deleted?
Please note I am not interested in using SharedPreferences/External Storage/Database. Android Studio 3.5.3.
You need to close the file once you are done using it. Otherwise it is not stored to the disk, but only to the memory.
That's why when you "shut down" the app, and start over, it's not there anymore.
FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE);
try {
fos.write(fileContents.toByteArray());
} catch (IOException e) {
e.printStackTrace();
} finally{
try{
if (fos!=null){
fos.flush();
fos.close();
}
} catch( Exception e) {
e.printStackTrace();
}
}
I a newbie in android development.
I sure that many people have same issue. I ve a Galaxy S7 phone without SD Card. So no external storage. But i want create file with my app which have to be access from windows explorer to export it.
Note : debbug in USB mode - No virtual device
Of course in my manifest file i ve setted those 2 permissions :
android.permission.WRITE_INTERNAL_STORAGE
android.permission.WRITE_EXTERNAL_STORAGE
To be sure i ve created a file i use this write method and the following read method :
File root = this.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
File customFolder = new File(root.getAbsolutePath() + "/CustomFolder");
customFolder.mkdirs();
file = new File(customFolder, "myData.txt");
// Must catch FileNotFoundException and IOException
try {
FileOutputStream f = new FileOutputStream(file);
PrintWriter pw = new PrintWriter(f);
pw.println("Howdy do to you,");
pw.println("and the horse you rode in on.");
pw.flush();
pw.close();
f.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.i(TAG, "File not found");
} catch (IOException e) {
e.printStackTrace();
Log.i(TAG, "I/O exception");
}
To read myData.txt
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while (true) {
line= br.readLine();
if (line== null) break;
tv.append("\n" + " " + line);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
So all method are OK, but when i browse my files system to get the created file myData.txt, I can't find it !!
Most of the apps we install have their own folder on the root, like Snapchat, Whatsapp etc etc
I d like to make the same thing, what is the way to write file in:
ROOT --> MyApplicationName --> CustomFolder
Thanks for your help :)
I finally found a solution adding a MediaScannerConnection.scanFile() method.
MediaScannerConnection.scanFile(getApplicationContext(),new String[]{file.getAbsolutePath()},null,new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
// Do something here if you want
}});
But this solution don't totally fit me, because the storage folder is :
Android/data/donain_name/files/Documents/CustomFolder
I'd like to have same result like whatsapp application which can have a folder in the internal storage root.
The result i want is :
MyApplication/CustomeFolder
I'm doing a simple app in Android and in a certain part of the app I would like to create an Excel file and write in it. I've already prepared everything to use jexcel library to edit an excel using Java, but the thing is I can't find the Excel file I created. I've tried to find it in my own device executing the app, but I couldn't.
String fileName = "hours.xls";
File file = new File(getApplicationContext().getFilesDir() + fileName);
Can anybody help me please?
Thanks in advance :)
On Android KitKat, it returns /data/data/{your package name}/files, however I imagine this could change depending on your platform version. Thus if you're just trying to dig through your filesystem and see a file, it's safe to use this path, but if you're using this path for some functionality across multiple platform versions, you should only reference it using getFilesDir().
What are you planning on using this file for? Do you want it usable by other apps too? Using getApplicationContext().getFilesDir() will give you /data/data/com.package/files but if you want a file that's easily accessible by yourself and other apps, you're better off using something like getExternalFilesDir()
If you want to access your file via your PC (with an usb cable) or via a file manager on your device, prefer:
new File(getExternalFilesDir(null), fileName);
This folder is created in .../Android/data/ ... com.yoursociety.yourapp/files ...
null means that you do not want to store files in predefined folders like Movies, Pictures and so on.
(See documentation for more info)
This worked:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
b = (Brain)load("brain.txt");
if (b == null) {
b = new Brain();
}
vocabulary = (ArrayList <String>) load("vocabulary.txt");
if (vocabulary == null) {
vocabulary = new ArrayList <String> ();
vocabulary.add("I love you.");
vocabulary.add("Hi!");
}
b.setRunning(true);
}
public Object load(String fileName) {
File file = new File("/storage/emulated/0/Android/data/com.cobalttechnology.myfirstapplication/files/" + fileName);
if (!file.exists()) {
return null;
}
try {
Object o;
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
o = ois.readObject();
if (o == null) {
System.out.println(fileName + " = null");
}
ois.close();
fis.close();
System.out.println("Loaded: " + fileName);
return o;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
return null;
}
public void save(Object o, String fileName) {
File file = new File("/storage/emulated/0/Android/data/com.cobalttechnology.myfirstapplication/files/" + fileName);
try {
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(o);
oos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Read the documentation, this method reads the files stored in the internal storage that were created with
with openFileOutput():
getFilesDir()
Returns the absolute path to the directory on the filesystem where
files created with openFileOutput(String, int) are stored.
This is how I create the file:
File directory = null;
File file = null;
try {
directory = new File(this.getExternalFilesDir(null));
} catch (Exception ex) {
ex.printStackTrace();
if (!directory.exists()) {
directory.mkdirs();
}
}
file = new File(directory, "user_data.json");
if (!file.exists()) {
try {
file.getParentFile().mkdirs();
file.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
}
and then this file appears in:
Android/data/com.mypackage.asd/files/user_data.json
but later on when I need it, using this code:
FileInputStream fis = null;
try {
fis = context.openFileInput("user_data.json");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
I get a NullPointerException and I see that the system looks for the file in
data/data/com.mypackage.asd/files/user_data.json
Why does it replace "Android" with "data" in the path?
In the first case, you are using getExternalFilesDir().
In the second case, you are using openFileInput().
Those are not pointing to the same place.
If you want your file to be placed onto external storage, use getExternalFilesDir() everywhere.
If you want your file to be placed onto internal storage, use getFilesDir() and/or openFileInput().