출처: http://lsit81.tistory.com/entry/추가-Micro-SD-Card-경로-얻기
안녕하세요.
최근에 출시된 Android 단말기들은 Micro SD Card를 삽입하지 않아도
기본적으로 내장 메모리를 가지고 있으며, 추가적으로 sd card를 삽입할 수도 있게
되었습니다.
문제는 Android 기본 API로는 이 추가적으로 삽입된 sd card의 경로는 알수가 없다는 것 입니다.
일반적으로는 /mnt/sdcard/external_sd/ 라는 경로를 가지고 있게되는데요...
문제는 이 경로는 제조사측에서 마음이 바뀌면 충분히 경로 명이 바뀔 수 있다는 것 입니다.
그래서 추가적으로 삽입된 sd card의 경로를 가져올 수 있는 코드를 한번 작성해 보았습니다.
동작방식
1. Android는 리눅스 커널기반에서 동작되므로 모든 장치는 mount 되어야만
2. mount에 대한 정보는 "/system/etc/vold.fstab", "/proc/mounts" 파일로 관리하고 있습니다.
3. 이 두가지 파일을 이용하여 mount된 Filesystem의 Path를 얻어 옵니다.
4. 추출된 Filesystem List에서 disk의 크기를 구하여 1Gbyte 미만의 Filesystem은 리스트에서 제거합니다.
5. 얻고자 하는 Filesystem만 올수 있도록 알려진 filesystem이 포함된 경우 해당 filsystem을 list에서 제거합니다. |
소스 보기
/** * 추가 적인 외부 확장 SDCard path 얻기. * 조건으로 걸러진 최종 String List size가 1이 아니면 null 리턴 * @return */ public static String getMicroSDCardDirectory() { List<String> mMounts = readMountsFile(); List<String> mVold = readVoldFile(); for ( int i= 0 ; i < mMounts.size(); i++) { String mount = mMounts.get(i); if (!mVold.contains(mount)) { mMounts.remove(i--); continue ; } File root = new File(mount); if (!root.exists() || !root.isDirectory()) { mMounts.remove(i--); continue ; } if (!isAvailableFileSystem(mount)) { mMounts.remove(i--); continue ; } if (!checkMicroSDCard(mount)) { mMounts.remove(i--); } } if (mMounts.size() == 1 ) { return mMounts.get( 0 ); } return null ; } private static List<String> readMountsFile() { /** * Scan the /proc/mounts file and look for lines like this: * /dev/block/vold/179:1 /mnt/sdcard
* 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 */ List<String> mMounts = new ArrayList<String>(); 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( "[ \t]+" ); String element = lineElements[ 1 ]; mMounts.add(element); } } } catch (Exception e) { // Auto-generated catch block e.printStackTrace(); } return mMounts; } private static List<String> readVoldFile() { /** * Scan the /system/etc/vold.fstab file and look for lines like this: * dev_mount sdcard /mnt/sdcard 1 /devices/platform/
* 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 */ List<String> mVold = new ArrayList<String>(); 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( "[ \t]+" ); String element = lineElements[ 2 ]; if (element.contains( ":" )) { element = element.substring( 0 , element.indexOf( ":" )); } mVold.add(element); } } } catch (Exception e) { // Auto-generated catch block e.printStackTrace(); } return mVold; } private static boolean checkMicroSDCard(String fileSystemName) { StatFs statFs = new StatFs(fileSystemName); long totalSize = ( long )statFs.getBlockSize() * statFs.getBlockCount(); if (totalSize < onE_GIGABYTE) { return false ; } return true ; } private static boolean isAvailableFileSystem(String fileSystemName) { final String[] unAvailableFileSystemList = { "/dev" , "/mnt/asec" , "/mnt/obb" , "/system" , "/data" , "/cache" , "/efs" , "/firmware" };
for (String name : unAvailableFileSystemList) { if (fileSystemName.contains(name) == true ) { return false ; } } if (Environment.getExternalStorageDirectory().getAbsolutePath().equals(fileSystemName) == true ) { /** 안드로이드에서 제공되는 getExternalStorageDirectory() 경로와 같은 경로일 경우에는 추가로 삽입된 SDCard가 아니라고 판단하였습니다. **/ return false ; } return true ; }
|
History
* 아래는 2012.05.14일에 작성된 내용으로 df 명령을 통해 외부 sdcard 경로를 가져왔으나 일부 디바이스에서 문제가 발견되어 위 내용으로 수정하였으며, 이 내용은 History를 관리하기위해 남겨둔 글 입니다.
그래서 df 명령을 이용하여 mount된 File System 정보를 얻어 아래는 "df" 시 넘어오는 데이터 입니다. 기준은 갤럭시 s3입니다.
위 내용을 parsing하여 추가 sd card가 존재하는지 여부를 판단하여 존재할 경우 해당 위치를 가져올 수 있게 하였습니다. 다만 추가 sd card의 위치는 "android.os.Environment.getExternalStorageDirectory()"로 얻은 경로 밑에 있다고 가정하였습니다. 그리고 알려진 File System에 대한 정보는 무시 처리하였습니다.
* 최종 코드
|
'IT_Programming > Android_Java' 카테고리의 다른 글
[펌] Android 프로세스의 통신 메커니즘: 바인더 (0) | 2013.07.23 |
---|---|
android:windowIsFloating 속성에 관하여 (0) | 2013.07.16 |
Android JellyBean에서 사라진 setEmbeddedTitleBar 해결 방법 (0) | 2013.07.16 |
[Android] 루팅 여부 확인하기. (0) | 2013.07.16 |
마켓 호출시 android.content.ActivityNotFoundException 문제. (0) | 2013.07.16 |