Android/StoreInfo

<정리> Data and file storage

re트 2024. 9. 21. 18:19
728x90

안드로이드는 다른 플랫폼의 디스크 기반 파일 시스템과 유사한 파일 시스템 사용

앱은 기본적으로 내부 저장소에 저장되지만 APK 사이즈가 너무 큰 경우에는 매니페스트 파일에서 외부 저장소에 설치하도록 설정 가능

 

데이터 저장 방법

1. App-specific storage(앱 전용 저장소)

다른 앱은 접근할 수 없는 해당 앱 전용 저장소

App-specific files 저장

내부 저장소 경로 : data/data/패키지명 

외부 저장소 경로 : /storage/emulated/0/Android/data/패키지명

내부/외부 저장소 접근 : Context 사용

2. Shared storage(공유 저장소)

다른 앱과 공유하려는 파일(동영상, 문서 등) 저장

Shareable media content 저장

3. Preferences

키-값 쌍으로 이루어진 개인적이고 원시적인 데이터 저장

Structured data 저장

4. Databases(데이터베이스)

Room Persistence Library(Room 라이브러리)를 사용하여 구조화된 데이터를 앱 데이터베이스에 저장

Structured data 저장

 

데이터 저장소에 들어가는 것들

1. App-specific files(앱 전용 파일)

- 앱에서만 사용하는 파일들

- 내부 저장소에 저장되어있는 파일에 접근하려면 getFilesDir()이나 getCacheDir() 사용
- 외부 저장소에 저장되어있는 파일에 접근하려면 getExternalFilesDir()이나 getExternalCacheDir() 사용
- 내부 저장소 접근에는 퍼미션이 필요없고 외부 저장소는 Android 4.4 이상의 단말기라면 필요없음
- 내부든 외부든 다른 앱에서 접근 불가

- 앱이 삭제된다면 전부 삭제됨

2. Media(미디어)

- 공유가능한 미디어 파일들(이미지, 오디오 비디오)

- MediaStore API를 사용해 접근

- Android 11 이상의 단말기에서 다른 앱의 미디어 파일에 접근하려면 READ_EXTERNAL_STORAGE 권한 필요

- Android 10 단말기에서 다른 앱의 미디어 파일에 접근하려면 READ_EXTERNAL_STORAGE나 WRITE_EXTERNAL_STORAGE 권한 필요(읽고 쓰고 하려면 두 권한 다 필요)

- Android 9 이하의 단말기에서는 모든 파일에 접근하기 위해 READ_EXTERNAL_STORAGE와 WRITE_EXTERNAL_STORAGE 권한 둘다 필요

- 외부 저장소의 공용 디렉토리에 저장되기 때문에 앱이 삭제되어도 자동적으로 삭제되지 않음

3. Documents and other files(문서와 기타 파일)

- 미디어 파일 유형을 제외한 다양한 유형의 공유 가능한 파일들(다운로드한 파일, 문서, 텍스트 파일 등)

- Storage Access Framework(SAF)를 사용해 접근

- SAF를 통해 사용자가 직접 파일을 선택하면 해당 파일의 접근 권한이 자동으로 부여되며 접근 가능

- 다른 앱의 문서 파일에 접근하려면 시스템 파일 선택기를 통해서 선택해야 함

- 외부 저장소의 공용 디렉토리에 저장되기 때문에 앱이 삭제되어도 자동적으로 삭제되지 않음

4. App preferences

- 키-값 쌍으로 이루어진 데이터

- Jetpack Preferences library를 사용해 접근

- App preferences는 해당 앱에만 관련된 데이터이기 때문에 특별한 권한이 필요하지 않음

- 해당 앱에만 관련된 데이터에 다른 앱은 접근 불가능

- 앱이 삭제된다면 전부 삭제됨

5. Database

- 구조화된 데이터

- Room persistence library를 사용해 접근

- 앱 자체 데이터베이스에 접근하는 것이기 때문에 추가적인 권한이 필요하지 않음

- 다른 앱과 격리되어있는 데이터베이스이기 때문에 다른 앱은 접근 불가능

- 앱이 삭제된다면 전부 삭제됨

 

앱 전용 저장소(App-specific storage) 접근

앱이 지워지면 앱 전용 저장소 내 파일 모두 삭제됨

앱과 별개로 남아있기를 바라는 데이터는 이 저장소에 저장하면 안 되고 적절한 공유 저장소에 저장해야 함

1. 내부 저장소 접근

사용자 설정이나 데이터베이스 같은 영구 파일과 민감한 데이터를 일시적으로 저장할 때 쓰는 캐시 데이터를 저장하는 디렉토리

다른 앱의 접근을 막기 위해 Android 10 이상부터는 내부 저장소 내 파일 경로 암호화

해당 앱에서만 접근 가능한 민감한 데이터 저장하는데 적합

해당 앱의 내부 저장소 접근에는 어떻나 시스템 권한도 필요하지 않음

대체로 내부 저장소는 용량이 작은 편

 

1) 영구 파일 접근

영구파일이 저장된 디렉토리는 Context 객체의 filesDir 속성을 사용하여 접근 가능(= getFilesDir())

파일에 접근하고 저장할 때는 File API 사용 가능

// 내부 저장소에 있는 영구 파일에 대한 참조 생성
// 해당 파일에 대해 읽기, 쓰기, 저장 등의 작업을 수행 가능
File file = new File(context.getFilesDir(), filename);

내부 저장소에 있는 파일을 다른 앱이 접근하려면 FileProvider와 FLAG_GRNAT_READ_URI_PERMISSION 속성을 사용해야 함

1. 매니페스트 파일에 FileProvider 추가
2. 접근할 파일의 경로를 정의하는 파일 생성(ex. file_paths.xml)
3. File API와 FileProvider를 이용하여 URI 생성
4. Intent 플래그에 Intent.FLAG_GRANT_READ_URI_PERMISSION 추가하여 파일 전송(Intent.createChooser)

내부 저장소 안에 있는 파일들의 이름을 배열로 얻으려면 fileList() 사용

 

2) 캐시 파일 접근

캐시 파일을 만드는 건 File.createTempFile(filename, null, context.getCacheDir()) 사용

캐시 파일이 저장된 디렉토리는 Context 객체의 cacheDir 속성을 사용하여 접근 가능(= getCacheDir())

// 내부 저장소에 있는 캐시 파일에 대한 참조 생성
File cacheFile = new File(context.getCacheDir(), filename);

내부 저장소의 캐시 파일을 지울 때는 File 객체의 delete() 사용하거나 앱 컨텍스트의 deleteFile(cacheFileName) 사용

// File 객체
cacheFile.delete();
// 앱 Context
context.deleteFile(cacheFileName);

 

2. 외부 저장소 접근

사용자가 생성한 이미지, 문서, 비디오와 같은 영구 파일과 캐시 데이터를 저장하는 디렉토리

다른 앱이 적절한 권한을 가지고 있다면 접근이 가능하지만 기본적으로 외부 저장소에 저장된 파일은 해당 앱에서만 사용하기 위한 것

Android 4.4 이상의 단말기라면 해당 앱에서 외부 저장소 내 앱 전용 디렉토리 접근에 어떠한 권한도 필요없음

Android 9 이하의 단말기에서는 적절한 저장소 권한을 가지고 있다면 다른 앱의 외부 저장소 앱 전용 파일에 접근 가능

Android 10 이상의 단말기에서는 기본적으로 앱 전용 디렉토리에 대한 접근이 제한됨(scoped storage)

접근가능한 파일을 만들려고 한다면 외부 저장소의 앱 전용 저장소에 저장하는 것이 아니라 외부 저장소의 공유 저장소에 저장해야 함

앱 내에서만 필요한 미디어 파일은 외부 저장소의 앱 전용 디렉토리에 저장하는 것이 좋음

외부 저장소의 앱 전용 테이터를 읽거나 쓰기 전에 외부 저장소의 접근 가능성 확인 필요

private boolean isExternalStorageWritable() {
    return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
}

private boolean isExternalStorageReadable() {
     return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) ||
            Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY);
}

제거 가능한 외부 저장소가 없는 단말기에서는 외부 저장소 관련 기능을 테스트하기 위해 가상 볼륨 활성화 가능

adb shell sm set-virtual-disk true

 

1) 영구 파일 접근

영구파일이 저장된 디렉토리는 getExternalFilesDir() 사용해서 접근

파일에 접근하고 저장할 때는 File API 사용 가능

// Android 11 이상에서는 외부 저장소에 앱 전용 저장소를 만들지 않는다고 함
File appSpecificExternalDir = new File(context.getExternalFilesDir(null), filename);

 

2) 캐시 파일 접근

캐시 파일이 저장된 디렉토리는 Context 객체의 getExternalCacheDir() 사용해서 접근

File externalCacheFile = new File(context.getExternalCacheDir(), filename);

외부 저장소의 캐시 파일을 지울 때는 File 객체의 delete() 사용

// File 객체
externalCacheFile.delete();

 

3. 저장 공간 확인

StorageManager 객체의 getAllocatableBytes()를 사용하여 단말기가 앱에 제공할 수 있는 공간을 확인 가능

확인한 공간이 필요한 공간보다 크다면 allocateBytes()를 사용하여 앱 전용 저장소 공간을 할당 가능

 

공유 저장소(Shared storage) 접근

사용자 데이터 중 다른 앱이 접근 가능한 데이터나 앱이 삭제되어도 남아이었어야 하는 데이터는 공유 저장소에 저장이 필요함

 

(추가 예정...)

반응형