본문 바로가기
코딩과 알고리즘

크레이의 앱개발 도전기 #3. startActivityForResult 가 없어졌다구?!

※ 이 게시글은 크레이의 IT개발 관련 성장기를 다루고 있습니다. 관련지식이 약간 있어야 이해되실 수 있습니다. 가벼운 마음으로 읽어보시면서 흥미가 생기고 의욕이 생긴다면? 개발자의 자질이 있으신 겁니다 :)

오늘은 뭘 해볼까~ 구름 에듀 강좌를 차례대로 따라하던 중, 음? 왜 안되지?.. 문제가 생겼네요.

https://edu.goorm.io/learn/lecture/15564/현직개발자가-알려주는-안드로이드-앱-개발/lesson/727133/11-카메라

위 강좌를 따라하다 보면 중간에 막히게 되는데요.
이 것 저 것 알아 보니 액티비티라는 안드로이드 앱 화면을 이동할 때 사용하는 명령어 중 하나가
startActivityForResult 라는게 있는데 그 명령어가 글쎄... 없어져 버렸답니다. ( 뭐라고?! )
보통 이런 경우 명령어가 deprecated 되었다고 합니다.

뭐 별 수가 있나요? 이제 다른 방법을 사용해야 합니다.
registerForActivityResult 라는 명령어를 사용해야 하는 것이지요.
근데 사용방법이 꽤 달라서 원래 강의에 있던 라이브러리는 사용할 수 없습니다.

이 참에 차례대로 하나씩 익히기로 했는데요.
오늘 내용은 앱에서 촬영 버튼을 누르면 카메라 앱을 실행해서 사진을 찍고 가져오는 코드를 공유합니다.
딱 거기까지만입니다 :)

아래 두 분의 게시글을 참고하였습니다.

https://www.youtube.com/watch?v=YtfAAImkLQM
https://aries574.tistory.com/294


1. 프로젝트 생성

안드로이드 돌핀 실행 후,  Empty Ativity 로 프로젝트를 시작합니다.
뭐 이건 홍드로이드님 강좌를 보셨다면 껌이겠지요 :)


2. 버튼과 이미지뷰 컨트롤 넣기

위와 같은 화면을 만들기 위해, activity_main.xml 파일을 열어 편집하는데요.
수정할 부분이 그리 많진 않습니다. .
기본 레이아웃 ( 화면 구성 ) 을 LinearLayout 으로 바꾸고, 배치 방향을 새로(vertical) 로 정해 줍니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android"
          :

그리고 기본 제공되는 TextView 를 삭제 후 Button과 ImageView 를 넣어 줍니다.

         :
    <
Button
       
android:id="@+id/btn_picture"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:text="촬영"
       
android:layout_gravity="center_horizontal"
       
android:layout_marginTop="55dp"/>

    <
ImageView
       
android:id="@+id/imageView"
       
android:layout_width="250dp"
       
android:layout_height="250dp"
       
android:layout_gravity="center_horizontal"
       
android:src="@mipmap/ic_launcher"
       
android:layout_marginTop="20dp"/>
         :

이렇게 수정하면 최종 소스는 아래와 같이 됩니다.


<?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:layout_width="match_parent"
   
android:layout_height="match_parent"
   
tools:context=".MainActivity"
   
android:orientation="vertical"
   
>

    <
Button
       
android:id="@+id/btn_picture"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:text="촬영"
       
android:layout_gravity="center_horizontal"
       
android:layout_marginTop="55dp"
       
/>

    <
ImageView
       
android:id="@+id/imageView"
       
android:layout_width="250dp"
       
android:layout_height="250dp"
       
android:layout_gravity="center_horizontal"
       
android:src="@mipmap/ic_launcher"
       
android:layout_marginTop="20dp"/>

</
LinearLayout>


 3. 액티비티 코드 수정

이제 기능 작업을 해야겠지요.
클래스(class) 안에 레이아웃 버튼과 이미지를  연결할 변수 2개를 MainActivity.java 에 선언,
기본 카메라 앱에서 이미지를 받아올 변수 bitmap 도 선언합니다.


         :
public class
MainActivity extends AppCompatActivity {

 
// 레이아웃의 버튼과 이미지뷰를 연결할 변수 선언
 
private Button btn_picture;
 
private ImageView imageView;

 
// 그림을 받아올 비트맵 변수를 선언
 
private Bitmap bitmap;
         :

이어서 기본 작성된 onCreate 함수 안에 코드를 짜는데요.
이미지와 버튼을 연결하는 코드는 별반 다를건 없지만,

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

   
imageView = findViewById(R.id.imageView);
   
btn_picture = findViewById(R.id.btn_picture);
            :

버튼의 클릭 이벤트가 좀 특별한데요.
아래와 같이 작성한 다음에,

             :
btn_picture.setOnClickListener(new View.OnClickListener() {
    
@Override
   
public void onClick(View view) {
       
cameraapp.launch(new Intent(
         
MediaStore.ACTION_IMAGE_CAPTURE
       
));
    }
});
            :

추가로 아래 코드를 작성해주어야 합니다.
주의할 것은 onCreate 함수과 같은 등급으로 바깥에 작성해 주어야 한다는 점입니다.
onCreate 함수 안에 정의하지 않도록 주의가 필요합니다.

             :
    @Override
   
protected void onCreate(Bundle savedInstanceState) {
       
:
    }

   
ActivityResultLauncher<Intent> cameraapp =
        registerForActivityResult(
           
new ActivityResultContracts.StartActivityForResult(),
           
new ActivityResultCallback<ActivityResult>() {
               
@Override
               
public void onActivityResult(ActivityResult result) {
                    
if( result.getResultCode() == RESULT_OK
                     
&& result.getData() != null){
                       
Bundle extras = result.getData().getExtras();
                       
bitmap = (Bitmap) extras.get("data");
                        
imageView.setImageBitmap(bitmap);
                    }
                }
            }
        );
}

최종적인 MainActivity.java 코드는 아래와 같습니다.


package com.cray.myapplication;

import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {
   
private Bitmap bitmap;
   
private Button btn_picture;
   
private ImageView imageView;

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

       
imageView = findViewById(R.id.imageView);
       
btn_picture = findViewById(R.id.btn_picture);
       
btn_picture.setOnClickListener(new View.OnClickListener() {
           
@Override
           
public void onClick(View view) {
               
cameraapp.launch(new Intent(
                 
MediaStore.ACTION_IMAGE_CAPTURE
                
));
            }
        });
    }

   
ActivityResultLauncher<Intent> cameraapp =
        registerForActivityResult(
           
new ActivityResultContracts.StartActivityForResult(),
           
new ActivityResultCallback<ActivityResult>() {
                
@Override
               
public void onActivityResult(ActivityResult result) {
                   
if( result.getResultCode() == RESULT_OK
                     
&& result.getData() != null){
                       
Bundle extras = result.getData().getExtras();
                       
bitmap = (Bitmap) extras.get("data");
                       
imageView.setImageBitmap(bitmap);
                    }
                }
            }
        );
}


4. 실행!

이제 휴대폰을 연결해서 실행하면, 처음에 이런 화면이 보이는데요.
촬영 버튼을 터치하면,

스마트폰에 내장된 카메라 앱이 실행됩니다.
적당한 피사체를 조준! 촬영하면 확인 버튼이 뜰텐데요. 확인 버튼을 터치하면,

원래의 앱으로 돌아오면서 촬영한 사진이 가운데 떡하니 박힙니다.

알아내기에는 약간 고생을 하긴 했지만, 코딩의 세계는 이런게 매력입니다.
아직은 단순히 촬영을 해서 화면에 보여주는게 끝이지만, 이 사진을 갤러리에 저장하는 걸 또 다음 목표로 삼아볼까 합니다 :)


필요하신 분께 도움이 되셨을지 모르겠습니다.
오늘도 방문해 주신 모든 분들께 감사드립니다.


성경 말씀 한구절 공유드립니다.

< 빌립보서 2:12 >
두렵고 떨림으로 '너희 구원'을 이루라.

이 말씀을 '너의 구원'으로 착오해서는 안됩니다.
성경에는 분명 이 부분이 단수가 아닌 복수로 표현되어 있습니다.
교회에 명령하신 말씀은 '너의 구원'이 아니라 '너희의 구원'입니다.
'너희'는 '너' 한 사람이 아니라 공동체 모두를 일컫는 말입니다.
즉 '공동체 구원'을 이루어 가는 것입니다.

내가 두렵고 떨린다고 노력해 구원을 이룰 수 없습니다.
구원을 이루신 분은 우리가 의지하는 분 오직 주 예수 그리스도이시니까요.