BigJeon Android 개발 블로그

ANDROID_JAVA S펜을 이용한 그림그리기_1 본문

AOS - JAVA

ANDROID_JAVA S펜을 이용한 그림그리기_1

Big-Jeon 2022. 2. 6. 17:05
반응형

이번엔 "S펜을 이용한 드로잉 / 저장"에 대하여 포스팅 해볼까 한다.

 

우선 Spen을 이용한다면 생각해야 할게 몇가지 있다.

 

1. Spen의 모션을 어떻게 인식하고 사용할것인가.

2. 그림 그리는 기능을 어떻게 구현 시킬것인가.

3. 저장은 어떤 형식으로 저장할 것인가.

 

위 3가지중 오늘은 12에 대하여 작성해볼까한다.

 

들어가기에 앞서 필자는 1순위로 'Spen의 터치를 어떻게 받아올까'에 대하여 고민하다보니 많은 시간을 날려버렸다....ㅠㅠ

 

각설하고 바로 시작해보겠다.

 

1. 삼성 공식 홈페이지를 통해 SDK받아오기.

 

https://developer.samsung.com/galaxy-spen-remote/overview.html

우선 위의 링크를 통해 들어가면 로그인 하라고 나오는데, 필자는 구글 로그인을 통해 바로 가입을 진행했다.

 

가입 진행 후 Downloads창에 들어간뒤 맨 위의 SDK파일을 다운 받아 압축을 풀어준다.

이걸로 1단계는 끝!

 

2. 새 프로젝트 만들기 / SDK파일 추가.

AndroidStudio를 실행하여 만들고자 하는 프로젝트의 이름으로 새로운 프로젝트를 생성해준다!(필자는 'SpenEX'로 만들었다.)

 

새로운 프로젝트를 생성하고 나면 화면 좌측 상단에 Android로 잡혀있는데, 이부분을 눌러 Project 단으로 변경해준다.

 

정상적으로 변경했다면 기존에 보던 파일들이 아닌 새로운 방식으로 보이는데, 'app'플더 안에있는 'libs' 풀더에 1번에서 다운받고 압축풀어주었던 파일 2개를 복-붙 해주면 된다.

 

 

정상적으로 진행했다면 위와같이 2개의 파일이 'libs'풀더안에 생성되었을 것이다.

 

3.SDK파일 적용.

이제 추가해준 SDK파일을 프로젝트에 추가해주어야하는데, 이 부분때문에 긴시간을 날려먹었다.(혹 저와같이 모르시는분은 시간 절약 하세요 ㅠㅠ)

 

삼성 공식 안내를 읽어보면 파일 추가해준뒤 build.Gradle(Module)의 Dependencies 안에 Compile해주라고 나와있지만 최근 안드로이드가 업데이트 되면서 SDK를 추가해주는 방법이 변경되었다.(삼성 좀 최신걸로 업데이트해주지 ㅠㅠ)

 

정상적으로 파일을 추가해줬다면 아까 Project단으로 바꿔줬던 부분을 다시 App단으로 바꿔주고, Build.Gradle:Module 부분으로 들어가준다.

 

이후 Dependecies 부분에 아래 코드를 추가해주고 오른쪽위에 SyncNow를 눌러주면 SDK추가가 완료된것이다.

implementation fileTree(include: '*.jar', dir:'libs')

 

이제 삼성에서 제공하는 SDK를 프로젝트에서 자유롭게 사용 가능하다.

 

4.XML(이부분은 별다른걸 해준게 없으므로 그냥 코드만 보여주고 넘어가겠다.)

별다른걸 해줄 필요는 없다.

 

5.View에 그림을 그려줄 SetView.Java생성

MainActivity가 아닌 'SetView'라는 새로운 JAVA클래스 파일을 생성해준다.

 

SetView.java를 만들었다면 아래 코드를 입력해준다.

 

package com.example.SpenEX;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import com.samsung.android.sdk.penremote.ButtonEvent;
import com.samsung.android.sdk.penremote.SpenEvent;
import com.samsung.android.sdk.penremote.SpenEventListener;
import com.samsung.android.sdk.penremote.SpenRemote;
import com.samsung.android.sdk.penremote.SpenUnit;
import com.samsung.android.sdk.penremote.SpenUnitManager;

public class SetView extends View {

    public SpenUnitManager spenUnitManager = null;
    //Spen버튼
    private SpenUnit button;
    //그림그리기 ON/OFF
    public Boolean State = false;
    //그리기 도구의 설정
    private Paint paint = new Paint();
    //그리기를 적용할 경로
    private Path path = new Path();
    //경로의 X,Y 좌표값
    private int x,y;

    public SetView(Context context) {
        super(context);
    }
    
    //그리기 도구 설정
    @Override
    protected void onDraw(Canvas canvas) {
        paint.setColor(Color.YELLOW);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(10);
        canvas.drawPath(path,paint);
    }
    
    //터치 이벤트 발생시 적용 시킬 이벤트 정의
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        SpenRemote spenRemote = SpenRemote.getInstance();
        //Spen이 정상적으로 연동이 되었는지 확인하는 부분
        if (!SpenRemote.getInstance().isConnected()){
            spenRemote.connect(getContext(), new SpenRemote.ConnectionResultCallback() {
                @Override
                public void onSuccess(SpenUnitManager manager) {
                    spenUnitManager = manager;
                    button = spenUnitManager.getUnit(SpenUnit.TYPE_BUTTON);
                    //정상적으로 연결이 되었다면 S펜 기능에 따라 어떤 이벤트를 작동시킬건지에 대한 리스너를 등록해준다.
                    spenUnitManager.registerSpenEventListener(mButtonEventListner, button);
                    Toast.makeText(getContext(), "SPEN연결 성공", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onFailure(int i) {
                    Toast.makeText(getContext(), "SPEN연결 안됨", Toast.LENGTH_SHORT).show();
                }
            });
        }
        //펜/손가락 터치에 대한 좌표값을 받아온다.
        x = (int)event.getX();
        y = (int)event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                path.moveTo(x,y);
                break;
            case MotionEvent.ACTION_MOVE:
                x = (int)event.getX();
                y = (int)event.getY();
                //펜의 버튼을 누르면 그리기 도구의 상태가 True일 경우 손가락이든 펜이든 터치에따라 그림이 그려진다.
                if (State){
                    path.lineTo(x,y);
                }
                break;
        }

        invalidate();

        return true;
    }
    //다른 기능은 추가하지않고 SPen의 버튼을 통해 한번 클릭시 그리기 도구를 활성화 시켜주고 다시 누르면 비활성화 되도록 설정했다.
     private SpenEventListener mButtonEventListner = new SpenEventListener() {
        @Override
        public void onEvent(SpenEvent spenEvent) {
            ButtonEvent buttonEvent = new ButtonEvent(spenEvent);

            switch (buttonEvent.getAction()){
                case ButtonEvent.ACTION_DOWN:
                    if (!State){
                        State = true;
                    }else{
                        State = false;
                    }
                    Log.d("Press", State.toString());
                    break;
            }
        }
    };
}

각 부분마다 주석으로 설명을 달아놨으니 따로 설명은 하지 않고 넘어가겠다!

(필자는 기초적인것만 추가했기에 펜기능중 극히 일부인 '버튼 클릭'과 그리기 도구를 한가지로만 설정해줬다.)

 

6. MainActivity 설정.

5단계에서 만든 SetView 클래스를 이용하여 그림을 그릴것이므로 MainActivity가 상속받는 View를 SetView로 설정해준다.

코드는 아래와 같다.

 

package com.example.SpenEX;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        setContentView(new SetView(this));
    }
}

 

 

마무리....

이렇게 작성한뒤 실행을 해보면 펜으로 화면을 한번 터치하면 연결이되었다는 메세지가 나오고 버튼을 한번 누르면 그림그리기가 가능하고 다시한번 누르면 그림그리기가 비활성화된다.

 

간단한 기능만 추가했는데 위 기능들만 이해한다면 다른 기능 추가하는데 훨신 쉽게 접근 가능할 수 있다고 생각한다.

다음에는 더 많은 기능을 추가해서 가져오도록 하겠습니다!

(궁금한점, 틀린점에 대한건 댓글로 남겨주세요!!!)

반응형