총 게시물 38,868건, 최근 3 건 안내 RSS 글쓰기
이전글  다음글  목록 글쓰기
[안드로이드]

Android 7.0 외부 저장소 접근 및 읽고 쓰기 질문

글쓴이 : RobertKim 날짜 : 2017-11-06 (월) 19:31 조회 : 294
글주소 : http://www.androidside.com/B49/168740
 
  No1 기술혁신 NXP반도체
반도체전문업체, 휴대전화, 가전, ID, 범용반도체, 소프트웨어, 반도체제품안내.
www.nxp.com
  오라클자바교육센터 구로본점
안드로이드전문교육, SDK실무개발, APP개발프로젝트, 실습폰지원, 재직자환급
www.oraclejava.co.kr
  엠브이테크
임베디드 개발용역 및 양산 Rockchip Freescale 엑시노스
www.mvtech.or.kr
신청하기


안드로이드, 자바 그리고 다양한 질문에 대해 성실히 답해드립니다. Q&A Jang



외부 저장소의 접근이 안됩니다...


이전에 안드로이드4.4 이전 버전을 사용할 때 제가 만든 앱이 외부 저장소(SD 카드, USB)에

읽고 쓰기가 자유로웠습니다.(경로 /mnt/sdcard)

AndroidManifest.xml 파일에 아래 권한을 줄 경우에 말이죠

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>



같은 앱을 안드로이드 7.0 버전에서 설치하였더니 외부 저장소에 접근이 되지 않더군요. 찾아보니 상위 안드로이드 버전에서는 권한을 사용자에게 요청하여 확인을 받아야되더군요. 그래서 아래의 코드를 추가하여 앱의 권한 허용을 하였습니다.

if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED
|| checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED)
{

// Should we show an explanation?
if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE))
{
// Explain to the user why we need to write the permission.
Toast.makeText(this, "Read/Write external storage", Toast.LENGTH_SHORT).show();
}

requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
1);

// MY_PERMISSION_REQUEST_STORAGE is an
// app-defined int constant

}


그리고 또 달라진 점은 외부 저장소의 경로가 완전히 달라졌습니다. 경로를 찾아주는 아래 코드로 경로를 찾아봤습니다. 확인해보니 SD 카드가 마운트된 경로가 /mnt/media_rw/2249-0688 로 잡혔혔습니다. 노트5에서 OTG로 USB를 연결하고 경로를 확인하니 뒤에 숫자만 달라진 경로가 나오더군요.

public static String getExternalSDCardPath()
{
HashSet<String> hs = getExternalMounts();
for(String extSDCardPath : hs)
{
return extSDCardPath;
}
return null;
}
// --------------------------------------------------------------------------------------------//
//
// --------------------------------------------------------------------------------------------//
public static HashSet<String> getExternalMounts() {
final HashSet<String> out = new HashSet<String>();
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
String s = "";
try {
final Process process = new ProcessBuilder().command("mount")
.redirectErrorStream(true).start();
process.waitFor();
final InputStream is = process.getInputStream();
final byte[] buffer = new byte[1024];
while (is.read(buffer) != -1) {
s = s + new String(buffer);
}
is.close();
} catch (final Exception e) {
e.printStackTrace();
}

// parse output
final String[] lines = s.split("\n");
for (String line : lines) {
if (!line.toLowerCase(Locale.US).contains("asec")) {
if (line.matches(reg)) {
String[] parts = line.split(" ");
for (String part : parts) {
if (part.startsWith("/"))
if (!part.toLowerCase(Locale.US).contains("vold"))
out.add(part);
}
}
}
}
return out;
}



권한을 허용받고 외부 저장소에 쓰기를 하니 IOException이 발생하더군요.

Permission Denied라면서요.

앱 정보를 들어가서 권한 정보를 보면 저장공간에 체크도 되어있습니다.(첨부파일)


여기서 질문사항이 생겼습니다..

1. 쓰기 권한을 허용 받았는데 왜 권한 문제라고 뜨면서 안써질까요? File API를 사용하여서 그런건지? 아래코드에서 mountPosition은 /mnt/media_rw/2249-0688 입니다.

File testFile = new File(mountPosition + "/" + "test.test");
testFile.createNewFile();

W/System.err: java.io.IOException: Permission denied

W/System.err:     at java.io.UnixFileSystem.createFileExclusively0(Native Method)

W/System.err:     at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:280)

W/System.err:     at java.io.File.createNewFile(File.java:948)


ES 파일 탐색기를 설치해서 OTG로 연결된 USB 사용 권한을 허용하니 USB 읽고 쓰기가 자유롭습니다. ES 파일 탐색기는 어떻게 쓰고 읽기를 하는 것인지?


2. 그리고 SD 카드의 경로 폴더를 File API의 exists() 함수로 /mnt/media_rw/2249-0688 의 폴더 존재 유무를 확인하니 폴더가 없다고 나오는데 왜 그럴까요? 

일단 이 이부분에서 드는 생각은 media_rw 폴더의 접근 권한이 없어서 2249-0688 폴더를 확인할 수가 없어 없다고 나오는 것 같습니다.


어떻게 하면 문제가 해결이 될지 조언 부탁드립니다.




질문자가 자신의 포인트 20 점을 걸었습니다.
답변하시면 포인트 2을, 답변이 채택되면 포인트 16을 드립니다.

질문답변 게시판에서 궁금한 사항을 해결하셨다면, 애써 답변해주신 분께 잘 되었다고 따뜻한 댓글 한마디 남겨주세요.
그리고 답변해주신 분의 글을 '추천' 해주세요.
추천받으신 분에게 1포인트가, 추천하신 분에게도 1포인트가 적립됩니다. ^^

꽁순이 2017-11-14 (화) 10:46
안드로이드 킷캣 밑의 버전은 자유롭게 접근 가능했으나 
킷캣버전부터 권한 강화로 인해 접근이 힘들어졌습니다.
킷캣 위의 버전부터는 DocumentFile 이라는 것을 검색해보시면 도움이 되실듯합니다.
DocumentFile을 사용자에게 권한 허용을 받아야 하는 부분도 해당부분도 함께 적용 하시면 될듯합니다. 
그치만 저 사이에 끼어있는 킷캣의 경우는.. 어쩔수 없이 읽기만 가능한 상태입니다. 굳이 쓰고자 한다면 자신의 패키지 폴더 안에만 사용 가능하달까요...
댓글주소 추천 0 반대 0
안사드 2017-11-14 (화) 11:08
6.0 마시멜로우부터 퍼미션 권한이 강화되었습니다. 메니페스트에만 선언한다고 주는게 아니고 사용자가 ok눌러야 합니다. tedpermission같은거 확인해 보세요.
댓글주소 추천 0 반대 0
이전글  다음글  목록 글쓰기

 


Copyright ⓒ www.androidside.com. All rights reserved.
채팅 권한: 글쓰기 1개
2레벨 이상만 대화 가능
공개 채팅: 평일 !(9시 ~ 17시),토,일
안사2 변경사항 보러가기 챗방이 잘 안보이면 크롬에서 접속해주세요
챗방 숨기기 |  챗방 보이기