Get External SDCard Location in Android

匿名 (未验证) 提交于 2019-12-03 02:05:01

问题:

I have an app with huge data pre-stored in the SD Card.

We are supporting all tablets ICS onwards. I am not able to find a way to access the SDCard location correctly on ALL devices.

I looked at various solutions given here on SO but they do not seem to work in all cases. Looking for a generic solution.

Even if anyone can tell me all the possible mount points of SDCard.

I am targeting android tablets only if that can narrow down the solution.

回答1:

Unfortunately this is a common problem due to the fact that Android devices are highly fragmented. Environment.getExternalStorageDirectory() refers to whatever the device manufacturer considers to be "external storage". On some devices, this is removable media, like an SD card. On some devices, this is a portion of on-device flash.(http://developer.android.com/reference/android/os/Environment.html#getExternalStorageDirectory()) Here, "external storage" means "the drive accessible via USB Mass Storage mode when mounted on a host machine". If a device manufacturer has elected to have external storage be on-board flash and also has an SD card, you will need to contact that manufacturer to determine whether or not you can use the SD card. For most conforming android devices(known ones from google compliance list) the Environment.getExternalStorageDirectory() should work. Or you could write a custom storage class that looks at the mount points and gives you the right path to the mounted SDCard. This is something I've implemented and it has worked so far.

public class StorageOptions {     private static ArrayList mMounts = new ArrayList();     private static ArrayList mVold = new ArrayList();      public static String[] labels;     public static String[] paths;     public static int count = 0;     private static final String TAG = StorageOptions.class.getSimpleName();      public static void determineStorageOptions() {         readMountsFile();          readVoldFile();          compareMountsWithVold();          testAndCleanMountsList();          setProperties();     }      private static void readMountsFile() {         /*          * Scan the /proc/mounts file and look for lines like this:          * /dev/block/vold/179:1 /mnt/sdcard vfat          * rw,dirsync,nosuid,nodev,noexec,          * relatime,uid=1000,gid=1015,fmask=0602,dmask          * =0602,allow_utime=0020,codepage          * =cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0          *           * When one is found, split it into its elements and then pull out the          * path to the that mount point and add it to the arraylist          */          // some mount files don't list the default         // path first, so we add it here to         // ensure that it is first in our list         mMounts.add("/mnt/sdcard");          try {             Scanner scanner = new Scanner(new File("/proc/mounts"));             while (scanner.hasNext()) {                 String line = scanner.nextLine();                 if (line.startsWith("/dev/block/vold/")) {                     String[] lineElements = line.split(" ");                     String element = lineElements[1];                      // don't add the default mount path                     // it's already in the list.                     if (!element.equals("/mnt/sdcard"))                         mMounts.add(element);                 }             }         } catch (Exception e) {             // Auto-generated catch block              e.printStackTrace();         }     }      private static void readVoldFile() {         /*          * Scan the /system/etc/vold.fstab file and look for lines like this:          * dev_mount sdcard /mnt/sdcard 1          * /devices/platform/s3c-sdhci.0/mmc_host/mmc0          *           * When one is found, split it into its elements and then pull out the          * path to the that mount point and add it to the arraylist          */          // some devices are missing the vold file entirely         // so we add a path here to make sure the list always         // includes the path to the first sdcard, whether real         // or emulated.         mVold.add("/mnt/sdcard");          try {             Scanner scanner = new Scanner(new File("/system/etc/vold.fstab"));             while (scanner.hasNext()) {                 String line = scanner.nextLine();                 if (line.startsWith("dev_mount")) {                     String[] lineElements = line.split(" ");                     String element = lineElements[2];                      if (element.contains(":"))                         element = element.substring(0, element.indexOf(":"));                      // don't add the default vold path                     // it's already in the list.                     if (!element.equals("/mnt/sdcard"))                         mVold.add(element);                 }             }         } catch (Exception e) {             // Auto-generated catch block              e.printStackTrace();         }     }      private static void compareMountsWithVold() {         /*          * Sometimes the two lists of mount points will be different. We only          * want those mount points that are in both list.          *           * Compare the two lists together and remove items that are not in both          * lists.          */          for (int i = 0; i ();         ArrayList mLabels = new ArrayList();          int j = 0;         if (mMounts.size() > 0) {             if (Build.VERSION.SDK_INT  1) {                 for (int i = 1; i ) mMounts.clone();         Constants.mLabels = (ArrayList) mLabels.clone();         count = Math.min(labels.length, paths.length);          // don't need this anymore, clear the mounts list to reduce memory         // use and to prepare it for the next time it's needed.         mMounts.clear();      } } 

I found this off of a similar question from SO, that I dont have the link to unfortunately, but it s there on probably Sony's Android developer site(no links there either unfortunately). Wagic - a C++ game engine library implements the same and their code is here: http://wagic.googlecode.com/svn-history/r4300/trunk/projects/mtg/Android/src/net/wagic/utils/StorageOptions.java so you could look at the implementation. I wish someone from Google can answer this question and provide a single way that reads the SDcard mount point from all Android devices



回答2:

Its not simple as you are thinking, String f = Environment.getExternalStorageDirectory().getAbsolutePath(); Log.v("TAG",f);//to print the path of sdcard

It returns device storage path not an external sdcard path.



回答3:

If you are trying to get the path to the SD card use this code

String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();

Then use this to get the path of the specific folder/file

String path = baseDir + "/your folder(s)/" + fileName;



回答4:

Its simple.

String f = Environment.getExternalStorageDirectory().getAbsolutePath(); Log.v("TAG",f);//to print the path of sdcard 

if you want to access a file then.

String f =  Environment.getExternalStorageDirectory()+"/file.ext"; Log.v("TAG",f);//to print the path of file in Logcat. 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!