티스토리 뷰

파일에 대한 Content URI 생성하기


Content URI를 통해서 다른 앱에 현재 내 앱의 파일을 공유하기 위해선 내 앱의 파일에 대한 Content URI를 생성해야 한다.

그러기 위해선 파일을 하나 생성한 다음 File.getUriForFile()메서드에 매개변수로 그 파일을 전달하면 된다. 그럼 이 함수는 그 파일에 대한

Content URI를 생성하여 되돌려준다. 이 Content URI는 임시권한이 부여 되어 있으며 인텐트에 담아서 다른 앱에 전송되게 된다.

그럼 그 인텐트를 받은 앱은 내 앱에 있는 파일을 ContentResolver.openFileDescriptor를 통해서 접근할수 있게 된다.


만약 내 앱에 있는 default_image.jpg를 다른 앱에 공유하고 싶다면?

1
2
3
File imagePath = new File(Context.getFilesDir(), "images");
File newFile = new File(imagePath, "default_image.jpg");
Uri contentUri = getUriForFile(getContext(), "com.mydomain.fileprovider", newFile);
cs

위와 같은 코드를 작성하면 된다. 우선 앱 홈 폴더 내의 files 디렉토리의 images 폴더를 생성한다. - 1번 line

(기본적으로 안드로이드는 리눅스 파일 시스템을 사용하기 때문에 폴더든 파일이든 디바이스 장치건 모두 파일로 취급된다.)

그리고, 그 경로에 default_image.jpg라는 파일을 생성한다. - 2번 line

그리고 그 파일을 getUriForFile의 매개변수의 마지막 인자로 전달한다. 두번째 인자는 fileprovider의 authorities를 의미한다.

content provider에서 authorities의 의미는 그 content provider의 주소와 같은 역할을 한다고 보면 된다.

즉 3번 line의 의미는 내 앱속에 있는 fileprovider에게 새롭게 만들어진 newFile에 대한 content uri를 내놔라 라고 요청하는것과 같다.


getUriForFile의 리턴값으로 다음과 같은 Content URI가 리턴된다.

content://com.mydomain.fileprovider/my_images/default_image.jpg.

보면 scheme은 content://이고 authorities는 나의 패키지명.fileprovider이며 path는 my_images/default_imgae.jpg 라는 Content URI가 생성 되었다.

이 uri를 이제 인텐트에 담아서 카메라 앱에 보내게 되면 카메라앱은 찍힌 사진을 자신의 ContentResolver의 openFileDescriptor를 통해서

전달받은 인텐트 속의 Content URI로 연결하여 그 사진을 나의 앱 홈 폴더에 insert할 수 있게 되는것이다.

여기서 빨간색 부분으로 칠해진 my_images라는 폴더는 우리가 만든적이 없었는데 뭐지? 라는 생각이 들것이다.

하지만 잘 생각해보면 아까 우리가 XML파일에 설정을 해주었었다.

1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
    <paths>
        <files-path name="my_images" path="./images" /
    </paths>
cs
이부분에서 우리는 아까 이런식으로 앱 홈 폴더내의 어떤 폴더의 경로에 별명을 붙임으로써 보안을 강화 할 수 있다고 했었다. 바로 그 경로가
위에 나타난 경로이다.즉, my_images라는 경로는 앱 홈 폴더 내의 files/images/ 디렉토리 경로와 정확히 일치한다. 또한 상대주소를 기준으로 패스가 정의되어있다.

content://com.mydomain.fileprovider/my_images/default_image.jpg.
content://com.mydomain.fileprovider/files/images/default_image.jpg.

위의 두 경로가 일치한다는 의미이다. 하지만 아래처럼 경로를 적어버리면 내 앱의 폴더 구조가 어떻게 되있는지 알 수 있기 때문에
보안상의 이유로 위처럼 별명을 짓는것이다.

여기부터는 약간 TMI이므로 궁금하신분만 읽기 바란다. 
위의 내용만 가지고도 충분히 FileProvider와 파일의 권한, 경로 등을 이해 할수 있다고 생각한다.

Content URI에 임시 권한 부여하는 여러가지 방법

첫번째 방법
getUriForFile()메소드를 통해서 얻은 Content URI는 아직 임시 권한이 부여되지 않았기 때문에 임시 접근 권한을 부여 한 다음에 인텐트에 담아서 
뿌려야 한다.
Context.grantUriPermission(package, Uri, mode_flags) 함수를 사용하면 어떤 패키지에서 Content Uri에 어떤 권한(mode_flags)을 가지고 접근 할
수 있을지를 설정할 수 있다.
mode_flags로 설정할 수 있는 플래그는
FLAG_GRANT_READ_URI_PERMISSION -> Content URI를 read할수 있는 권한
FLAG_GRANT_WRITE_URI_PERMISSION -> Content URI를 write할수 있는 권한
두가지 또는 두가지 모두 |를 통해 연결하여 설정 할 수 있다.
revokeUriPermission() 함수를 사용하게 되면 그 패지키에서 Content Uri에 접근할수 있는 권한을 박탈하게 된다. 이 함수가 호출되기 전까지 권한은
유지 된다.

두번쨰 방법
Content URI를 인텐트의 setData()의 매개변수로 전달한다. 그리고 나서 인텐트의 setFlags() 메소드를 통해 위에 나와 있는 두가지 권한을 또는 둘다를
설정한다. 인텐트의 데이터 속성은 목적어에 해당한다 예를들어 tel:010-2032-4923라는 번호를 VIEW할수 있는 앱을 찾는다고 할때 tel:~~~에
해당하는부분이 data라고 할 수 있다. 즉, Content://~~~~에 사진 데이터를 담아줄수 있는 앱을 찾는다라고 인텐트의 setData를 통해
설정해놓고 인텐트를 발송하면 카메라 앱이 그 인텐트를 받을것이다. 

이부분은 적어는 놓았지만 정확히 이해하지 못한 부분이다. 나중에 다시 한번 살펴보자..

출처 https://developer.android.com/training/secure-file-sharing/
출처: http://simsimjae.tistory.com/265?category=293983 [흔한 컴공의 코딩 블로그]
https://stackoverflow.com/questions/24090667/how-can-make-a-fileprovider-available-to-other-applications
https://developer.android.com/reference/android/support/v4/content/FileProvider


'컴퓨터 공학과 졸업 > 안드 개발 기록' 카테고리의 다른 글

Canvas.save() Canvas.restore()  (1) 2018.07.25
외장메모리공간  (0) 2018.07.22
어플리케이션 간 파일 공유  (0) 2018.07.22
MediaStore  (0) 2018.07.21
File, File Path, SharedPreferences  (0) 2018.07.21
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함