11

I try to write something into my phone memory.

At first, I hard-coded the path as:

myFile = new File("/sdcard/" + txtName.getText() + ".txt");

This works totally ok.

And then, eclipse gives me a warning saying that I shouldn't have hard-coded the path like that instead, I should do the following:

myFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"+ txtName.getText() + ".txt");

Then I follow the correction suggestion and avoid the warning.

However, I encountered a runtime exception on the writer class.

Then, I print out Environment.getExternalStorageDirectory().getAbsolutePath() for debugging purpose. The result is

/storage/sdcard0

. But the hardcoded one that worked perfectly fine before is actually

/sdcard

.

Why would this happen?

And if I wish to avoid the warning, how can I get the path directory in a more "formal and right" way instead of hardcoding the path?

P.S.: My phone is HTC One X, which has NO external SD card slot. I guess the 32GB storage comes with a built-in SD card, and therefore, the essence should be the same.

Sibbs Gambling
  • 19,274
  • 42
  • 103
  • 174
  • check this might help http://stackoverflow.com/questions/15744064/cant-check-if-file-on-sdcard-exists/15744282#comment22381234_15744282 – Raghunandan Jun 20 '13 at 13:55

2 Answers2

16

Why would this happen?

Because the path to external storage has changed over the years, which is why you should have never hard-coded the path in the first place.

how can I get the path directory in a more "formal and right" way instead of hardcoding the path?

Use Environment.getExternalStorageDirectory().

On your test environment, /sdcard is a symlink or hardlink to /storage/sdcard0, as set up by the device manufacturer. However, there is no guarantee that all devices will have such an /sdcard symlink.

I guess the 32GB storage comes with a built-in SD card

External storage is a portion of your on-board 32GB of flash memory.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thank you mark , i was also thinking same !! but have some doubts !! but you cleared it out.. – Sandeep Dhull Jun 20 '13 at 14:00
  • 2
    completely agree on this point **However, there is no guarantee that all devices will have such an /sdcard symlink**. When i use `Environment.getExternalStorageDirectory()` returns path of internal memory named `sdcard0` and my external sdcard is named `extsdcard`. Its for samsug galaxy s3. – Raghunandan Jun 20 '13 at 14:00
  • 1
    Thanks for the comments! But you seemed to have missed my most important question:"I encountered a runtime exception on the writer class when I use `Environment.getExternalStorageDirectory().getAbsolutePath()`. How can I fix this?" THX – Sibbs Gambling Jun 20 '13 at 14:03
  • @Commonsware How about the one in @ http://stackoverflow.com/questions/15744064/cant-check-if-file-on-sdcard-exists/15744282#comment22381234_15744282 – Raghunandan Jun 20 '13 at 14:04
  • @perfectionming: Use LogCat to examine the Java stack trace associated with your runtime exception. Also, use the proper two-parameter `File` constructor instead of concatenation. – CommonsWare Jun 20 '13 at 14:06
  • 1
    @Raghunandan: I certainly cannot recommend that technique -- anything that relies upon possibly-nonexistent command-line programs like **`mount`** is asking for trouble. I am sincerely hoping that Google eventually adds official support for multiple mount points. – CommonsWare Jun 20 '13 at 14:07
  • I am really new to this. I am sure the exception happens because of `Environment.getExternalStorageDirectory().getAbsolutePath()`, because once I hardcode the directory, everything is fine. Once I use that, the exception occurs. COuld you please kindly help me? – Sibbs Gambling Jun 20 '13 at 14:11
  • @perfectionming: "COuld you please kindly help me?" -- I did. I told you to use LogCat to examine the Java stack trace associated with your runtime exception. If you cannot interpret what the stack trace is telling you, copy and paste the trace into your question. I also told you to use the proper two-parameter `File` constructor instead of concatenation. I *think* that fix will clear up your problem, as right now you are trying to load `/storage/sdcard0whatever.txt` (where `whatever` is the value of `txtName.getText()`). – CommonsWare Jun 20 '13 at 14:13
  • @Raghunandan just found my case to be exactly same as yours! I also access the phone memory via `Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + userName + ".parameters.txt"`. So how do you get the path of your SD card in the end? – Sibbs Gambling Jun 20 '13 at 14:19
  • @CommonsWare `Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + userName + ".parameters.txt"` returns me the directory of my phone memory instead of SD card... How may I get the directory of my SD card using codes? – Sibbs Gambling Jun 20 '13 at 14:21
  • @perfectionming: There is no support in the Android SDK for anything other than the official external storage returned via `Environment.getExternalStorageDirectory()`. – CommonsWare Jun 20 '13 at 14:22
  • @CommonsWare Thanks! Then if so, how can I assure that the app can function properly on every device? As you said, the hard-coding method is not universal. – Sibbs Gambling Jun 20 '13 at 14:24
  • @perfectionming: The code will work on every device. For example, it works fine on your HTC One X. However, *your file has to be on the device's official external storage*, not other data stores (e.g., SD cards, USB thumb drives). You could try to use `MediaStore`, as many devices will index other data stores. You're welcome to experiment with solutions like what Raghunandan suggested (relying on stuff like **`mount`**), though I can't recommend that. Support for alternative data stores like SD cards, etc. has been a long-standing hole in the SDK. – CommonsWare Jun 20 '13 at 14:30
  • If we use `getExternalStorageDirectory()` to create a new directory in primary storage (which is generally internal memory), then what happens if the default storage has been set to `External Memory` and it's not **writable**? I mean what is the best way to handle it then? – S.R Jul 16 '17 at 18:50
  • @S.R: I do not know what you are referring to. Please consider opening a separate question, where you explain your concern. In there, please provide technical explanations for the terms "primary storage", "default storage", and "external memory". – CommonsWare Jul 16 '17 at 23:52
  • Thanks for the reply. I've already asked my question [here](https://stackoverflow.com/questions/45128244/how-to-write-read-a-folder-file-in-android-storage). but I didn't get my answer. – S.R Jul 17 '17 at 08:03
0

Remove the .getAbsolutePath() and it will be fine. Environment.getExternalStoreDirectory() will give you the path to wherever the manufacture has set their external storage.

3rdeye7
  • 536
  • 4
  • 25