티스토리 뷰

Android에서 카메라로 사진을 찍어 사진 데이터를 처리할 수 있는 방법은 크게 2가지로 나눌 수 있다. 

  1.  Intent로 단말의 카메라 앱을 실행한 후 결과 사진을 받아 처리하기
  2. 앱 화면에 카메라 미리보기를 보여주고 직접 사진을 찍어 처리하기

 

우선 Intent 객체를 이용하여 카메라 앱을 실행한 뒤, 그 결과 데이터를 받아 처리하는 방법을 먼저 해보자.


카메라를 켜고, 사진을 저장할 때 외부 저장소에 데이터를 넣고 읽어들일 수 있어야 하므로 Manifest 파일에 해당 권한을 작성한다. 

 

또한 제작한 앱에서 사진을 저장하고, 저장된 사진을 파일관리자에서 불러와야 하기 때문에 내용 제공자도 아래와 같이 추가해준다.

 

◎AndroidManifest.xml

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

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

    <uses-feature android:name="android.hardware.camera" />

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/Theme.SampleCamera">
        <provider android:authorities="com.example.samplecamera.intent.fileprovider" android:name="androidx.core.content.FileProvider"
                  android:exported="false"
                  android:grantUriPermissions="true">
                  <meta-data
                      android:name="android.support.FILE_PROVIDER_PATHS"
                      android:resource="@xml/external"/>
        </provider>
        
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

 

다음에는 Intent 객체를 만들어 Activity를 띄운 뒤, 결과 값을 받을 때 Intent 객체가 해당 카메라 앱에서 내용 제공자를 통해 제공하는 데이터를 사용할 수 있게 설정해주는 코드를 작성하면 된다. 

 

전부 이전 포스팅에 있는 내용이니 따로 부가 설명은 생략한다.

 

◎MainActivity.java

package com.example.samplecamera;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import androidx.core.content.FileProvider;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.runtime.Permission;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    ImageView imageView;
    File file;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AndPermission.with(this)
                .runtime()
                .permission(Permission.READ_EXTERNAL_STORAGE,
                        Permission.WRITE_EXTERNAL_STORAGE,
                        Permission.CAMERA
                        )
                .start();

        imageView = findViewById(R.id.imageView);
        Button button = findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                takePicture();
            }
        });
    }

    public void takePicture() {
        if(file == null) {
            file = createFile();
        }
        
        // 카메라 앱에서 공유하여 사용할 수 있는 파일 정보를 Uri 객체로 만들 수 있다
        Uri fileUri = FileProvider.getUriForFile(this, "com.example.samplecamera.intent.fileprovider", file);
        
        // 생성된 Uri 객체를 인텐트에서 부가 데이터로 사용할 수 있게 설정
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

        // Intent 에서 지정한 Activity가 있을 때
        if(intent.resolveActivity(getPackageManager()) != null) {
            mGetContent.launch(intent);
        }
    }

    private File createFile() {
        String filename = "capture.jpg";
        File storageDir = this.getExternalCacheDir();

        return new File(storageDir, filename);
    }


    ActivityResultLauncher<Intent> mGetContent = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                if(result.getResultCode() == Activity.RESULT_OK) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = 8;
                    Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);

                    imageView.setImageBitmap(bitmap);
                }
            }
        });
}

 

Comments