environment.getExternalStorageDirectory() shows path which doesn't even exist - android

When I print the SD Storage path using Environment.getExternalStorageDirectory();, it returns storage/emulated/0
but when I use DDMS to browse SD Storage there is no such directory at all. The available directory is storage/emulated/legacy
Why Environment.getExternalStorageDirectory(); shows path which doesn't even exist ?

The path exists for your app's process.
Android, starting with 4.2, supports multiple accounts per device (originally just for tablets, now for all devices starting with 5.0). Each account gets its own distinct area for internal and external storage. The framework will return paths from methods like getExternalStorageDirectory() that are correct for the current account holder that is running your app. What these locations map to in terms of actual filesystem locations is up to Android, as part of its effort to secure access to storage.

Related

SD Card Location on Android

I'm using Bluestacks for testing my app, because I don't have Androids lying around. I'm tring to write a file to the SDCard but can't seem to figure out the path for it. I've tried the following: /mnt/sdcard/ext_sd & /mnt/extSdCard but neither of those worked.
I've tried the following: /mnt/sdcard/ext_sd & /mnt/extSdCard but
neither of those worked.
You should not hardcode paths. Because SD card storage location or path varies from phone to phone. SD card storage location in my phone is /storage/sdcard1
Now coming to your question,
Before API level 19, there was no official API method to store in SD card. But, many could do it using unofficial libraries or APIs.
Officially, one method (getExternalFilesDirs) was introduced in Context class in API level 19 (Android version 4.4 - Kitkat).
File[] getExternalFilesDirs (String type)
It returns absolute paths to application-specific directories on all
shared/external storage devices where the application can place
persistent files it owns. These files are internal to the application,
and not typically visible to the user as media.
That means, it will return paths to both types Storage - Internal memory and Micro SD card. Generally, second returned path would be storage path of micro SD card(but not always). So you need to check it out by executing the code with this method.
Instead of hardcoding paths, you should use this method in your app source code to get the SD card location. Then, write files to that location.
If you want to know more about storage location or paths in Android, please go through my other answer

Android device internal storage full path

I am making AR video playback app.
I want to play video from device storage instead of include it in the app.
In the path field in video texture I should write the path of the internal storage.
I wrote "/storage"emulated/0/Demo.mp4" (video's name is Demo)
It works on the testing device, but when I try running the app on other device it does not work because the path differs (internal path is :/storage/sdcard0)
What is the path should I wrote in the video texture to ensure running the app whatever the device is?
To find locations on internal storage for your app, use getFilesDir(), called on any Context (such as your Activity, to get a File object.
To get a location on external storage unique for your app, use getExternalFilesDir(), called on any Context (such as your Activity, to get a File object.
To get a standard location on external storage for common types of files (e.g., movies), use getExternalStoragePublicDirectory() on Environment.
To get the root of external storage, use getExternalStorageDirectory() on Environment. This, however, is considered sloppy programming nowadays, as it encourages developers to just put files in random locations.
Hardcoding things is not the best way but you could check if the video exists in
/sdcard
/mnt/sdcard
/storage/sdcard0
/storage/emulated/0
/storage/emulated/legacyode
at least those are the most common places for android devices.
Then set the patch programatically instead of using the inspector

Android external storage

After reading Android documentation and Stackoverflow discussion about all storage types,
and after viewing filesystems on a number of android devices, I'm a bit cofused.
Given the following results-
getFilesDir() - returns /data/data..
getExternalFilesDir() - returns /mnt/sdcard/Android/data/<ap_name>/files
getExternalStorageDirectory() - returns /mnt/sdcard/
And given the fact that the file system Windows shows me when I'm connecting my device using USB:
device\Card - contains DCIM, Images (folders) ...
device\Phone - contains WhatsApp, PicArts, Pou (apps folders) ...
And given the fact that when openning My Files app, the path is /sdcard/ and it contains all the apps folder (WhatsApp, PicsArts..),
There are things I do not understand, such as:
How come the Device/Phone contain what /mnt/sdcard/ contains? why isn't it contained in Device/Card?
are those results mean that all those known apps use the external storage as the default storage type for media files?
My intention is to create and maintain a directory in the android file system and to store media files in there.
I want this folder to be placed where all the other apps place their folder , in this case is /sdcard/ as shown in My Files app (or /mnt/sdcard as the full path), but I dont want it to be depend on whether or not the device have an availble external storage.
What should I do?
Few remarks regarding storage :
there is no guaranty that the absolute path for getExternalFilesDir() will be the same on all devices
there is no guaranty that the absolute path for getFilesDir() will be the same on all devices
there is no guaranty that the absolute path for getExternalStorageDirectory() will be the same on all devices
So don't rely on hardcoded absolute path in your code if you need that your app run on different devices.
Every Android device have 2 storage space (mainly for historical reason) : the internal and the external.
Major differences between them :
internal storage :
always available
case sensitive file system
not accessible from a PC connected by USB (for a normal user)
accessible with getFilesDir()
files stored there are private to your app
external storage :
not always available : especially after reboot it takes some time to mount the external storage; or on some devices, when the device is connected to a PC with an USB cable; or when the user has removed the microSD.
case insensitive file system
accessible in windows explorer when connected to a PC
accessible with the api getExternalFilesDir() (to get a directory dedicated to your app) or getExternalStorageDirectory() to get the root of the external storage.
Remark about external storage : today, many vendors use a virtual external storage. i.e. there is no removable sd-card; but instead there is a partition of the internal memory that is mounted as if it was an external storage (so even on those devices the external storage is not available just after a reboot).
I want this folder to be placed where all the other apps place their folder
There is no such place. All the other apps are free to put their data either on the internal storage or on the external storage.
How come the Device/Phone contain what /mnt/sdcard/ contains? why isn't it contained in Device/Card?
Only external storage is visible when your device is USB-connected. The path Device/Phone is choose by the the usb driver (and so not really relevant). The important thing is that under this path you only see the content of root external storage (i.e. the content of the directory returned by getExternalStorageDirectory())
In my Apps I always use:
fileMedia = Environment.getExternalStorageDirectory().getAbsolutePath() + "/yourappdirectoryonsdcard/" + "MediaFileName.3gpp";
File outFile = new File(fileMedia);
if (outFile.exists()) {
outFile.delete();
}
and don't have problems with available external storage detecting.

Why there are two folders sdcard and sdcard2 under /mnt on my android device

When using Eclipse file explorer to navigate my android directories, I saw mnt/sdcard and mnt/sdcard2, see below image:
When callingEnvironment.getExternalStorageDirectory() it returns mnt/sdcard, so I think the mnt/sdcad is the external storage , and mnt/sdcard2 is my actual SD card, is that true? And how can I use code to access files under mnt/sdcard2 ?
P.S.
It seems that I can access the external sd card directly:
File extStorageDir = Environment.getExternalStorageDirectory();
String parent = extStorageDir.getParent();
File extSdCardDir = new File(parent+"/sdcard2");
File file = new File(extSdCardDir, "DemoFile.jpg");
But I wonder the extra sd card will change name in other cases.
You are correct, getExternalStorage will return your built-in external storage. Unfortunately, as of Jelly Bean applications are no longer able to utilize the SD card if the device also has built-in storage as well as an SD card. You can try working around it through shell commands or hardcoding paths, but without root there is no reliable way to access it anymore.
This was just recently added the Android CTS, which all OEMs must comply with in order to use the Play store.
Compatibility Program Overview | Android Developers
Section 9.5 (pg. 34) of Android 4.3 Compatibility Definition
Device implementations that include multiple external storage paths
MUST NOT allow Android applications to write to the secondary external
storage.
Storage Options | Android Developers
It's possible that a device using a partition of the internal storage
for the external storage may also offer an SD card slot. In this case,
the SD card is not part of the external storage and your app cannot
access it (the extra storage is intended only for user-provided media
that the system scans).
Android 4.2 APIs | Android Developers
Saving data in a multi-user environment
Whenever your app saves user preferences, creates a database, or
writes a file to the user’s internal or external storage space, that
data is accessible only while running as that user.
To be certain that your app behaves properly in a multi-user
environment, do not refer to your internal app directory or external
storage location using hard-coded paths and instead always use the
appropriate APIs:
For access to internal storage, use getFilesDir(), getCacheDir(), or openFileOutput().
For access to external storage, use getExternalFilesDir() or getExternalStoragePublicDirectory().
No matter which of these APIs you use to save data for a given user,
the data will not be accessible while running as a different user.
From your app’s point of view, each user is running on a completely
separate device.

Can you write to the sdcard folder when there is no sdcard?

So I'm testing an app on a galaxy s3 on 4.1 and an older phone that runs 2.3. Neither phone has an sdcard in it but when I use Environment.getExternalStorageDirectory().getAbsolutePath() on my galaxy s3 it directs me to a folder called sdcard0 within a folder called storage. When I run it on the older phone it gives me the path mnt/sdcard/ and the sdcard folder is read only.
I am trying to create a folder in these directories. I can do it on my s3 but not on my older phone.
Is there something similar to the storage folder I'm missing on the older phone or can I write to the sdcard folder when there is no sd card present?
EDIT: I have the external write permissions in my manifest
On some phones, as the documentation suggests, the word external is not to be taken all too serious:
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.
You can check if the storage is really external or not, using the Environment.isExternalStorageRemovable()-method. If it's not removable, you should always be able to write to it (given that you have the permissions declared).
If it is however removable, you'll need to check it's current state with Environment.getExternalStorageState(). Here's a quick example of how to use it:
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write!
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// Mounted read only...
} else {
// Something is wrong...
}
So in these cases, you can write to the external storage.
Important: As the documentation specifies at multiple points, the above methods work for the primary external storage. Some devices (like the Motorola Xoom) have both an internal "external" storage, and an SD-Card.
There seems to be no "generalized" way to access the "secondary external storage" on such devices, although there is a standard now, introduced with Android 4.2
Devices may contain multiple instances of external storage, but
currently only the primary external storage is exposed to developers through API.
[...]
Starting in Android 4.2, devices can support multiple users, and
external storage must meet the following constraints:
[...]
Secondary external storage must not be writable by apps.
It seems to depend on the vendor which storage (internal or real external) is considered the primary one. Not much you can do here (without things getting messy...)
If there is no external storage present, you can use your applications Internal Storage, or the caching directory, depending on what kind of data you're storing.

Categories

Resources