목차
- 문제 발생 배경
- 여러 가지 해결 방법
- 가장 간편한 해결 방법
문제 발생 배경
구글 플레이에서 안드로이드 SDK 버전 업그레이드가 강제되면서
Android 13(티라미슈) 으로 어플 버전을 올려 업데이트 하게 되었다.
초반에는 문제 없는 듯 보였으나, 서서히 밀려오는 CS 문의...
" 사진 권한을 동의하라는데 어플 설정에 사진 권한이 없어요. "
뒤늦게 확인해보니 Android 13에서 파일 및 미디어 접근 권한이었던 항목이 이미지, 동영상, 오디오 권한 3가지로 분할 되었던 것이었다.
즉, Android13에선 이전 버전의 코드가 구동이 안된다....(그런 권한은 이제 존재하지 않으니까.....)
그리고 더불어, 기존엔 어플 다운로드 시 알림 on이 디폴트였는데 Android13이 되면서 off가 디폴트가 되었다...
따라서 알림을 보내려면 어플 내에서 권한을 받아야한다는 소리...
머리가 아팠다.... 리액트 네이티브로 개발 중이라 정보도 제한적이었다...
이 글을 보신 분들은 저처럼 고생하지 않길 바라며...
여러 가지 해결 방법
밥법은 총 3가지가 있다.
- RN 버전을 0.70 이상으로 업그레이드하기
- react-native-permissions 라이브러리를 설치 후 사용하기
- patch-package 라이브러리를 통해서 RN 라이브러리를 직접 수동으로 수정(필요한 권한을 강제로 끼워넣기) 후 패치하기
1번은 절대 안 된다. 보자마자 포기했다. RN 버전을 함부로 업그레이드 했다간 사용 중인 라이브러리 버전 안 맞아서 다 충돌나고 그거 하나하나 찾아가며 해결하려하면 배보다 배꼽이 더 커진다. 개발자들의 멘탈과 소중한 머리털을 위해선 이 방법은 기피하는 편이 좋다.
2번은 react-native-permissions 라이브러리를 설치해서 그 안에 있는 권한을 불러와서 사용하는 방법이다. RN 안에 있는 Permission을 관리해주는.. 파일과 내용은 유사하나, RN을 업데이트 할 순 없으니 react-native-permissions 최신 버전을 받아 쓰면 된다. 처음엔 이 방법을 사용해서 사진, 동영상 권한을 받는데엔 성공했다. 근데 희한하게 알림 권한이 죽어도 안 떴다. 왜 안 됐는지는 아직도 모름. 포기하고 3번으로 ㄱㄱ
아 그러면 그냥 RN 안에 있는 권한 파일을 수동으로 수정하면 되는 거 아님??;;
--> 맞다.
복잡하게 갈 필요 없다.... 그냥 필요한 코드만 추가해주고, 협업하는 동료들이 git pull을 받더라도 RN 내부 파일의 수정 사항까지 받아 별도 의 작업이 필요없도록 해주면 된다.
이 과정에서 patch-package라는 라이브러리를 설치해야하는데... 별 거 없다.
가장 간편한 3번으로 문제 해결하기
우선 첫번째로 해야할 것
AndroidManifest.xml 에 새로운 권한 추가 해주기
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
위는 기존에 사용하던 파일 및 미디어 접근 권한이다. 아예 지워버리면 이번엔 역으로
안드로이드13으로 업데이트하지 않은 사용자에게 접근 권한을 받을 수가 없다..... 13 기준으로 분기하여 작업해야한다.
따라서 새로이 추가된 아래의 권한을 추가해준다.
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
차례로 사진 권한, 비디오 권한, 오디오 권한이다. 필요한 권한을 알아서 골라 추가해주면 된다.
+ 알림 권한
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" android:minSdkVersion="33" />
Android13부터 생긴 알림 권한이다. 얘도 같이 추가해주자.
여기까지 해줬다면 두번째로
react-native 라이브러리를 수정해줄 거다.
그리고 아래 파일을 찾아서 잘 들어가라.
node_modules/react-native/Libraries/PermissionAndroid/PermissionAndroid.js
그럼 이런 파일이 나올 것이다.
여기 Object.freeze 객체 안에 새 권한을 추가해주자!
READ_MEDIA_IMAGES: 'android.permission.READ_MEDIA_IMAGES',
READ_MEDIA_VIDEO: 'android.permission.READ_MEDIA_VIDEO',
READ_MEDIA_AUDIO: 'android.permission.READ_MEDIA_AUDIO',
POST_NOTIFICATIONS: 'android.permission.POST_NOTIFICATIONS', // 알림
이렇게!!!!
그리고 끝이 아니고 추가해준 permission의 type을 지정해줘야 한다.
스크롤 좀 내리면,
나오는 이 부분에
READ_MEDIA_IMAGES: string,
READ_MEDIA_VIDEO: string,
READ_MEDIA_AUDIO: string,
POST_NOTIFICATIONS: string,
를 넣어주면 된다.
이렇게!!
그럼 끝임. 이제 협업하는 동료들을 위한 일 하나만 해주면 된다.
마지막 단계
npm install patch-package
npx patch-package react-native
그리고 package.json 에 들어가서
아래 내용을 추가 해준다.
"scripts": {
"postinstall": "patch-package"
}
.patch 파일이 같이 만들어졌을 것이다.
라이브러리 수정 내용을 파악할 수 있다.
그러면 끝이다.
코드 적용은 대충 아래와 같은 식으로.... 현재 권한 상태에 따라 원하는 대로 작업하면 될 듯하다.
import React, { Component } from "react";
import { PermissionsAndroid } from "react-native";
export default class SplashScreen extends Component {
.
.
.
.
async checkAlarm() {
try {
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS);
console.log("granted", granted);
} catch (error) {
console.log(error);
}
}
}
참고로, 알림 같은 경우 해당 권한은 Android13 미만에선 없기 때문에 분기를 해주지 않아도 상관이 없다.
(없으니까 안 뜸) 그러나 사진, 동영상, 오디오 같은 경우엔
Androdi 13을 기점으로 권한 명 자체가 다르기 때문에
분기를 제대로 안 해주면 특정 버전이 권한을 받아올 수 없는 불상사가 발생한다.
따라서
const granted =
// 아래는 react-native-permissions 라이브러리 사용한 코드
// react-native-permissions에서 import
// Platform.Version < 33
// ? await request(PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE)
// : await request(PERMISSIONS.ANDROID.READ_MEDIA_IMAGES);
// 아래는 RN PermissionAndroid 모듈 사용한 코드 (해당 글에 작성한 방식)
Platform.Version < 33
? await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE) //RN에서 import
: await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_MEDIA_IMAGES);
위와 같은 형태로 33을 기준으로 코드를 분기해주어야한다. (sdk33 이 Android13이다)
Platform은 react-native 라이브러리에서 import 해온 것이다.
참고한 블로그
https://jake-seo-dev.tistory.com/259