path_provider package , dart:io library(File, Directory)
안드로이드는 현재 앱내의 저장소(data/data/0/packageName/...) 이외의 모든 저장소들을 외부 저장소로 취급한다.
ex) 내부저장소 , SD카드 등등
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
일반적으로 플러터에서 가장 많이 사용하는 저장 위치경로 들을 얻을 수 있는 패키지
Temporary directory: 캐쉬같이 임시로 데이터를 저장하는 공간이고 언제든지 삭제될 수 있다.
iOS 의 NSCachesDirectory와 Android 의 getCacheDir() 의 값에 해당하는 위치이다.
Documents directory: 해당 앱만의 저장공간이며 앱이 삭제되면 없어진다.
iOS 의 NSDocumentDirectory 와 Android 의 AppData 값에 해당한다.
아래의 함수들을 통해 일반적인 앱이 접근하여 사용하는 저장공간에 해당하는 파일 시스템상의 위치 정보를 얻을 수 있다.
getApplicationDocumentsDirectory()
getApplicationSupportDirectory()
getExternalCacheDirectories()
getExternalStorageDirectories({StorageDirectory type })
getExternalStorageDirectory()
getTemporaryDirectory()
getApplication, getExternal차이점
= 사용자가 접근가능한 폴더에 접근 유무
Directory('path')
// dir생성
var directory = await Directory('path').create(recursive: true);
// system디렉토리 항목 나열
var systemTempDir = Directory.systemTemp;
// dir존재 여부
final myDir = Directory('dir');
var isThere = await myDir.exists();
외부저장소에 접근할 수 있는 경로를 반환해줌
function
ExternalPath.getExternalStorageDirectories()
getExternalStoragePublicDirectory(공용저장소)
Android 11 (API 30) 부터 외부저장소 앱 및 사용자 데이터를 보호하기 위해 범위 지정 저장소 도입
(android 11에서 기존 권한(android.permission.WRITE_EXTERNAL_STORAGE) 무시됨
출처: https://devmason.tistory.com/344 [With IT:티스토리]
Android 10 (API 29)를 타겟팅 하는 앱에서는 requestLegacyExternalStorage를 요청하여 범위 지정 저장소와 관련된 사항을 해제할 수 있엇지만, Android 11부터 requestLegacyExternalStorage는 무시됨.
따라서, 새로운 파일 관리를 위한 파일 엑세스 권한 요청이 필요함.
= MANAGE_EXTERNAL_STORAGE
= 앱에 대한 모든 파일 관리 허용 옵션
// 저장공간 permission 허용
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
이후, permission_handler 라이브러리를 사용해서 권한 요청
// android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
PermissionStatus status = await Permission.manageExternalStorage.request();
final dir = await ExternalPath.getExternalStorageDirectories();
// 디렉터리 경로 가져온 후 하위 디렉토리 생성
Directory path_dir = await Directory('${dir[0]}/').create(recursive: true);
// 위에서 생성한 디렉토리에 파일 생성하고 리턴
print('경로 : ${path_dir.path}');
if (status.isDenied) {
print('권한요청 실패');
} else {
print('권한요청 성공');
}
storage permission 관련 참고 링크
함수 별 경로
permission 관련 - 1
permission 관련 - 2
내부 메모리 : 실행 중인 앱의 메모리에 저장되어 있는 것
data/data/패키지명
내부 저장소 : 디바이스 기기에서 기본적으로 제공되는 저장소 공간
storage/self/primary/
외부 저장소 : 디바이스 기기 이외에 저장소 (sd카드 등등)
storage/'SD카드명'/
출처
https://iosroid.tistory.com/45 [조용한 담장:티스토리]
https://ksrapp.tistory.com/6
https://byunpa.tistory.com/187
https://m.blog.naver.com/heennavi1004/222390438020
Uri를 filepath로 바꾸는 방법
toFile(url) : /data/data/패키지명/files/uri_to_file/파일명
image.picker : /data/user/0/패키지명/cache/파일명
getTemporaryDirectory : /data/user/0/패키지명/cache/파일명
uri_to_file 라이브러리 사용
Uri uri = Uri.parse(result['filePath']);
// uri : content://media/external/images/media/1599
File file = await toFile(uri.toString());
// File: '/data/data/패키지명/files/uri_to_file/파일명'
= getTemporaryDirectory로 cache에 파일 저장 후 사용
final box = context.findRenderObject() as RenderBox?;
sharePositionOrigin: box!.localToGloal(Offset.zero) & box.size
ios개발자 페이지 (폴더 구조) 참고
https://developer.apple.com/documentation/foundation/nssearchpathdirectory/nscachesdirectory
stackoverflow ios path 참고
https://stackoverflow.com/questions/59501445/flutter-how-to-save-a-file-on-ios
pathprovider를 통해서 경로에 접근할 때 사용하는 함수
ex)getApplicationDocumentsDirectory()
를 사용하면 플러그인에서 각 기기에 맞는 경로로 접근해서 파일을 엑세스한다.
getApplicationDocumentsDirectory를 사용하면
IOS = NSDocumentDirectory로 이동하고
android = /data/user/0/패키지 이름/app_flutter_
앱은 일반적으로 컨테이너 디렉터리 외부에 있는 파일에 엑세스하거나 파일을 생성할 수 없다.
= path_provider에서 getExternal을 사용할 수 없다.
예외적으로 앱이 공용 시스템 인터페이스를 사용하여 사용자의 연락처, 음악같은 항목에 엑세스하는 경우
Documents/
이 디렉토리를 사용하여 사용자 생성 콘텐츠를 저장합니다. 이 디렉토리의 내용은 파일 공유를 통해 사용자가 사용할 수 있습니다. 따라서 이 디렉토리에는 사용자에게 노출하려는 파일만 포함되어야 합니다.
이 디렉토리의 내용은 iTunes 및 iCloud에 의해 백업됩니다.
Documents/Inbox
앱은 이 디렉터리의 파일을 읽고 삭제할 수 있지만 새 파일을 만들거나 기존 파일에 쓸 수는 없습니다. 사용자가 이 디렉터리의 파일을 편집하려고 하면 앱은 변경하기 전에 디렉터리 밖으로 파일을 자동으로 이동해야 합니다.
Library/
Library사용자에게 노출하지 않으려는 파일에는 하위 디렉토리를 사용하십시오. 앱은 사용자 데이터 파일에 이러한 디렉터리를 사용해서는 안 됩니다.
ios File System 참고 https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html
path_provider
getApplicationDocumentsDirectory()
= 사용자에게 모든 파일 표시
getApplicationSupportDirectory()
= 사용자에게 파일을 보여주지 않음
stackoverflow참고
https://stackoverflow.com/questions/55220612/how-to-save-a-text-file-in-external-storage-in-ios-using-flutter
감사합니다. 덕분에 궁금했던 내용을 한번에 알아갑니다 ^^