삼성 갤러리의 OneDrive 동기화가 끝난다길래, 갤러리 앱을 직접 만들었다 - Miettes 개발기

2026. 9. 30. 11:25·Develop

2026년 9월 30일, 삼성 갤러리의 OneDrive 동기화가 종료됐습니다. 찍은 사진을 알아서 OneDrive에 올려 주고, 폰에서 지운 옛 사진도 갤러리에서 그대로 보여 주던 기능입니다. 폰 용량이 넉넉하지 않은 저에게는 사실상 갤러리의 전부였습니다.

대안을 찾아보니 원하는 건 의외로 단순했습니다. 폰에 있는 사진과 OneDrive에만 남은 사진을 한 타임라인에서 보고, 새 사진은 알아서 올라가면 된다. 그런데 이 두 가지를 제대로 해 주는 앱이 마땅치 않았습니다. 그래서 직접 만들었고, 첫 커밋부터 지금 버전(v0.5.4)까지 나흘이 걸렸습니다.


Miettes는 어떤 앱인가

Miettes(미에뜨)는 프랑스어로 '부스러기들', '작은 조각들'이라는 뜻입니다. 크루아상을 먹고 나면 부스러기가 남듯, 사진도 일상에서 떨어져 나온 작은 기억의 조각입니다. 오늘 찍은 사진은 폰에 있고, 몇 년 전 사진은 OneDrive에만 남아 있기도 합니다.

Miettes는 이렇게 흩어진 조각을 하나의 타임라인으로 다시 모아 보여 주는 삼성 갤러리 스타일의 Android 갤러리입니다. 사진이 어디에 저장돼 있는지 신경 쓸 필요가 없게 하는 것이 목표입니다.

흩어진 사진을, 하나의 시간으로.

데모 빌드로 녹화한 화면. 사진은 Unsplash(picsum.photos)에서 가져온 가짜 데이터입니다.

주요 기능

  • 하나의 타임라인: 폰 사진(MediaStore)과 OneDrive 사진을 날짜순으로 합칩니다. 같은 사진이 양쪽에 있으면 하나로 보입니다.
  • 저장 위치 표시: 백업됨, 기기에만 있음, 클라우드에만 있음, 업로드 대기, 실패를 타일의 아이콘으로 구분하고, 필터로 골라 볼 수도 있습니다.
  • 자동 백업: 삼성 동기화가 쓰던 자리(사진/삼성 갤러리/<기기 폴더>/)에 그대로 올려서 기존 폴더 구조가 이어집니다.
  • 양쪽 삭제: 기기 휴지통과 OneDrive 휴지통으로 함께 보내고, 둘 다 30일 동안 복구할 수 있습니다.
  • 삼성 갤러리에서 쓰던 기능들: 스토리, 검색, 앨범, 정리 제안, 내장 플레이어, 상세정보(EXIF와 지도), 2~12칸 확대·축소와 연도 보기까지 옮겼습니다.
  • 서버 없음: 폰이 Microsoft Graph와 직접 통신하고, 썸네일만 캐시합니다(최대 1GB).

타임라인, 뷰어, 상세정보. 구름 아이콘이 붙은 사진은 OneDrive에만 있어서 기기 용량을 쓰지 않습니다.


코드보다 계획을 먼저

바로 코드를 짜지 않고, 두 AI 모델(GPT-6 Astra와 Claude Fable 5.1)에게 각각 설계안을 받은 뒤 하나의 문서로 합쳤습니다. 두 안이 같은 결론을 낸 부분은 그대로 가져가고, 의견이 갈린 부분은 어느 쪽을 왜 골랐는지 적어 가며 정했습니다. 그중 몇 가지를 소개합니다.

  • 구조: Room 데이터베이스 하나를 유일한 원천으로 둡니다. 로컬 스캐너와 클라우드 인덱서가 각자 여기에 기록하고, 화면은 이 인덱스만 봅니다.
  • 클라우드 인덱스 범위: 드라이브 전체가 아니라 지정한 폴더만 Graph delta로 가져옵니다. 전체를 훑으면 느리고 자주 실패하기 때문입니다.
  • 중복 판정: ID, quickXorHash, (이름 + 크기 + 촬영 시각) 순서로 맞춰 봅니다. 마지막 단계는 '잠정 연결'일 뿐이라, 해시로 확인되기 전에는 삭제하거나 업로드를 건너뛰는 근거로 쓰지 않습니다.
  • 백그라운드 업로드: 포그라운드 서비스 대신 일반 WorkManager 작업으로 돌리고, 청크 단위로 진행 상황을 저장합니다. Android 16의 dataSync 시간 제한을 피하기 위해서입니다.

계획 맨 앞에는 '비슷한 앱이 이미 있으면 만들지 않는다'는 단계도 넣었습니다. 만드는 것보다 만들지 않는 편이 늘 더 싸니까요.

MediaStore ──scan──┐                 ┌── Graph delta (폴더별, 이어받기 가능)
                   ▼                 ▼
          Room 인덱스 (유일한 원천) ── 이름 + 크기 + 시각으로 연결
                   │
       ┌───────────┼──────────────┐
  Compose UI   WorkManager     Coil 썸네일 캐시
              (15분 주기 + 새 사진 트리거,
               이어 올리기, quickXorHash 검증,
               삭제 전파, 밀린 업로드 알림)

전체 구조


기술적으로 신경 쓴 부분

사진의 신원은 quickXorHash로

개인 OneDrive에서는 sha1Hash가 2023년 7월에 폐지돼, 보장되는 해시가 quickXorHash 하나뿐입니다. Microsoft가 공개한 이 알고리즘을 Kotlin으로 직접 구현하고, 로컬 파일의 해시를 백그라운드에서 조금씩 계산해 둡니다. 업로드가 끝나면 서버가 돌려준 해시와 비교해 검증하고, '기기 공간 확보'로 기기 사본을 지울 때도 해시가 일치하는 사진만 지웁니다.

끊겨도 이어지는 업로드

4MiB보다 작은 파일은 PUT 한 번으로, 그보다 큰 파일은 업로드 세션을 만들어 10MiB 청크로 올립니다(청크 크기는 320KiB의 배수여야 합니다). 업로드 URL과 오프셋을 저장해 두기 때문에 중간에 끊겨도 이어서 올릴 수 있습니다. 세션이 만료되면 새로 만들기 전에 목적지에 파일이 이미 있는지부터 확인합니다.

사고를 막는 안전장치

사진 앱에서 가장 무서운 건 사진이 사라지는 일이라, 안전장치에 공을 많이 들였습니다.

  • 앱을 다시 설치하면 모든 폴더의 첫 인덱싱이 끝날 때까지 업로드를 멈춥니다. 그래야 이미 올라간 사진을 또 올리지 않고 '양쪽에 있음'으로 연결합니다.
  • 한꺼번에 많은 사진이 사라지면 삭제 동기화를 멈춥니다.
  • '기기 공간 확보'는 기본으로 꺼져 있고, 켜더라도 OneDrive 쪽 사진은 건드리지 않습니다.
  • 로그인은 OAuth 2.0 + PKCE로 폰 안에서 끝나며, 클라이언트 시크릿이 없습니다.

나흘 동안의 버전 기록

  • 9/27 첫 버전(당시 이름 OD Gallery): 통합 타임라인, Graph delta 인덱스, 자동 업로드, 양쪽 삭제, 다중 선택과 공유, 내장 플레이어
  • 9/28 v0.2.0: 즐겨찾기, EXIF·위치 상세정보, 검색, 앨범 이동·복사·숨기기, 모션 포토, 슬라이드쇼, 연도 보기. R8로 줄인 APK는 4.5MB
  • 9/28 v0.3.0: 기기 공간 확보, OneDrive 링크 공유, N년 전 오늘, 정리 제안, 이름 바꾸기·회전·배경화면 설정
  • 9/28 v0.4.0: 스토리 탭
  • 9/28 v0.5.0: Miettes로 리브랜딩
  • 9/28~9/30 v0.5.1~v0.5.4: 카카오톡 공유 수정, 삼성 편집기 연동, Android 13 지원

스토리 탭, 1년 전 오늘, 앨범


삽질 기록

카카오톡이 사진 한 장을 받지 않는다 (v0.5.1)

여러 장을 공유하면 잘 되는데, 한 장만 공유하면 카카오톡에 첨부되지 않았습니다. 원인은 공유 인텐트의 MIME 타입이었습니다. 파일의 실제 타입(image/jpeg 같은)을 넣어 보내도록 고치자 바로 해결됐습니다.

삼성 편집기는 불러도 오지 않는다 (v0.5.2)

처음에는 편집 버튼을 누르면 ACTION_EDIT으로 앱 선택 창을 띄웠는데, 정작 삼성 편집기가 목록에 나오지 않았습니다. 삼성 갤러리가 다른 앱이 보낸 ACTION_EDIT에는 응답하지 않기 때문입니다. 그래서 삼성 사진 편집기(SPEActivity)를 직접 지정해 부르고, 실패할 때만 선택 창으로 넘어가도록 바꿨습니다.

OneDrive에만 있는 사진도 한 번 탭하면 기기에 받은 뒤 바로 편집기로 엽니다. 백업된 파일이 편집으로 바뀌면 같은 OneDrive 항목에 다시 올리기 때문에, 이전 사진은 OneDrive 버전 기록에 남습니다.

동영상 편집기는 열리자마자 닫힌다 (v0.5.3)

사진 편집기와 같은 방식으로 동영상 편집기를 부르자, 편집기가 켜지자마자 스스로 닫혀 버렸습니다. 디컴파일 대신 로그를 읽었습니다. logcat을 비운 상태에서 삼성 갤러리로 동영상 편집을 한 번 실행하고, 편집기가 스스로 남긴 인텐트 로그를 확인했습니다.

삼성 갤러리는 ACTION_EDIT이 아니라 ACTION_MAIN에 타입 */*, EXTRA_STREAM으로 Uri 목록, 그리고 launch_from 값까지 담아 부르고 있었습니다. 똑같은 모양으로 맞춰 보내니 편집기가 제대로 열렸습니다.

Intent(Intent.ACTION_MAIN).setType("*/*").setComponent(ComponentName.unflattenFromString(VIDEO_EDITOR))
    .putParcelableArrayListExtra(Intent.EXTRA_STREAM, arrayListOf(uri))
    .putExtra("launch_from", "From Gallery")
    .putExtra("video_type", "normal")
    .apply { clipData = ClipData.newRawUri(null, uri) }
    .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)

Android 13 지원 (v0.5.4)

minSdk를 34에서 33으로 낮췄습니다. Android 14에만 있는 API는 '일부 사진만 허용' 권한 확인 하나였고, Android 13에서는 이 값이 '거부'로 읽힐 뿐이라 문제가 없었습니다. Android 13 에뮬레이터와 실제 Galaxy S24에서 모두 확인했습니다.

검색, 메뉴(정리 제안과 기기 공간 확보), 백업 설정


OD Gallery에서 Miettes로

처음 이름은 OD Gallery였습니다. 그런데 OneDrive에 묶인 이름이라 도구 같은 인상이 강했고, 나중에 다른 저장소를 붙이면 이름과 기능이 맞지 않게 됩니다. 그래서 사진과 기억이라는 본질에 맞춰 Miettes로 바꿨습니다. 제 닉네임 '크로아상생쥐'와도 은근히 이어지는 이름이라 마음에 듭니다.

다만 OAuth 리디렉트 URI에 기존 패키지 이름(com.sanguneo.odgallery)이 들어 있어서, applicationId와 리디렉트는 그대로 두고 화면에 보이는 이름만 바꿨습니다. 덕분에 OD Gallery 위에 덮어 설치해도 데이터와 로그인이 그대로 유지됩니다.


마치며

처음에는 '사라지는 기능 하나만 메우자'는 생각이었는데, 쓰다 보니 삼성 갤러리에서 매일 쓰던 기능을 거의 다 옮기게 됐습니다. 아직 한계도 있습니다. 개인 OneDrive 전용이라 회사·학교 계정은 테스트하지 않았고, 업로드 시점은 Android의 백그라운드 정책을 따르며, 모션 포토는 기기에 있는 사진만 재생됩니다.

  • 기술 스택: Kotlin, Jetpack Compose(Material 3), Room, WorkManager, Coil 3, Media3, OkHttp, Microsoft Graph
  • 지원 환경: Android 13 이상, 개인 Microsoft 계정

Miettes by 크로아상생쥐 (@croissmouse)

저작자표시 비영리 변경금지 (새창열림)

'Develop' 카테고리의 다른 글

카카오톡을 터미널에서 읽는다 — 윈도우 kanao-cli, 맥 kamado-cli  (0) 2026.09.21
한국어 IME 조합 버그를 고쳐 Windows Terminal에 기여한 이야기  (0) 2026.07.29
Vercel 보안 이슈 정리  (0) 2026.04.20
Zlack: Slack을 더 가볍게 쓰기 위한 Tauri 데스크톱 클라이언트  (0) 2026.04.15
구너 영상 플레이어 15.11  (1) 2018.05.30
'Develop' 카테고리의 다른 글
  • 카카오톡을 터미널에서 읽는다 — 윈도우 kanao-cli, 맥 kamado-cli
  • 한국어 IME 조합 버그를 고쳐 Windows Terminal에 기여한 이야기
  • Vercel 보안 이슈 정리
  • Zlack: Slack을 더 가볍게 쓰기 위한 Tauri 데스크톱 클라이언트
상구너
상구너
개발, AI, 자동화, 일상 기록을 담는 상구너의 작업노트. 직접 해본 것, 써본 것, 정리한 것을 가볍고 실용적으로 남깁니다
  • 상구너
    상구너의 개발노트
    상구너
  • 전체
    오늘
    어제
    • 분류 전체보기 (63) N
      • Day by day (4)
        • Diary (1)
        • TV (0)
      • Challenge (6)
      • Study (32)
        • AI (10)
        • NodeJS (0)
        • JavaScript (3)
        • Markup (1)
        • Linux (6)
        • Java (1)
        • BCI&BCEL&ASM (8)
        • WAS (1)
        • DB (1)
      • Develop (14) N
        • inKrKamus (3)
        • SmartDropPoint (2)
        • rhwptopdf (1)
      • Faith (0)
  • 블로그 메뉴

    • 홈
    • GITHUB
    • LinkedIn
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    개발기
    html5
    Rust
    tts
    oci
    Supertonic
    Hermes
    나노바나나
    openclaw
    Ai
  • 최근 댓글

  • 최근 글

상구너
삼성 갤러리의 OneDrive 동기화가 끝난다길래, 갤러리 앱을 직접 만들었다 - Miettes 개발기
상단으로

티스토리툴바