I want to store data on external storage and Environment.getExternalStorageDirectory() returns /storage/emulated/0/
path and and when i store data on that directory it store data on storage/sdcard0/... and on /storage/emulated/0/
I need to store a great numbers of images on external storage
How could i implement that?How could i get path on external storage?
How could I get path on external storage?
/storage/emulated/0/ and storage/sdcard0/ is basically the same, this is just an alias. On devices like the Nexus 5 and any other device that doesn't have a physical SD card, "external storage" means the device built-in storage which emulates an SD card. Environment.getExternalStorageDirectory() will point to this location so you are good to go using this method.
From the docs:
Note: don't be confused by the word "external" here. This directory
can better be thought as media/shared storage. It is a filesystem that
can hold a relatively large amount of data and that is shared across
all applications (does not enforce permissions). Traditionally this is
an SD card, but it may also be implemented as built-in storage in a
device that is distinct from the protected internal storage and can be
mounted as a filesystem on a computer.
First of all find of path of external storage
String path = Environment.getExternalStorageDirectory().toString() + directoryName;
then you can write whatever content you want to the file as follows:
File file = new File(path, fileName);
BufferedWriter br;
try {
br = new BufferedWriter(new FileWriter(file));
br.write(content);
br.close();
} catch (IOException e) {
e.printStackTrace();
}
Related
I have created an android app that gets input from user through EditText and writes them to name.txt file in phone's internal storage. Is it possible to open the text file in phone's file manager? I tried to get the file path using getFilesDir().getAbsolutePath()+"/"+FILE_NAME. But couldn't locate the file in file manager.
You need to use External storage if you want another app like File Manager to access the file. Internal storage is only readable by your app.
In the comments you ask a valid question - "What if the phone doesnt have external storage...?". That is not really a concern today. See https://developer.android.com/training/data-storage/files:
Many devices now divide the permanent storage space into separate
"internal" and "external" partitions. So even without a removable
storage medium, these two storage spaces always exist...
==========
So change your above code to this:
getExternalFilesDir().getAbsolutePath()+"/"+FILE_NAME
getExternalFilesDir is a method from the android.content.Context class. So this call will work from your activity class which is a Context.
=============
Further supporting the choice of external storage is the following, also from https://developer.android.com/training/data-storage/files.
Internal storage is best when you want to be sure that neither the
user nor other apps can access your files.
External storage is the best place for files that don't require access
restrictions and for files that you want to share with other apps or
allow the user to access with a computer.
there is private storage for each app that can be accessed from the app itself and then public storage /sdcard/... that other app can access too (it needs to get Storage Permission from system)
this method will save a content in a file in private storage of app
public void saveFile(String fileName, String content) {
try {
FileOutputStream fOut = context.openFileOutput(fileName, Context.MODE_PRIVATE);
fOut.write((content).getBytes());
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
So I am aware that there is SD Card access API which allows us to write files via DocumentProvider and DocumentFiles. I have made it work on removable SD Cards. I was always confused about External and Internal Storage. I always thought External Storage is Always SD card but today I came to know that it is not so.
So I have three question .
Question1 , how to know if Files are stored in external emulated storage or sdcard ?
One solution maybe by searching for instances of "sdcard0" or "emulated" in the file path.
Will this solution always work? I mean on all phones?
Question 2 what to Use for writing files on emulated storage(non removable external storage) normal files or DocumentFile?
Question 3 If solution of Q2 is Document File then why doesn't this work ?
private static String[] getExtSdCardPaths() {
List paths = new ArrayList<>();
for (File file : GlobalSongList.GetInstance().getApplicationContext().getExternalFilesDirs("external")) {
if (file != null && !file.equals(GlobalSongList.GetInstance().getApplicationContext().getExternalFilesDir("external"))) {
int index = file.getAbsolutePath().lastIndexOf("/Android/data");
if (index < 0) {
Log.w("StorageAccessAPI", "Unexpected external file dir: " + file.getAbsolutePath());
}
else {
String path = file.getAbsolutePath().substring(0, index);
try {
path = new File(path).getCanonicalPath();
}
catch (IOException e) {
// Keep non-canonical path.
}
paths.add(path);
}
}
}
return paths.toArray(new String[paths.size()]);
}
So I am aware that there is SD Card access API which allows us to write files via DocumentProvider and DocumentFiles.
You are referring to the Storage Access Framework. This allows you to read and write streams, not files, where the streams are backed by document providers. The user chooses what document provider to use, which in turn determines where the stream's content is stored. That could be local (e.g., external storage, removable storage) or remote (Google Drive, Dropbox, Samba file server, Web server, FTP server, SFTP server, etc.).
how to know if Files are stored in external emulated storage or sdcard ?
If you are using the Storage Access Framework, you do not know where the stream's content is stored.
what to Use for writing files on emulated storage(non removable external storage) normal files or DocumentFile?
If you explicitly want to use external storage, use external storage.
Using the Storage Access Framework allows the user to choose where the stream's content is stored, which may or may not be external storage.
why doesn't this work ?
I have no idea what you expect that to do. I expect it to return a series of useless strings.
If I have paths like following:
/storage/emulated/0/...
/storage/UsbDriveA/...
/sdcard/...
I basically have following questions:
How do I find out which storage they are located on? (USB stick, external storage, internal storage)
How do I find out which type they are? (primary storage (I have direct r/w access), secondary storage (on android >=4.4, I don't have direct w access and I need to acquire this right through the Storage Access Framework if I need it))
How do I find out what the ROOT path is?
Results that I want
This is: internal storage, primary storage, root path is /storage/emulated/0/
This is: USB Stick, secondary storage, root path is /storage/UsbDriveA/
This is: external storage, secondary storage, root path is /sdcard/
I know the paths may vary from phone to phone, so how do I find out which path is located on which storage and which permissions I do have on which paths? I know I can guess by the names of the path, but I'm interested in a reliable way that works on all (or at least on most) phones...
You need to check access for every primary and secondary storage through Environment class. You should do something like this:
Boolean canWrite = Environment.getExternalStorageDirectory().canWrite(); if(canWrite)// do something with externalstorage
and use Environment.getRootDirectory() for internal root
for USB you need to check it with
public static boolean isConnected(Context context) {
intent = context.registerReceiver(null, new IntentFilter("android.hardware.usb.action.USB_STATE"));
return intent.getExtras().getBoolean("connected");
}
I'm downloading some text data by issuing a HTTP GET request to server. I want to save downloaded text file to re-use it on request if it has already been downloaded. But I want to keep my data private, so that no other apps could access it. On the other hand, it would be OK if Android removed that files if there's not enough disk space.
So, my question is - should I store downloaded content in App Data folder or in cache folder? Is there any difference between two?
First, I used to save files in App Data folder, using a method like
public void save(String fileName, String data) {
FileOutputStream fos;
try {
fos = mContext.openFileOutput(fileName, Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Using this method I can set Private mode for my files so that no other apps could access them. But then I thought about moving files to cache directory, I need to do something like
private void save(String filename, String data) {
File cacheDir = new File(mContext.getCacheDir(), "app_directory");
cacheDir.mkdir();
try {
FileOutputStream fos = new FileOutputStream(new File(cacheDir, filename));
fos.write(data.getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I cannot set Private attribute to my files anymore, so, as I understand, any application will be able to get access to my data. Am I right?
Maybe there's a way to make files in cache directory private? Or it doesn't really matter where to save files to?
Both the CacheDir and the FilesDir are app specific, and can not be accessed by any other app.
Both of these however can be accessed if the user has rooted their device.
The CacheDir is for temp files, that may be deleted if so required to free up space by Android OS. The Files dir will not be cleared unless explicitly done so by the app, the user, or if the app is uninstalled.
This is covered in the docs:
http://developer.android.com/guide/topics/data/data-storage.html
Saving cache files
If you'd like to cache some data, rather than store it persistently,
you should use getCacheDir() to open a File that represents the
internal directory where your application should save temporary cache
files.
When the device is low on internal storage space, Android may delete
these cache files to recover space. However, you should not rely on
the system to clean up these files for you. You should always maintain
the cache files yourself and stay within a reasonable limit of space
consumed, such as 1MB. When the user uninstalls your application,
these files are removed.
Data in the cache can only be accessed your app (if its not rooted, but thats a user choice to minimze security)
I have read so many theories about saving a file to the internal storage and external storage that I don't know exactly any more what to do.
I created a PDF file with droidtext that I want to e-mail as an attachment in the chosen e-mail app.
This is no problem. I succeeded in this, however... I only can do it with the external storage.
So, I create a PDF, put it in the external storage with Environment.getExternalStorageDirectory().getAbsolutePath().
However, if no external storage is available I want to save the PDF on the internal storage.
I did it like this so far:
External (working perfectly):
pdf = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + java.io.File.separator + fileName);
PdfWriter.getInstance(document, new FileOutputStream(pdf));
Internal storage:
pdf = new File(fileName);
PdfWriter.getInstance(document, openFileOutput(fileName, MODE_PRIVATE));
With both having Document document = new Document();.
The Internal memory method delivers no error whatsoever, but I am not sure if the file is saved internally.
Also, I think that because it is saved internally, the mail app will not be able to select it as an attachment.
I can't test this because my emulator has no mail app. Nor can I go through the content on the device. Nor do I own a device that has no external storage...
What is the best way to solve this? Force users to have external storage or are there other ways to solve this?
"What is the best way to solve this? Force users to have external storage or are there other ways to solve this?"...I'm not certain, but I think you have no choice but to force users to have external storage to be able to email an attachment.
You can't use MODE_PRIVATE to save to internal storage or the email app won't be able to access the file. You'll have to use MODE_WORLD_READABLE.
To get the directory of where the file is stored use Context.getFilesDir() (http://developer.android.com/reference/android/content/Context.html#getFilesDir%28%29)
You can also just install an email app on the emulator to test this. Just download an apk and install it via adb.