5

Please read the whole post before down-voting and/or marking it as a duplicate!

I'm working on an app that reads files from within a specific folder on the user's phone - either from the SD card (if there's one) or from the built in storage. Yes, the "READ_EXTERNAL_STORAGE" is mentioned in the manifest and I'm also handling the permission popup for API>23.

I used to simply use

File folder = new File(Environment.getExternalStorageDirectory(), "myfolder");

to get the path of the folder that is stored in the built in storage (32gb for an S7) but now I want to get the path to the SD card. According to pretty much every result google gave me, "Environment.getExternalStorageDirectory()" is supposed to give you the path to the SD card but for me it doesn't (and never has).

I've tested the following with two different Samsung Galaxy S7s, both with Android 7.0, one with an SD card (+ the folder), the other without (+ the folder):

Log.d(tag, System.getenv("EXTERNAL_STORAGE"));
Log.d(tag, System.getenv("SECONDARY_STORAGE"));
Log.d(tag, ""+new File(System.getenv("EXTERNAL_STORAGE")+File.separator+"myfolder").isDirectory());
Log.e(tag, ""+new File(System.getenv("EXTERNAL_STORAGE")+File.separator+ordner).getAbsolutePath());
Log.d(tag, Environment.isExternalStorageRemovable());
Log.d(tag, Environment.getExternalStorageDirectory());
Log.d(tag, Environment.getExternalStorageDirectory().getAbsolutePath());

To my surprise both phones output the same infos:

/sdcard
null
true
/sdcard/myfolder
false
/storage/emulated/0
/storage/emulated/0

According to the file manager app ("My Files"), the built in storage is called "Internal Storage", which makes even less sense (I know the difference between Internal and External Storage in Android).

How do I get the path to the actual SD card (without hardcoding it)?

Neph
  • 1,823
  • 2
  • 31
  • 69
  • `Environment.getExternalStorageDirectory()` can be used. keep following the parent folder until you find /sdcard/ – FindOutIslamNow May 02 '18 at 10:48
  • Please read the whole post! my first test already gave me "/sdcard" but even though I crated the "myfolder" folder directly inside it using the "My Files" app, the third test failed. – Neph May 02 '18 at 11:06
  • I can see you are using `SECONDARY_STORAGE` to check for your folder, not EXTERNAL_STORAGE – FindOutIslamNow May 02 '18 at 11:09
  • Go up one line. Like I said: Please read the whole post! – Neph May 02 '18 at 11:23
  • `Log.d(""+new File(System.getenv("SECONDARY_STORAGE")+File.separator+"myfolder").isDirectory());` What can u see here, dude? – FindOutIslamNow May 02 '18 at 11:26
  • Really, "dude"? But yes, that was my mistake because using "EXTERNAL_STORAGE" actually results in "true", thanks for the tip. – Neph May 02 '18 at 11:31
  • Never mind, it does return "true" but it also does on the S7 that hasn't got an SD card, so back to square one. :/ – Neph May 02 '18 at 11:37
  • @Neph I gone thr all response you passed to every answer from that I have made below conclusion, 1) You have created folder inside your device SD card with third party application 2) You are getting different address with Env.getexternalstorage() method so you can't decide whether it's right address or not. 3) If that folder exists inside device then want to perform file zip and unzip operation right? – chetan mekha May 02 '18 at 11:38
  • 1) Yes and no, I created the "myfolder" folder with the standard Android "My Files" app (not 3rd party) - I also just tested creating another one through Win 10 and the resulting folder ("myfolder2") showed up on the same level as "myfolder", 2) No, I always get "/storage/emulated/0 " (and always have), 3) Yes, I want to unzip a file within that folder on the SD card, then read the resulting files or just read the files that are already in the folder. – Neph May 02 '18 at 11:44
  • Duplicate of https://stackoverflow.com/questions/5694933/find-an-external-sd-card-location – LarsH Jan 24 '19 at 20:24
  • 1
    @LarsH It's a really similar question, you're right about that but it's 7 years old and about a much older Android version - I asked about Android 7.0, in which accessing files on SD cards works in a completely different way compared to e.g. Android 4.3. – Neph Jan 25 '19 at 09:42

2 Answers2

9

The only way I found is to semi-hardcode it:

File[] folders = myappcontext.getExternalCacheDirs();

gives you the path to the "cache" folders your app has access to (but that are deleted when you uninstall your app).

If the phone uses a removable SD card (that is currently mounted), the length of the array should be "2":

  1. The path to the "cache" folder in the external (not removable) storage
  2. The path to the "cache" folder on your SD card

They look something like this:

/storage/emulated/0/Android/data/com.mycompany.myapp/cache
/storage/xxxx-xxxx/Android/data/com.mycompany.myapp/cache

... where "x" is the number (id?) of your sd card. I've only been able to test it with 2 different SD cards and both had their own number.

Environment.getExternalStorageDirectory();

should also give you

/storage/emulated/0/

which is the non-hardcoding way of getting access to the external storage. ;)

If you create a new folder on the very first level of your SD card on your PC, its path will be:

/storage/xxxx-xxxx/myfolder

I also have to warn you: While you can read the "myfolder" folder, you can't write in it (will just throw an "Access Denied" exception with Android 7) because of the changes to the whole system that came with Kitkat. But that's a different problem I'm going to address in a new question.

Neph
  • 1,823
  • 2
  • 31
  • 69
  • These are good ways (for lack of a better way) of finding the removable SD card. For a more robust approach, across more Android versions and manufacturers, see https://stackoverflow.com/questions/5694933/find-location-of-removable-sd-card/54411385#54411385 – LarsH Jan 29 '19 at 10:23
-1

you have to insert the following permission into your application's manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android" >

   <!-- Add this -->
   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

</manifest>
Badr
  • 2,021
  • 1
  • 21
  • 27
Venki WAR
  • 1,997
  • 4
  • 25
  • 38
  • 1
    Please read the whole post! The permission is already mentioned in my manifest file (including the permission popup in my code), otherwise it wouldn't have worked in the first place before I tried changing it, so it can handle SD cards as well. – Neph May 02 '18 at 11:09