안드로이드 핸드폰 내장 SD 카드 경로 획득

16771 단어 android저장 장치
  ,            ,        ,      。       ,      ,     ,  !          ~~
              ,            。                。

1.나타난 문제 및 현상
1) 문제가 발생한 샘플: ZTE U930HD(내장 메모리 카드 2G, 외장SD카드 삽입이 없음) 다른 샘플은 문제가 없습니다.2) 현상: 사진을 찍은 후의 사진은 관련 로그를 다음과 같이 저장할 수 없다.
01-19 15:20:25.625: W/System.err(21600): java.io.FileNotFoundException: /mnt/sdcard/MMCamera/photo/20160119152025.jpg: open failed: EACCES (Permission denied)
01-19 15:20:25.625: W/System.err(21600):    at libcore.io.IoBridge.open(IoBridge.java:406)
01-19 15:20:25.625: W/System.err(21600):    at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
01-19 15:20:25.625: W/System.err(21600):    at java.io.FileOutputStream.<init>(FileOutputStream.java:73)
01-19 15:20:25.625: W/System.err(21600):    at com.wuxianxi.mmcamera.utils.FileUtil.saveImageToSDCard(FileUtil.java:26)
01-19 15:20:25.625: W/System.err(21600):    at com.wuxianxi.mmcamera.view.MainActivity$2.onPictureTaken(MainActivity.java:310)
01-19 15:20:25.625: W/System.err(21600):    at android.hardware.Camera$EventHandler.handleMessage(Camera.java:754)
01-19 15:20:25.625: W/System.err(21600):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-19 15:20:25.625: W/System.err(21600):    at android.os.Looper.loop(Looper.java:137)
01-19 15:20:25.625: W/System.err(21600):    at android.app.ActivityThread.main(ActivityThread.java:4424)
01-19 15:20:25.625: W/System.err(21600):    at java.lang.reflect.Method.invokeNative(Native Method)
01-19 15:20:25.625: W/System.err(21600):    at java.lang.reflect.Method.invoke(Method.java:511)
01-19 15:20:25.625: W/System.err(21600):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-19 15:20:25.625: W/System.err(21600):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-19 15:20:25.625: W/System.err(21600):    at dalvik.system.NativeStart.main(Native Method)
01-19 15:20:25.625: W/System.err(21600): Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied)
01-19 15:20:25.625: W/System.err(21600):    at libcore.io.Posix.open(Native Method)
01-19 15:20:25.625: W/System.err(21600):    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
01-19 15:20:25.625: W/System.err(21600):    at libcore.io.IoBridge.open(IoBridge.java:390)
01-19 15:20:25.635: W/System.err(21600):    ... 13 more

2.분석 원인 1) 휴대전화 연결 Eclipse,DDMS ->File Explorer를 보면 내장된 마운트 디렉터리는/mnt/sdcard2이지만 내 응용 프로그램에서 저장 경로를 가져오는 코드인 Environment이다.getExternal StorageDirectory (), "/mnt/sdcard"가 저장 경로 오류를 가져왔습니다. Environment를 다시 확인하십시오.getExternalStorageState(),"removed"로 되돌아오기; 원래는 Environment.getExternalStorageDirectory()로 외장 메모리 카드를 받았지만 외장SD카드가 삽입되지 않아 저장할 수 없습니다.2) 그럼 왜 다른 샘플은 문제가 없습니까? 다른 샘플은 getExternalStorageDirectory()를 호출합니다.반환 값은 다르다.Android의 문서를 조회한 후에 원인을 찾았습니다. 원래 이 방법은 현재 장치 제조업체가 생각하는'외부 저장소'를 되돌려줍니다. 외부SD카드 디렉터리(Micro SD Card)를 되돌릴 수도 있고 내장된 SD카드 디렉터리(eMMC)를 되돌릴 수도 있습니다.대부분의 샘플은 eMMC 저장소를 Environment에 마운트합니다.getExternal StorageDirectory () 노드에서 실제 외부 SD 카드를/mnt/external에 마운트합니다sd,/mnt/sdcard2 등 노드.그러나 지금의 ZTE U930HD와 반대로 eMMC 저장소를/mnt/external에 마운트하는 부분도 있다.sd,/mnt/sdcard2 등 노드를 외장된 SD카드를 Environment에 마운트합니다.getExternal StorageDirectory () 의 결점입니다.
3.해결 방법은 위에서 말한 바와 같이 Environment를 사용하면External Storage Directory () 에서 얻은 것은 외장SD 카드 경로이지만 외장SD 카드를 삽입하지 않았습니다. 이럴 때 내장된 eMMC 저장소로 일부 프로그램에서 사용하는 데이터를 저장해야 합니다. 이 eMMC 저장소의 경로를 어떻게 가져와야 합니까?인터넷에서 몇 가지 자료를 찾았는데 비교적 좋은 것은 시스템 파일을 스캔하는 시스템/etc/vold이다.fstab을 참조하십시오.시스템/etc/vold.fstab은 Android의 마운트 지점 정보를 설명하는 간단한 구성 파일입니다.먼저 구성 파일을 반복하여 모든 마운트 지점을 가져옵니다.
    //  android      
    private static List<String> getDevMountList() {
            List<String> mVold = new ArrayList<String>(10);
            mVold.add("/mnt/sdcard");

            try {
                File voldFile = new File("/system/etc/vold.fstab");
                if(voldFile.exists()){
                    Scanner scanner = new Scanner(voldFile);
                    while (scanner.hasNext()) {
                        String line = scanner.nextLine();
                        if (line.startsWith("dev_mount")) {
                            String[] lineElements = line.split(" ");
                            String element = lineElements[2];
                            Log.d(TAG, "Vold: element = "+element);

                            if (element.contains(":"))
                                element = element.substring(0, element.indexOf(":"));
                            if (!element.equals("/mnt/sdcard"))
                                mVold.add(element);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            return mVold;
    }

그리고 Environment를 판단합니다.getExternal Storage State () 의 값입니다. 만약 Environment가 되돌아온다면.MEDIA_MOUNTED("mounted")는 내장된 SD 카드 경로를 가져와 정확하게 저장할 수 있음을 설명한다.그렇지 않으면 외장SD카드로 되돌아온다고 하면 위의 모든 마운트 지점에서 저장할 수 있는 경로를 찾아 저장 작업을 해야 한다.참조 코드:
    public static String getExternalSdCardPath() {
        String  path = null;
        String state = Environment.getExternalStorageState();
        //Environment.getExternalStorageDirectory()      SDcard
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            path = Environment.getExternalStorageDirectory().getPath();
        } else {  //Environment.getExternalStorageDirectory()      SDcard,     sdcard
            List<String> devMountList = getDevMountList();
            for (String devMount : devMountList) {
                File file = new File(devMount);
                if (file.isDirectory() && file.canWrite()) {
                    path = file.getAbsolutePath();
                    break;
                }
            }
        }
        Log.d(TAG, "getExternalSdCardPath: path = "+path);
        return path;
    }

이로써 이 문제가 해결되고 프로젝트도 기본적으로 완성되었다.여기까지만 쓰세요.

좋은 웹페이지 즐겨찾기