Android Auto Backup

사용 언어: Kotlin 1.6.10
사용 버전: Android Studio 2021.01.01

안드로이드 Auto Backup을 알아보겠습니다.

안드로이드에서는 자동 백업 기능을 제공해 줍니다.
앱 사용자 개인 google drive에 앱의 데이터가 저장되는 건데요. 25 MB까지 지원해 줍니다. 이 25 MB는 무료로 제공되며 앱 개발자와 사용자에게 부과되는 것은 없습니다. 그럼 이렇게 좋은 기능을 사용해 봅시다.
이 기능은 Android 6.0(API 23) 이상부터 지원해 줍니다.



간단한 방법은 AndroidManifest.xml에 allowBackup을 true로 하면 됩니다.





그러면 이러한 데이터들이 저장됩니다.

Shared preferences 파일들, getFilesDir() 또는 getDir(String, int)에서 반환하는 내부 저장소 파일들, getDtatabasePath(String)에서 반환하는 데이터베이스 파일들, getExternalFilesDir(String)에서 반환하는 외부 저장소 파일들.




하지만 저런 데이터가 너무 많아서 25 MB가 넘어가면 자동으로 저장이 안 됩니다.

25 MB 이하가 되어야 자동으로 다시 백업을 진행합니다.




그러면 정말 필요한 것만 선택해서 백업을 시키려면 어떻게 해야 할까요?


우선 Android 11 이하 버전부터 살펴봅시다.

res/xml에 backup_rules라는 xml을 하나 만들어줍니다.

res 우 클릭 - New - Android Resource File




Root element에는 full-backup-content를 적어줍니다.




AndroidManifest.xml에 android:fullBackupContent 속성을 추가합니다.

값에는 @xml/backup_rules를 적습니다.





아까 만든 backup_rules.xml로 돌아갑니다.

<include>에는 포함할 것들 <exclude>에는 제외할 것들을 적습니다.






domain에는 file, database, sharedpref, external, root 등이 들어갈 수 있습니다. path에는 위치가 들어갑니다. requireFlags는 clientSideEncryption, deviceToDeviceTransfer가 들어갑니다.




기본적으로 backup은 모든 파일을 포함합니다. 그런데, 이렇게 include를 적어주면, include에 포함된 것만 백업시킵니다. 만약 include 중에 제외해야 할 것이 있다면 그 부분은 <exclude>로 적어줍니다.

예를 들면 sharedpref 중에 제외해야 할 파일이 있다면 <exclude domain="sharedpref" path="제외할 파일.xml" /> 이렇게 적습니다.





path에는 ./로 현제 디렉터리를 지명할 수 있습니다. 하지만 '..'은 보안상의 이유로 사용할 수 없습니다.

path에 포함된 폴더는 하위 폴더도 포함하여 백업합니다.



Android 9 (API 28) 이상부터는 백업에 비밀번호를 사용할 수 있습니다.

Android 9 이상을 위한 backup_rules.xml을 만듭시다.


res 우 클릭 - New - Android Resource File




File name, Resource type, Root element, Directory name을 설정합니다.

Directory name에 xml-v28은 API 28 이상에 적용되는 xml이라는 뜻입니다.




확인을 누르면 파일 모양이 이렇게 됩니다.





방금 만든 v28이 적힌 xml로 가서 아래와 같이 적어줍니다.

기존의 것과 똑같은데 추가된 것은 requireFlags입니다. 여기에 clientSideEncryption을 적어서 백업 시, 유저의 비밀번호를 사용한다고 설정합니다.





이제, Android 12에서 작동되는 Backup rules를 만들어 봅시다.

res 우 클릭 - New - Android Resource File을 누릅니다.





File name, Resource type, Root element, Directory name을 설정합니다.





cloud-backup 태그를 추가합니다.

여기에 disableIfNoEncryptionCapabilities 속성이 들어가는데, 이 속성은 잠금 화면이 설정되어 있을 때만 백업을 실행하겠다는 뜻입니다.

안에는 위에서 적은 것과 동일하게 include 태그를 사용합니다.




한 가지 다른 점은 <device-transfer>인데 이 태그는 cloud를 통한 백업이 아닌, 기기끼리의 연결을 통한 백업을 의미합니다.  Device-todevice (D2D) transfers를 의미합니다.

여기를 비워두면 자동 백업되는 모든 파일을 전송하겠다는 뜻입니다. 클라우드 백업처럼 용량 제한이 없으니 모든 파일을 보내는 것도 나쁘지 않아 보이네요.



Android 12에서 작동되는 rules를 적었으니 적용시킵시다.

AndroidManifest.xml로 갑니다.

android:dataExtractionRules에 우리가 만든 backup_rules_new를 적어줍니다.





형광펜이 칠해진 것처럼 불이 들어오는데 무시하면 됩니다.

XML에서 자신보다 높은 속성은 무시한다고 합니다.





가상 기기에서 백업 테스트를 해봅시다.

Android Studio 밑에 있는 Terminal을 눌러줍니다.




adb shell bmgr list transports를 입력합니다.




com.google.android.gms/.backup.BackupTransportService 앞에 *가 있으면 제대로 설정되었습니다.


백업을 시키려면, shell bmgr backupnow <패키지 이름>을 적습니다.

저 같은 경우는 shell bmgr backupnow starlight.jaehwa.three라 적었습니다.




메시지를 보니 실패했습니다. Backup is not allowed라고 나옵니다.

원인을 보니 가상 기기에 구글 로그인이 안 되어 있군요.



Settings에 가서 System으로 갑니다.





Backup을 누릅니다.




A


dd account로 계정을 추가해 줍니다.





자, 로그인했으면 다시 명령어를 칩니다.



이번에는 그냥 실패했다는 문구가 나오네요.






Logcat을 보면 내용이 나옵니다.





아무래도 encrypt를 설정해서 잠금 설정이 된 기기만 백업이 되나 봅니다.

가상 기기에 잠금 설정 후 실행해 봤는데 그래도 안되네요.




다른 방법을 사용해 봅시다.


adb shell bmgr backup @pm@ && adb shell bmgr run을 입력합니다.





Logcat을 보면, backup pass finished가 나옵니다.





adb shell fullbackup <패키지 이름>을 칩니다.

저는 adb shell fullbackup starlight.jaehwa.three를 입력했습니다.





음... Logcat을 보니 진행이 안되었네요. 가상 기기라서 그런가.

ㅠㅠ

최신 휴대폰 사면 직접 해봐야겠네요. 지금은 제가 가지고 있는 Android 8로 다시 테스트 진행하겠습니다.


adb shell bmgr backupnow starlight.jaehwa.three를 하면 이렇게 백업이 진행됩니다.






이제, 백업이 되었으니 복구하는 걸 해봅시다.

앱 정보로 가서 데이터를 지웁니다.





앱을 켜보면 빈 화면이 나옵니다.






이제 복원해 봅시다.

토큰이 필요합니다. 아래 명령어를 칩니다.

adb shell dumpsys backup






아래와 같이 토큰들이 나옵니다. 모자이크 처리해 줄게요.





이 토큰을 이용해서 복원합니다.


adb shell bmgr restore <토큰> <패키지 이름>을 적습니다.

그런데, 제가 위에서 구한 토큰을 적으니까 맞는 토큰이 없다면서 아래 다른 토큰을 알려줍니다. 저걸 적어봅시다.








짜잔, 복구되었습니다.







끝.


카테고리: Android

댓글

이 블로그의 인기 게시물

Python urllib.parse.quote()

Python OpenCV 빈 화면 만들기

tensorflow tf.random.uniform()

Android Notification with Full Screen

KiCad 시작하기 2 (PCB 만들기)

Android Minimum touch target size

Python bs4.SoupStrainer()

KiCad 시작하기 4 (기존 회로도 수정 및 추가)

음악 총보(Score), 파트보(Part)

tensorflow tf.expand_dims()