- 불필요한 코드나 잘못 작성된 내용에 대한 지적은 언제나 환영합니다. 👍
- Android Developers Data backup 문서를 참고하여 실습하면서 배운 것들을 정리한 글입니다 😄
사용자들은 App 내에서 ID를 생성하고 데이터를 추가하고, 앱의 환경 설정을 개인의 경험에 맞춰하기도 하고, 많은 시간과 노력을 투자합니다. 새로운 스마트폰으로 업그레이드하거나, 재설치할 때 이러한 데이터와 개인화를 유지하는 것은 훌륭한 사용자 경험을 위해 중요한 부분입니다. 이 것을 가능케 하는 데이터 백업 기능에 대해 알아보겠습니다.
백업 옵션
Android는 앱이 데이터를 클라우드에 백업할 수 있도록 두 가지 방법을 제공합니다.
주요 차이점을 간략하게 살펴보고, 이 글에서는 자동 백업을 먼저 살펴보도록 하겠습니다.
(다음글에서는 Key-value 백업을 알아보도록 하겠습니다.)
1. 자동 백업 (Android Auto Backup)
2. Key-value Backup (Android Backup Service)
<주요 차이점>
카테고리 | Key-value Backup | Android Auto Backup (자동 백업) |
지원되는 버전 | Android 2.2(API 수준 8) 이상 | Android 6.0(API 수준 23) 이상 |
기본 사용 여부 | 사용 X | 사용 O |
구현 | 앱에서 BackUpAgent를 직접 구현해야함 | - 기본적으로 App 파일의 대부분을 포함 - XML을 사용하여 포함할 파일, 제외할 파일 설정 가능 - 내부적으로 SDK에 제공되는 BackUpAgent를 사용 |
실행 | - 백업할 데이터를 준비하고 앱에서 요청을 직접 보내야 함 - 앱에서 보낸 백업 요청은 몇 시간마다 일괄 실행됨 |
대략 하루에 한 번 자동으로 실행 |
앱 종료 여부 | 백업 중에는 앱이 종료되지 않음 | 백업 도중에 시스템이 앱을 종료함 |
백업 저장용량 | - 데이터는 Android Backup Service에 저장 - 앱당 5MB로 제한 |
- 데이터는 사용자의 Google Drive에 저장 - 앱당 25MB로 제한 |
사용자 로그인 | 사용자가 앱에 Google 로그인하지 않아도 됨 단, 기기자체가 Google 계정이 로그인되어 있어야 함 |
|
데이터 복원 | - 앱이 설치되면 데이터가 복원됨 - 필요한 경우 수동 복원을 요청 가능 |
- 앱이 설치되면 데이터가 복원됨 - 여러 데이터 세트를 사용할 수 있다면, 사용자는 백업 데이터 세트 목록에서 선택 가능 |
자동 백업 (Auto Backup)
- Android 버전 6.0 (API level 23) 이상에서 사용 가능
- 사용자의 Google Drive 계정에 데이터를 업로드하여 보존
- 시스템에서 앱에 할당한 대부분의 디렉터리에 있는 파일 포함
- 파일 기반 방식으로, 데이터를 앱당 25MB까지 저장
- 일반적으로 자동 백업을 사용하는 것이 좋으며, 그 이유는 기본으로 사용 설정되어 있고 구현할 작업이 없음
(Android 버전 6.0 이상을 타겟팅하는 앱은 자동 백업이 자동으로 사용 설정됨) - Android 9 이상의 기기에서는 PIN이나 패턴, 비밀번호를 사용하여 End to End 암호화(종단 간 암호화) 가능
- 앱에서 백업 절차를 맞춤설정하거나, 백업을 사용 중지하여 해제할 수 있음
백업되는 파일
기본적으로 시스템에서 앱에 할당하는 대부분의 디렉터리에 있는 다음과 같은 파일이 포함됩니다.
- SharedPreferences 파일
- getFilesDir() 또는 getDir(String, int)을 사용하여 액세스하는 앱의 내부 저장소에 저장된 파일
- getDatabasePath(String)에서 반환한 디렉터리의 파일(SQLiteOpenHelper 클래스를 사용하여 생성한 파일 포함)
- getExternalFilesDir(String)에서 반환한 디렉터리의 외부 저장소에 있는 파일
getCacheDir(), getCodeCacheDir(), getNoBackupFilesDir()에서 반환한 디렉터리에 있는 파일은 자동 백업에서 제외됩니다. 이 위치에 저장된 파일은 일시적으로만 필요하며 백업 작업에서는 의도적으로 제외됩니다.
백업 위치
- 백업 데이터는 사용자의 Google Drive 계정에 있는 비공개 폴더에 저장되며 앱당 25MB로 제한됩니다.
- 저장된 데이터는 사용자의 개인 Google Drive 할당량에 포함되지 않습니다
- 최근 백업만 저장됩니다. 백업이 이뤄지면 이전 백업 파일은 삭제됩니다.
- 기기의 사용자나 다른 앱은 백업 데이터를 읽을 수 없습니다.
- 사용자는 Google Drive Android 앱에 백업된 앱의 목록을 확인할 수 있습니다. (설정 > 백업 및 재설정)
❗️주의: 데이터양이 25MB를 초과하면 시스템이 onQuotaExceeded()를 호출하고 데이터를 클라우드에 백업하지 않습니다. 시스템은 데이터양이 이후에 25MB 이내로 줄어드는지 주기적으로 확인하고 줄어들면 자동 백업을 계속합니다.
백업 일정
다음 조건이 모두 충족되면 자동 백업이 실행됩니다.
- 사용자가 기기에 백업을 사용 설정 On
- 마지막 백업 후 24시간 이상 경과
- 기기가 유휴(idle) 상태
- 기기가 Wi-Fi 네트워크에 연결되어 있음 (기기 사용자가 모바일 데이터 백업을 선택하지 않은 경우)
자동 백업을 하는 동안 시스템은 앱을 종료하여 앱이 더 이상 파일을 수정하지 못하도록 합니다.
사용자가 현재 사용중인 (포어그라운드 상태인) 앱은 갑자기 꺼져버리지 않도록, 자동 백업을 실행하지 않습니다.
복원 일정
데이터는 앱이 설치될 때마다 복원됩니다. 이는 Play 스토어를 통해 설치되는 경우, 시스템이 이전에 설치된 앱을 설치하는 경우, 또는 adb install을 실행할 때 모두 해당됩니다. 복원 작업은 APK가 설치된 후에 발생하지만 사용자가 앱을 실행하기 전에 이루어집니다.
백업 사용 설정
앱 매니페스트 파일에서 android:allowBackup="true" or "false" 값을 설정하여 백업을 사용 설정 또는 중지할 수 있습니다.
Android 6.0(API 수준 23) 이상을 타겟팅하는 앱은 자동 백업 설정이 자동으로 활성화됩니다. (기본값 true)
1
2
3
4
5
6
|
<manifest ... >
...
<application android:allowBackup="true" ... >
...
</application>
</manifest>
|
cs |
파일 포함 및 제외시키기
XML 을 정의하여 백업 대상을 제어할 수 있습니다.
Android 11 (API 수준 30) 이하의 경우
❗️ 중요 : Android 12 이상 기기를 지원하기 위해서는, 아래 Android 12 (API 수준 31) 이상의 경우 설정도 함께 해줘야 합니다.
1. AndroidManifest.xml에서 <application> 요소에 android:fullBackupContent 속성을 추가합니다. 이 속성은 백업 규칙을 정의하는 XML 파일을 가리킵니다. (backup_rules.xml)
1
2
3
|
<application ...
android:fullBackupContent="@xml/backup_rules">
</application>
|
cs |
2. res/xml/ 디렉터리에 backup_rules.xml 파일을 만듭니다. 파일 내에 포함할 파일을 정의하는 <include>와 제외할 파일을 정의하는 <exclude> 요소를 사용하여 규칙을 추가합니다. 다음 샘플에서는 device.xml을 제외한 모든 SharedPreferences 파일을 백업합니다.
1
2
3
4
5
|
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
</full-backup-content>
|
cs |
백업 추가 조건 설정
앱에서 민감한 정보를 저장하는 경우, 앱의 데이터에 적용되는 조건을 지정할 수 있습니다. Android 9(API 수준 28) 이상에서는 다음 조건을 추가할 수 있습니다.
- clientSideEncryption : 사용자의 백업이 기기의 보안 설정을 사용하여 암호화됩니다. Android 9 이상에서 백업을 사용 설정하고, 기기에 화면 잠금을 설정하면 됩니다. (PIN, 패턴 또는 비밀번호 등)
- deviceToDeviceTransfer : 사용자가 다른 디바이스로 백업을 전송하는 경우, 로컬 디바이스 간 전송을 지원하는 다른 디바이스로 전송됩니다 (예: Google Pixel)
1
2
3
4
5
6
7
|
<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<!-- App data isn't included in user's backup
unless client-side encryption is enabled. -->
<include domain="file" path="."
requireFlags="clientSideEncryption" />
</full-backup-content>
|
cs |
- 위와 같이 <include> 요소 내에서 requireFlags="clientSideEncryption" 을 선언하면,
App Data는 기기 보안이 설정되어 있을 때만 백업이 활성화됩니다. (PIN, 패턴 또는 비밀번호 등)
Android 12 (API 수준 31) 이상의 경우
❗️ 중요 : 앱이 Android 12 이상을 타겟팅하더라도 위에서 살펴본 설정도 함께 지정해서, Android 11 (API 수준 30) 이하를 실행하는 기기를 지원해야 합니다.
1. AndroidManifest.xml에서 <application> 요소에 android:dataExtractionRules 속성을 추가합니다. 이 속성은 백업 규칙을 정의하는 XML 파일을 가리킵니다. (backup_rules.xml)
1
2
3
|
<application ...
android:dataExtractionRules="backup_rules.xml">
</application>
|
cs |
2. res/xml/ 디렉터리에 backup_rules.xml 파일을 만듭니다. 파일 내에 포함할 파일을 정의하는 <include>와 제외할 파일을 정의하는 <exclude> 요소를 사용하여 규칙을 추가합니다. 다음 샘플에서는 device.xml을 제외한 모든 SharedPreferences 파일을 백업합니다.
1
2
3
4
5
6
7
|
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
<cloud-backup [disableIfNoEncryptionCapabilities="true|false"]>
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
</cloud-backup>
</data-extraction-rules>
|
cs |
Backup rule XML 구성 문법
구성 파일의 XML 구문은 앱이 타겟팅하고 실행하는 Android 버전에 따라 다릅니다.
Android 11 (API 수준 30) 이하의 경우
1
2
3
4
5
6
7
|
<full-backup-content>
<include domain=["file" | "database" | "sharedpref" | "external" | "root"]
path="string"
requireFlags=["clientSideEncryption" | "deviceToDeviceTransfer"] />
<exclude domain=["file" | "database" | "sharedpref" | "external" | "root"]
path="string" />
</full-backup-content>
|
cs |
Android 12 (API 수준 31) 이상의 경우
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<data-extraction-rules>
<cloud-backup [disableIfNoEncryptionCapabilities="true|false"]>
...
<include domain=["file" | "database" | "sharedpref" | "external" | "root"]
path="string"/>
...
<exclude domain=["file" | "database" | "sharedpref" | "external" | "root"]
path="string"/>
...
</cloud-backup>
<device-transfer>
...
<include domain=["file" | "database" | "sharedpref" | "external" | "root"]
path="string"/>
...
<exclude domain=["file" | "database" | "sharedpref" | "external" | "root"]
path="string"/>
...
</device-transfer>
</data-extraction-rules>
|
cs |
구성의 각 섹션(<cloud-backup>, <device-transfer>)에는 특정 전송 유형에만 적용되는 규칙이 포함되어 있습니다. 이를 통해 Device to Device 전송에는 특정 파일이나 디렉터리를 포함시키면서, Google Drive 클라우드 백업에서는 특정 파일/디렉터리를 제외시키는 작업 등을 할 수 있습니다.
<cloud-backup> 섹션에서 disableIfNoEncryptionCapabilities="true|false" 플래그를 설정하여 기기에 잠금 화면이 있는 경우에만(기기의 잠금 설정으로 데이터를 암호화할 수 있는 경우)에만 백업이 실행되도록 할 수 있습니다.
<include> 및 <exclude>에 관한 문법 (포함/제외될 파일 및 디렉터리 설정)
<include>
- 백업할 파일 또는 폴더를 지정합니다. 기본적으로 자동 백업은 거의 모든 앱 파일을 포함합니다.
- ❗️ <include> 요소를 지정하면 시스템은 더 이상 어떤 파일도 기본으로 포함하지 않고 지정된 파일만 백업합니다.❗️
- 여러 파일을 포함하려면 다수의 <include> 요소를 사용합니다.
✏️ 참고 : getCacheDir(), getCodeCacheDir(), getNoBackupFilesDir() 에서 반환된 디렉터리의 파일은 개발자가 포함하려고 해도 항상 제외됩니다.
✏️ 참고 : 사용자 인증 정보와 인증 토큰을 백업하려면 SharedPreferences 또는 파일에 저장하지 마세요. 대신 Block Store API를 사용하여 사용자 인증 정보를 저장하고 관리하세요. 이렇게 하면 안전하게 저장되고 다른 앱 데이터와 함께 백업 및 복원할 수 있습니다.
<exclude>
- 백업 대상에서 제외할 파일 또는 폴더를 지정합니다. 백업에서 일반적으로 제외되는 파일은 다음과 같습니다.
- 서버에서 발행하거나 기기에서 생성한 기기 전용 식별자(device-specific identifiers)를 사용하는 파일 (ex: FCM Token)
- 앱 디버깅과 관련된 파일
- 앱이 25MB의 백업 할당량을 초과하도록 하는 대용량 파일.
✏️ 참고 : <include>와 <exclude> 요소를 모두 지정하면 <include> 요소에서 지정된 모든 파일에서 <exclude> 요소에 지정된 파일을 대상에서 제외하고 나서, 백업을 실행합니다. 즉, <exclude>가 우선합니다.
각 <include> 및 <exclude> 요소는 다음 두 속성을 포함해야 합니다.
domain
- root - 이 앱에 속한 모든 비공개 파일이 저장된 파일 시스템의 디렉터리
- file - getFilesDir() 에서 반환한 디렉터리
- database - getDatabasePath()에서 반환한 디렉터리(SQLiteOpenHelper 클래스를 사용하여 생성한 파일 포함)
- sharedpref - SharedPreferences가 저장된 디렉터리
- external - getExternalFilesDir()에서 반환한 디렉터리
path
- 파일 또는 폴더 경로를 지정합니다. 다음 내용을 참고하세요.
- ./ 를 사용하여 현재 디렉터리를 참조할 수 있지만, 보안상의 이유로 상위 디렉터리 .. 는 참조할 수 없습니다.
- 디렉터리를 지정하면 그 디렉터리와 반복되는 하위 디렉터리에 있는 모든 파일에 규칙이 적용됩니다.
'Android' 카테고리의 다른 글
[Android] Kotlin Flows in practice 번역 및 정리 (2) (0) | 2023.04.22 |
---|---|
[Android] Kotlin Flows in practice 번역 및 정리 (1) (0) | 2023.04.21 |
[Android] 앱 아키텍처 가이드 (2) (0) | 2023.04.15 |
[Android] 앱 아키텍처 가이드 (1) (0) | 2023.04.15 |
[Android] selector 를 통해 Layout 모든 요소에 터치 효과 만들기 (0) | 2020.03.13 |