Expo의 ImagePicker를 Android 용으로 빌드하는 데 필요한 권한 정보

이 기사의 간략한 요약



create-react-native-appexpo 에서 카메라 앱을 만들 때 ImagePicker 을 사용한 경우 Android용으로 build할 때는 app.json 에 다음과 같은 permission 을 지정해야 한다.

app.json
{
  "expo": {
    ・・・,
    "android": {
      ・・・,
      "permissions": [
        "CAMERA",
        "READ_EXTERNAL_STORAGE",
        "WRITE_EXTERNAL_STORAGE"
      ]
    }
  }
}

문제점



Expo의 공식 페이지와 같이 ImagePicker를 사용할 때는 먼저 소스 코드에 permission을 취득하기 위한 처리가 필요합니다.
askAsync 함수는 필요한 permission이 없는 경우에 유저에게 확인 다이얼로그를 표시해, permission를 취득하는 함수입니다만, 원래 android측에서 앱에 허가하고 있지 않으면 확인 다이얼로그조차 나오지 않았습니다.
expo 앱을 사용하여 디버깅할 때는 expo 앱 자체로 설정되어 있으므로 괜찮습니다만, 자작 앱이라고 설정할 필요가 있습니다.
  • 샘플 코드

  • App.js
    import * as React from 'react';
    import { Button, Image, View } from 'react-native';
    import * as ImagePicker from 'expo-image-picker';
    import Constants from 'expo-constants';
    import * as Permissions from 'expo-permissions';
    
    export default class ImagePickerExample extends React.Component {
      state = {
        image: null,
      };
    
      render() {
        let { image } = this.state;
    
        return (
          <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Button
              title="Run camera"
              onPress={this._takePhoto }
            />
            {image &&
              <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
          </View>
        );
      }
    
      _takePhoto = async () => {
        let res = await Permissions.askAsync(Permissions.CAMERA_ROLL)
        if (res.status !== 'granted') {
          console.log('require camera permission')
          return
        }
        res = await Permissions.askAsync(Permissions.CAMERA)
        if (res.status !== 'granted') {
          console.log('require camera permission')
          return
        }
    
        let result = await ImagePicker.launchCameraAsync({
          allowsEditing: false,
        });
    
        if (!result.cancelled) {
          this.setState({ image: result.uri });
        }
      }
    }
    
  • 확인 대화 상자의 예

  • ※통상은 이하와 같은 다이얼로그가 나옵니다만, Android 어플리로서 자작 어플리를 빌드하면 permission이 없으면 확인조차 되지 않고, 거부됩니다.



    해결 방법



    expo build:android 명령으로 빌드할 때 사용하는 app.json 파일에 android에서 사용할 permission을 지정해 줍니다.
    나를 위해 한 느낌이라면 다음 3 가지는 필수였습니다.
  • app.json의 전체 용도

  • app.json
    {
      "expo": {
        "name": "test",
        "slug": "test-app",
        "privacy": "public",
        "sdkVersion": "35.0.0",
        "platforms": [
          "ios",
          "android",
          "web"
        ],
        "version": "1.0.0",
        "orientation": "portrait",
        "icon": "./assets/icon.png",
        "splash": {
          "image": "./assets/splash.png",
          "resizeMode": "contain",
          "backgroundColor": "#ffffff"
        },
        "updates": {
          "fallbackToCacheTimeout": 0
        },
        "assetBundlePatterns": [
          "**/*"
        ],
        "ios": {
          "supportsTablet": true
        },
        "android": {
          "package": "com.example",
          "versionCode": 1,
          "permissions": [
            "CAMERA",
            "READ_EXTERNAL_STORAGE",
            "WRITE_EXTERNAL_STORAGE"
          ]
        }
      }
    }
    

    ※참고: Android 앱 빌드 방법


    cd /path/to/your/app
    expo build:android -t app-bundle
    # expoのURLからaabファイルをダウンロード
    # aabファイルをGoogle Play Consoleからアップロード
    

    소감



    샘플 사이트만이라면 잡히지 않기 때문에 버그라고 깨닫기 어려운 것과, ImagePicker의 경우 어느 permission를 지정해 주면 좋을지를 알기 어려웠습니다.
    또한 expo 앱을 사용하면 제대로 작동하므로 확인이 어려웠습니다.

    좋은 웹페이지 즐겨찾기