본문 바로가기

Android_Java

targetSdkVersion 30 적용

문제점

21년 9월 이후 마켓에 올라가는 app은 필수적으로 targetSdkVersion 30으로 업데이트 해주어야 한다.

현재 앱은 29 이고, 9월 업데이트가 예정되어 있으므로, 29 > 30으로 업데이트 진행.

업데이트시, 앱에서 수정해야 할점이나, 고려해야 할 점들을 파악하여 업데이트시 문제가 발생하지 않도록 진행.


해결 방법

개발자 문서에 잘 적혀있다. 개발자 문서를 보면서 현재 앱에 적용되어있는 부분들을 고려.


해결 과정

개발자 문서 파악

https://developer.android.com/distribute/best-practices/develop/target-sdk?hl=ko

 

Google Play의 타겟 API 수준 요구사항 충족하기  |  Android Developers

APK를 업로드하는 경우 Google Play의 타겟 API 수준 요구사항을 충족해야 합니다. 새 앱과 앱 업데이트는 Android 10(API 수준 29) 이상을 타겟팅해야 합니다. 단, Wear OS 앱은 API 수준 28 이상을 타겟팅해야

developer.android.com

참고한 문서는 위의 것이고 좀더 중점적으로 봐야하는 부분만 따로 추려보았습니다.

2021년 8월부터 신규 앱은 API 30 이상을 타겟팅 / 2021년 11월부터 앱 업데이트는 API 수준 30 이상을 타겟팅

Android 11의 동작 사항에 맞게 조정(?) 아직은 정확한 내용을 모르겠습니다. 
>. 동작 사항에 맞게 조정이라는건 And11 에서도 정상 동작할수 있게 지원하는걸 의미하는것 같습니다.

 

29 > 30 변경시 고려해야할 사항을 확인합니다. 크게 2가지로 나뉩니다.

1. And 11을 "타겟팅" 하였을 경우(targetSdkVersion 30) : https://developer.android.com/about/versions/11/behavior-changes-11?hl=ko

 

동작 변경사항: Android 11을 타겟팅하는 앱  |  Android 개발자  |  Android Developers

모든 앱에 영향을 주는 Android 11의 변경사항을 알아봅니다.

developer.android.com

2. And 11에서 "실행될 수" 있도록 지원(targetSdkVersion과 관계없이) : https://developer.android.com/about/versions/11/behavior-changes-all?hl=ko

 

동작 변경사항: 모든 앱  |  Android 개발자  |  Android Developers

Android 11을 타겟팅하는 앱에 영향을 주는 Android 11의 변경사항을 알아봅니다.

developer.android.com

위의 두개념이 좀 헷갈렸지만, 전자의 경우는 targetSdkVersion을 30으로 설정했을 경우. 후자의 경우는 targetSdkVersion이 29이더라도 And11에서 앱이 실행될수 있도록 지원해주는 것을 의미합니다. 

결론은 둘다 적용하면 됩니다.

 

앱에서 수정해야 하는 부분 파악

1. And 11을 "타겟팅" 하였을 경우(targetSdkVersion 30) 

1-1. Android 11의 저장소 업데이트

https://developer.android.com/about/versions/11/privacy/storage?hl=ko#scoped-storage

 

Android 11의 저장소 업데이트  |  Android 개발자  |  Android Developers

Android 11(API 수준 30)에서는 플랫폼을 한층 더 강화하여 외부 저장소의 앱 및 사용자 데이터를 더욱 안전하게 보호합니다. 이 버전에는 미디어의 원시 파일 경로 액세스 선택, 미디어의 일괄 수

developer.android.com

1-1-1. 범위 지정 저장소 적용

targetSdkVersion을 30(Android 11)으로 변경됨으로서 requestLegacyExternalStrorage 플래그를 무시하고 동작합니다.

requestLegacyExternalStorage 플래그를 제거 해도 정상적으로 동작하는지 확인이 필요합니다.

 

1-1-1-1. Android 10과 호환성 유지

target이 30이 되었으므로, requestLegacyExternalStrorage 플래그를 무시해버릴것으로 생각 됩니다.

target 30, 실제 단말 OS 10 일 경우, 플래그값이 어떻게 처리 되는지 확인이 필요합니다.

 

1-1-1-2. 범위 지정 저장소 사용 시 표시되는 디렉터리로 데이터 이전

target 29 일때 저장해둔 파일을 target30 일때도 동일하게 가져와 사용할 수 있는지 확인이 필요합니다.

 

1-1-1-3. 범위 지정 저장소 테스트

실제 테스트할때 버전을 올리고 내리고 하는것이 아니라, targetSdkVersion을 30(Android 11)으로 변경하고, 

위의 2개의 플래그를 해제하여, 기존 저장소를 사용. 위의 2개의 플래그 설정을 해서 범위 지정 저장소 사용하는 방식으로 테스트 하면 될 것 같습니다.

 

1-1-2. 기기 저장용량 관리

앱이 기기 저장용량을 관리해야 한다면, 사용하면 될것 같습니다. 

수정하려는 앱은 저장용량을 관리해야 할 정도로, 저장 데이터가 많지 않으므로, 상관이 없습니다.

 

1-1-3. 외부 저장소의 앱별 디렉터리

외부 저장소에 앱별 디렉터리를 생성할 수 없습니다. 수정하려는 앱에서 자체 앱별 디렉터리를 사용하지 않으므로, 상관 없습니다.

 

1-1-4. 미디어 파일 액세스

1-1-4-1. 일괄 작업 실행

미디어 파일 액세스 하는 메서드가 여러 추가되었다고 합니다. 수정하려는 앱에서는 파일을 저장하고 외부 앱을 호출해 파일을 읽어주고, 삭제하는 기능밖에 없으므로, 별도의 추가 메서드가 필요없습니다.

https://developer.android.com/training/data-storage/shared/media?hl=ko#manage-groups-files

 

공유 저장소의 미디어 파일에 액세스  |  Android 개발자  |  Android Developers

많은 앱에서 더욱 풍부한 사용자 환경을 제공하기 위해 사용자가 외부 저장소 볼륨에서 사용 가능한 미디어를 제공하고 액세스할 수 있게 합니다. 프레임워크는 미디어 저장소라고 하는 미디어

developer.android.com

 

1-1-4-2. 직접 파일 경로 및 네이티브 라이브러리를 사용하여 파일에 액세스

MediaStore 이외에 API를 사용해서 직접 파일 경로를 통해 공유 저장소 미디어 파일에 액세스가 가능하다고 합니다.

  • File API
  • 네이티브 라이브러리(예: fopen())

위의 두 API를 사용하고 있다면 고려해봐야 합니다.

java.io.File 을 사용중이므로, 그대로 사용하여도 이상없는지 확인이 필요합니다.

 

1-1-5. 다른 앱의 데이터 액세스

다른앱의 데이터에 액세스 하지 않기 때문에 상관 없습니다.

 

1-1-5-1. 내부 저장소의 데이터 디렉터리 액세스

다른앱의 데이터에 액세스 하지 않기 때문에 상관 없습니다.

 

1-1-5-2. 외부 저장소의 앱별 디렉터리 액세스

다른앱의 데이터에 액세스 하지 않기 때문에 상관 없습니다.

 

1-1-6 문서 엑세스 제한

1-1-6-1. 디렉터리에 액세스

ACTION_OPEN_DOCUMENT_TREE  인텐츠 작업으로 일부 디렉터리에 관한 액세스 권한을 요청할 수 없습니다.

수정하려는 앱에서는 사용하지 않기 때문에, 상관 없습니다.

 

1-1-6-2. 파일에 액세스

 ACTION_OPEN_DOCUMENT_TREE 또는 ACTION_OPEN_DOCUMENT 인텐트 작업 사용시 제한이 생겼습니다.

수정하려는 앱에서는 사용하지 않기 때문에, 상관 없습니다.

 

1-1-6-3. 변경사항 테스트

 

1-1-7. 권한

1-1-7-1. 임의의 버전 타겟팅

targetSdkVersion과 관계없이, 단말의 OS가 Android 11 일 경우를 이야기합니다.

  • 권한명이 변경 됩니다. 저장소 런타임 권한 > 파일 및 미디어
  • READ_EXTERNAL_STORAGE 권한 요청시 대화상자가 변경됩니다.

대화상자 내용만 변경된것이라 상관 없습니다.

 

1-1-7-2. Android 11 타겟팅

targetSdkVersion 30으로 설정시, 고려사항입니다.

Android 10 이상의 기기에서 저장소 권한을 요청하지 않고도 MediaStore.DownLoads 와 같은 파일에 접근이 가능하다고 합니다. 예를 들어 카메라 앱을 개발하고 있다면 미디어 저장소에 쓰고 있는 이미지를 앱이 소유하고 있으므로 저장소 관련 권한을 요청할 필요가 없습니다.

요약하자면, 내 앱이 미디어 저장소에 쓰는 파일을 내앱에서 사용하는 경우에 저장소 관련 권한이 필요없습니다. 하지만, 다른앱이 생성한 파일에 접근하기 위해서는 여전히 권한이 필요합니다. 

Android 9 이하를 앱이 지원한다면, 저장소 권한을 그대로 요청해주어야 합니다. 다만 10이상에서는 필요없을 수 있으므로, 아래 개발자 가이드를 참조해서 권한에 maxSdkVersion을 설정해주어야 할듯 합니다. 파일 읽고 쓰기 권한이 설정되어 있으므로, 확인이 필요합니다.

https://developer.android.com/training/data-storage/shared/media?hl=ko#scoped_storage_enabled

 

공유 저장소의 미디어 파일에 액세스  |  Android 개발자  |  Android Developers

많은 앱에서 더욱 풍부한 사용자 환경을 제공하기 위해 사용자가 외부 저장소 볼륨에서 사용 가능한 미디어를 제공하고 액세스할 수 있게 합니다. 프레임워크는 미디어 저장소라고 하는 미디어

developer.android.com

1-1-8. 모든 파일 액세스

백신관련이나, 파일관리와 같이 특수한 앱에서만 적용하면 될것같습니다. 모든 파일에 대한 엑세스를 주는것인데, 수정하려는 앱에는 해당없습니다.

 

1-2. 권한 자동 초기화

https://developer.android.com/about/versions/11/privacy/permissions?hl=ko#auto-reset

1-2-1. 일회성 권한

위치, 마이크, 카메라 관련 권한은 요청할때 마다 사용자에게 표시되는 "이번만 허용"이라는 옵션이 생깁니다. 따라서, 각각의 기능을 사용하는곳에서 매번 권한을 체크 해주고 있는지 확인이 필요합니다.

 

1-2-2. 사용하지 않는 앱의 권한 자동 재설정

몇달동안 사용자가 앱을 사용하지 않았을 경우, 민감한 권한을 자동으로 재설정합니다. 사용자가 "거부"를 선택한 것과 동일한 수준으로 효과를 발휘하기에, 위와 동일하게 권한이 필요한 곳에서 매번 권한을 체크 해주고 있는지 확인이 필요합니다.

민감한 권한은 https://developer.android.com/reference/android/Manifest.permission?hl=ko 페이지에서 protection level : dangerous 인 권한들입니다.

 

1-2-3. 권한 대화상자 공개 상태

사용자가 권한 대화상자에서 "거부"를 두번 눌렀을 경우 시스템 대화상자가 사용자에게 표시되지 않습니다. "다시 묻지 않음"을 선택한것과 동일하게 동작합니다.

사용자가 거부를 2번 눌렀을 경우, 설정에서만 권한 여부를 설정할 수 있으므로, 설정에서 권한 변경할 수 있도록 유도해주는 시나리오가 필요합니다. 이런 시나리오가 있는지, 없다면 요청할 수 있도록 확인이 필요합니다.

 

1-2-4. 시스템 알림 창 변경사항

SYSTEM_ALERT_WINDOW 권한을 사용하지 않으므로, 상관없습니다.

 

1-2-5. 전화번호

위의 2 메서드를 사용한다면, READ_PHONE_STATE 대신 READ_PHONE_NUMBERS 권한을 요청해야 합니다.

Android 10 이하에서는 여전히 READ_PHONE_STATE를 사용해야 하므로, READ_PHONE_STATE를 maxSdkVersion 29까지 사용하도록 설정하고, 11이상부터는 READ_PHONE_NUMBERS를 사용하도록 해주어야 합니다.

 

 

1-3. 백그라운드 위치 액세스

https://developer.android.com/about/versions/11/privacy/location?hl=ko#background-location

 

Android 11의 위치 업데이트  |  Android 개발자  |  Android Developers

사용자 개인정보 보호를 강화하기 위해 Android 11에서는 일회성 위치 액세스 권한을 추가하고 사용자가 백그라운드 위치 액세스 권한을 부여하는 방식을 변경합니다. 이러한 업데이트는 Android 1

developer.android.com

수정하려는 앱은 포그라운드 위치 서비스만 사용하고 있으므로, 상관 없습니다. 

"이번만 허용"옵션에 대한 처리만 해주면 될듯 합니다.

백그라운드 위치 액세스 권한이 필요할 경우 검토가 필요합니다.

 

1-4. 패키지 공개 상태

https://developer.android.com/about/versions/11/privacy/package-visibility?hl=ko

 

Android 11의 패키지 공개 상태  |  Android 개발자  |  Android Developers

Android 11에서는 앱이 사용자가 기기에 설치한 다른 앱을 쿼리하고 상호작용하는 방법을 변경합니다. 요소를 사용하여 앱은 액세스할 수 있는 다른 패키지 집합을 정의할 수 있습니다. 이 요소를

developer.android.com

내 앱에서 엑세스할수 있는 다른 패키지 집합을 정의할 수 있게 되었습니다.

현재 수정하려는 앱은 다른 앱으로부터 불려지거나, 작업을 처리하여 호출한 앱을 다시 호출하는 기능이 포함되어있습니다. 

다른 앱이 내 앱에 표시되는지와 관계없이 암시적, 명시적 인텐트를 사용해서 다른앱의 활동을 시작할 수 있으므로, 고려해야 하는 대상이 아닙니다. 

다른 앱에서 수정하려는 앱을 호출가능한지 정도만 확인해보면 될것 같습니다.

 

1-5. 보안

1-5-1. 힙 포인터 태그하기

포인터의 최상위 바이트에 정보를 잘못 저장하는 Android 앱은 MTE(Memory Tagging Extention) 지원 기기에서 작동이 중단 될 수 있습니다. 64비트 버전의 앱에서 테스트가 가능하다고 합니다.

포인터 태그 지정기능을 사용하고 있지 않아, 상관없습니다. 만약 이러한 에러가 보고된다면 targetSdkVersion 30에서는 "이스케이프 해치"가 제공된다고 하니, 적용하여 해결하면 될것같습니다. 기존처럼 동작하게 만들어주는 설정으로 추후에 사라진다고 하니, 임시방편으로만 사용이 가능할 것으로 보입니다.

https://source.android.com/devices/tech/debug/tagged-pointers?hl=ko#developer-support

 

태그가 지정된 포인터  |  Android 오픈소스 프로젝트  |  Android Open Source Project

 

1-6. 토스트 메시지 업데이트

1-6-1. 백그라운드에서 맞춤 토스트 메시지가 차단됨

백그라운드에서 토스트 메시지 노출시, 시스템이 이를 차단할 수 있다고 합니다. 텍스트 토스트 메시지는 여전히 허용된다고 합니다.

setView를 호출하는 토스트 메시지만 해당 되는것 같습니다.

수정하려는 앱에서는 setView를 사용하는 토스트 메시지를 사용하고 있지않으므로, 상관 없습니다.

 

1-6-2. 토스트 메시지 콜백

토스트 메시지가 사라질때의 동작을 정의할 수 있는 addCallback 메서드가 추가 됩니다. API 30 이후에 추가 되었으므로, 30 이전 버전에서는 setOnDismissListener를 계속 사용해야 합니다. 

 

1-6-3. 텍스트 토스트 메시지 API 변경사항

위의 메서드를 사용하고 있다면, 사용하지 않도록 수정이 필요합니다.

 

1-7. 연결

 텔레포니 제공자 APN 데이터베이스를 읽거나 데이터베이스에 액세스하려면 Manifest.permission.WRITE_APN_SETTINGS 독점 권한이 있어야 합니다. 수정하려는 앱에서는 사용하지 않으므로, 상관없습니다.

 

1-8. 접근성

1-8-1. 매니페스트 파일에서 TTS 엔진과의 상호작용 선언

TTS 사용시 고려 대상입니다. 사용하지 않으므로, 상관 없습니다.

 

1-8-2. 메타데이터 파일에서 접근성 버튼 사용 선언

소프트웨어에서 렌더링한 탐색 영역을 사용하며 Android 8.0(API 수준 26) 이상을 실행하는 기기에는 탐색 메뉴 오른쪽에 접근성 버튼이 있습니다. 사용자가 이 버튼을 누르면 현재 화면에 표시된 콘텐츠에 따라 사용 설정된 여러 접근성 기능 및 서비스 중 하나를 호출할 수 있습니다.

위의 기능을 하는 접근성 버튼이 있는데, 이를 사용한다면 고려해야 하는 내용입니다. 지원하지 않는 기능이므로, 상관없습니다.

 

1-9. 카메라

위의 3가지 인텐트를 사용해서 카메라를 호출할 경우, 기본카메라 만을 사용할 수 있습니다. 다른 카메라 앱을 사용하려면 명시적 인텐트 호출을 이용하면 됩니다.

 

1-10. 앱 패키징 및 설치

1-10-1. 압축된 리소스 파일

압축된 resources.arsc 파일을 포함하거나, 파일이 4바이트 경계에 정렬되지 않으면(?) 설치가 불가능하다고 합니다.

해당 사항없어, 상관 없습니다.

 

1-10-2. 이제 APK 서명 체계 v2가 필요함.

서명 체계 v2를 이전부터 사용했었기 떄문에, 상관 없습니다.

 

1-11. Firebase

Android 6.0 (API 23) 이상에서 Firebase JobDispatcher 및 GcmNetworkManager API 호출이 사용 중지됩니다.

사용하지 않고 있으므로 상관없습니다.

 

1-12. 기기 간 파일 전송

allowBackUp 속성을 사용해 백업시 앱파일의 클라우드 기반 백업 및 복원을 막거나 허용할 수 있습니다. default값은 true(백업 허용)이므로, 검토가 필요합니다.

 

 

1-13. OnSharedPreferenceChangeListener의 콜백 변경사항

Editor.clear를 사용할 경우 OnSharedPreferenceChangeListener.onSharedPreferenceChanged로 콜백이 실행됩니다.

Editor.clear를 사용하지 않으므로, 상관 없습니다.

 

1-14. 비 SDK 인터페이스 제한사항

아래 링크에서 한가지 방법을 사용해 테스트가 필요해 보입니다. 비 SDK 메서드 또는 필드를 사용하면 앱이 중단될 가능성이 높아지므로 추가 확인이 필요합니다.

https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces?hl=ko#test-for-non-sdk

 

비 SDK 인터페이스 제한사항  |  Google Play  |  Android Developers

Android 9(API 수준 28)부터 플랫폼에서는 앱에서 사용할 수 있는 비 SDK 인터페이스가 제한되어 있습니다. 이러한 제한사항은 앱에서 비 SDK 인터페이스를 참조하거나 리플렉션 또는 JNI를 사용해 비 S

developer.android.com

 

2. And 11에서 "실행될 수" 있도록 지원(targetSdkVersion과 관계없이) : 

2-1. 개인정보 보호

2-1-1. 일회성 권한

"이번만 허용" 선택에 대한 처리입니다.

위에서 타겟설정시 고려했으면, 추가적으로 고려할 사항이 없습니다.

 

2-1-2. 권한 대화상자 공개 상태

"다시 묻지 않음" 선택에 대한 처리입니다.

위에서 타겟설정시 고려했으면, 추가적으로 고려할 사항이 없습니다.

 

2-1-3. 데이터 액세스 분석

앱은 다음 이벤트 중 하나가 발생할 때마다 작업을 실행할 AppOpsManager.OnOpNotedCallback 인스턴스를 등록할 수 있습니다.

  • 앱의 코드가 비공개 데이터에 액세스합니다. 이벤트를 호출한 앱의 로직 요소를 확인하려면 속성 태그별 데이터 액세스를 분석하면 됩니다.
  • 종속 라이브러리 또는 SDK의 코드가 비공개 데이터에 액세스합니다.

비공개 데이터에 액세스 하는것을 알수 있는 방법이 추가되었습니다. 해당 방법을 사용할지에 대해서는 추가적인 고려가 필요해보입니다.

 

2-1-4. 시스템 알림 창 권한

사용자를 시스템 설정의 화면으로 이동 시키는 권한, 인텐트 작업에 대한 내용입니다.

위에서 타겟설정시 고려했으면, 추가적으로 고려할 사항이 없습니다.

 

2-1-5. 영구적 SIM 식별자.

Android 11 이상에서는 getIccId() 메서드를 통해 iccid 액세스가 제한됩니다. 대신 getSubscriptionId() 메서드를 사용하여, 대체가 가능해집니다. 

수정하려는 앱에서는 OS 9 미만에 대해서만 getIccId메서드를 사용하고 있어, 상관 없습니다. (Android 11에서는 getIccId 미사용이므로 고려하지 않습니다.)

 

2-2. 노출 알림

Android 11은 노출 알림 시스템을 염두에 두고 플랫폼을 업데이트합니다. 이제 사용자는 기기 위치 설정을 켜지 않고도 Android 11에서 노출 알림 앱을 실행할 수 있습니다.  노출알림을 검색해보니 코로나 19 확진자와 접촉했을때, 알려주는 시스템이라고 합니다. 이런 유사한 서비스를 제공하고 있지않기에, 상관 없습니다.

 

2-3. 보안

2-3-1. SSL 소켓은 기본적으로 Conscrypt SSL 엔진을 사용함

SSLSocket 사용하는 부분을 테스트 해볼 필요가 있는것 같습니다. 내부적으로 빌드되는 과정이 변경되었으므로, 동작에 이상없는지 확인이 필요해보입니다.

 

2-3-2. Scudo 강화 할당자

비정상 종료 보고서에 "Scudo ERROR : " 가 표시되어 있다면 https://source.android.com/devices/tech/debug/scudo?hl=ko#Troubleshooting 링크에서 해결방법을 찾아보면 될것 같습니다. 추가적으로 고려해야 할 내용은 없습니다.

 

2-3-3. 앱 사용통계

사용자를 더 잘 보호하기 위해 Android 11은 각 사용자의 앱 사용 통계를 사용자 인증 정보 암호화 저장소에 저장합니다. 따라서 isUserUnlocked() true를 반환하지 않으면 시스템이나 앱은 앱 사용 통계 데이터에 액세스할 수 없습니다. 실제 앱 동작과는 관계가 없으므로, 추가적으로 고려해야할 부분이 없습니다.

 

2-3-4. 5G에 대한 에뮬레이터 지원

5G관련 API가 추가되었습니다. 필요한 기능이 없어 별도로 고려해야 할 부분이 없습니다.

다만 네트워크 타입은 앱에서 받아와 사용중이므로, 네트워크 타입에 5G를 추가해주어야 합니다.

 

2-4. 성능 및 디버깅

2-4-1. JobScheduler API 호출 제한 디버깅

2-4-2. 파일 설명사 새니타이저(fdsan)

디버깅시 좀더 자세하게 할수 있도록, 기능이 추가되었습니다. 이에 대해서는 추가적으로 공부가 필요해보입니다. 앱은 수정사항 없습니다.

 

 

2-5. 비 SDK 인터페이스 제한사항

위에서 타겟설정시 고려했으면, 추가적으로 고려할 사항이 없습니다.

 

2-6. 지도 v1공유 라이브러리 삭제됨

지도 v1공유 라이브러리를 사용하고 있지 않아, 상관 없습니다.

 

2-7. 다른 앱과의 상호작용

2-7-1. 콘텐츠 URI 공유

앱이 다른 앱과 콘텐츠 URI를 공유한다면 인텐트는 FLAG_GRANT_READ_URI_PERMISSION  FLAG_GRANT_WRITE_URI_PERMISSION 인텐트 플래그 중 하나 이상을 설정하여 URI 액세스 권한을 부여해야 합니다.

이미 사용하고 있던 인텐트 플래그 이므로, 추가로 수정해야할 사항은 없습니다.


결과


느낀점

뭔가 많아서 어지럽지만, 개발자문서를 가까이 해야겠다는 생각이 많이 들었습니다. 권한 관련해서도 기존에 개발자 문서에서 제시한 방법으로 개발을 진행하였다면, 추가적으로 고려해야하는 부분이 없습니다. 

항상 새로운 개발을 진행하기 앞서 문서에서 꼭 확인해보고 적용해야 추후 유지보수에 편하다고 직접 느꼈습니다.

'Android_Java' 카테고리의 다른 글

Android Java 상단바(statusbar) 투명 처리  (0) 2021.06.22