본문 바로가기

Android

[Android] 홍드로이드 기초 강의 - Camera 촬영 및 Image 가져오기_환경설정

카카오톡에서 사진을 보낼 때 2가지 방법이 있습니다.

하나는 앨범에서 이미지를 가져오는 것이고, 다른 하나는 이미지를 촬영해서 보내는 방법입니다.

여기서 이미지를 촬영해서 보내는 방법을 선택하면 "카메라 - 사진 촬영 - 카메라 어플 실행"의 과정을 거칩니다.

 

이처럼 앱에서 기본 카메라를 실행 및 촬영하고, 이미지를 앱으로 가져오는 기능을 학습했습니다.

기초 강의라고 하기엔 코드가 길고 설명이 부족한 요소들이 다소 있어서 환경설정 파트와 Main 코드 파트로 나누어서 작성할 계획입니다.

1. 권한 허용 라이브러리 적용 및 Manifest 설정

이번에 학습한 예제가 카메라와 저장장치에 대한 접근 권한이 필요한 앱입니다.

Android 6.0 마시멜로 버전부터는 권한 허용/거부 프로세스가 강화되어 사용하기 까다로워졌습니다.

다행히 해당 문제를 해결하는 TedPermission 라이브러리를 만들어서 배포해주신 "박상권" 개발자님 덕분에 쉽게 해결할 수 있었습니다.

 

먼저 카메라 및 저장장치 읽기/쓰기 권한을 Manifest에 등록해야 합니다.

AndroidManifest.xml 파일로 가서 <uses-permission ...> 코드를 추가합니다.

 

1) app - manifest - AndroidManifest.xml 파일

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.패키지명">

    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    <application
    	...
        
    </application>
</manifest>

 

permission.CAMERA는 이름에서 알 수 있듯이 카메라를 사용하기 위한 권한입니다.

 

permission.WRITE_EXTERNAL_STORAGEpermission.READ_EXTERNAL_STORAGE는 공용 외부 저장소에 저장된 이미지에 대한 쓰기/읽기 권한입니다.

Android 카메라 애플리케이션은 원본 크기의 이미지를 공용 외부 저장소에 저장합니다.

저장소는 모든 앱이 접근할 수 있는데 이때 필요한 권한들이 바로 WRITE(READ)_EXTERNAL_STORAGE입니다.

※ 쓰기 권한은 암묵적으로 읽기를 허용하므로 외부 저장소에 쓰려면 WRITE 권한만 요청해도 무방하다고 합니다.

 

다음으로 build.gradle로 가서 tedpermission 라이브러리를 사용할 것을 명시합니다.

 

2) Gradle Scripts - build.gradle(:app) - dependencies {}

android {
    ...
}

dependencies {
    ...
    implementation 'io.github.ParkSangGwon:tedpermission:2.3.0'
    ...
}

 

코드를 작성하면 우측 상단에 파란 글씨로 'Sync Now'가 활성화된 것을 볼 수 있습니다.

해당 버튼을 눌러주고 빌드되기를 기다립니다.

 

※ 참고로 강의 영상에서 추가하는 코드는 'gun0912.ted:tedpermission:2.0.0'입니다.

이 코드는 jcenter[각주:1]에서 라이브러리를 가져오겠다는 의미인데 jcenter가 서비스 종료를 선언했습니다.

안전한 사용을 위해 MavenCentral에서 라이브러리를 가져왔습니다.

 

2. 화면 구성(xml)

기능을 알아보기 위한 예제이므로 화면은 알아보기 쉽게 구성되어 있습니다.

LinearLayout 안에 독립된 LinearLayout 2개를 생성합니다.

하나의 LinearLayout에는 ImageView가 포함되고 다른 하나의 LinearLayout에는 Button이 있습니다.

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1">
        <ImageView
            android:id="@+id/iv_result"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <Button
            android:id="@+id/btn_capture"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="촬영"/>
    </LinearLayout>
</LinearLayout>

 

화면은 다음과 같습니다.

 

 

3. 파일 공유 설정

앱에서 다른 앱으로 안전하게 파일을 제공하려면 파일에 보안 핸들을 콘텐츠 URI 형태로 제공해야 한다고 Android 공식 문서에 나와 있습니다.

개발자가 XML에서 제공하는 사양에 맞춰서 파일의 콘텐츠 URI를 생성하는 구성요소가 바로 FileProvider입니다.

 

FileProvider를 지정하려면 Manifest에 <provider> 요소를 추가해줘야 합니다.

 

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.cameraexample_fixed">

    ...

        <provider
            android:authorities="본인 프로젝트의 패키지명"
            android:name="androidx.core.content.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">

            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
    </application>
</manifest>

 

위의 코드에서 <meta-data>란 공유하려는 directory를 지정하는 XML 파일입니다.

공유 디렉터리를 생성하는 방법은 간단합니다.

 

1) res 디렉터리 하위에 xml 디렉터리 생성

2) xml 디렉터리에 file_path.xml 파일 생성

3) file_path.xml의 코드를 아래의 코드로 변경

 

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="my_images"
        path="Android/data/본인 프로젝트의 패키지명/files/Pictures"/>
</paths>

 

본인 프로젝트의 패키지명은 build.gradle(:app)에서 android - defaultConfig의 applicationId로 확인할 수 있습니다.

저의 경우 CameraExample_fixed로 프로젝트명을 지정해서 아래와 같이 나타납니다.

 

android {
    compileSdk 31

    defaultConfig {
        applicationId "com.example.cameraexample_fixed"
        minSdk 21
        targetSdk 31
        versionCode 1
        versionName "1.0"
    
        ...
        
    }
    ....
}

 

설정해야 하는 부분들은 여기까지 입니다.

빠른 시일 내에 Main 코드 부분도 작성해서 올리겠습니다.

 

※ 참고

https://developer.android.google.cn/training/camera/photobasics?hl=ko#java 

 

사진 촬영  |  Android 개발자  |  Android Developers

이 과정에서는 기존 카메라 애플리케이션을 사용하여 사진을 캡처하는 방법을 설명합니다. 클라이언트 앱을 실행하는 기기에서 촬영한 하늘 사진을 조합하여 세계 날씨 지도를 만드는 크라우

developer.android.google.cn

https://developer.android.com/training/secure-file-sharing/setup-sharing?hl=ko 

 

파일 공유 설정  |  Android 개발자  |  Android Developers

파일 공유 설정 앱에서 다른 앱으로 파일을 안전하게 제공하려면 파일에 보안 핸들을 콘텐츠 URI 형태로 제공하도록 앱을 구성해야 합니다. Android FileProvider 구성요소에서는 개발자가 XML에서 제

developer.android.com

 

  1. 오픈 소스 라이브러리를 공유하는 공개 repository [본문으로]