2013년 10월 20일 일요일

안드로이드 RC카 App.(자체제작 어플)

싸구려 RC카를 안드로이드로 컨트롤하려면, 당연한 이야기이겠지만 안드로이드 어플개발법을 알아야한다. 하지만 나는 C언어와 그 계열의 스크립트 언어(Python...)만을 다루어봤기에 자바부터 안드로이드 개발까지 한 스텝씩 밟아 나갈만한 시간이 없었고, 날림으로 만든... 그리고 처음으로 만든 어플임을 미리 밝혀둔다!

간단하게 만든 RC카 컨트롤 어플


매우 단순한 이 어플리케이션은 상하방향의 Seekbar를 조작하여 속도를 조절하고, 좌우방향의 Seekbar로 RC카의 방향을 조절하도록 한다. 내가 발휘한 약간의 창의력이라고 하면, '센서Drive ON' 토글버튼으로 스마트폰 내 가속도센서를 읽어 Seekbar를 컨트롤 할 수 있도록 한 것이다.

즉, 스마트폰을 수직으로 점차 세우면 속도가 빨라지고, 좌우로 기울이면 방향이 전환된다. 마치 스마트폰을 핸들처럼 사용할 수 있는 것이다. (내부 센서를 읽어오는 방법은 IBM의 자료 http://www.ibm.com/developerworks/library/os-android-sensor/ 를 참고했다. 약간은 deprecated된 내용인 듯 하니 유의바람)

그리고 안드로이드 api 내에는 수직으로 된 Seekbar가 없기에 기존의 것을 Extend하여 구현해 주어야 했다. Stackoverflow와 기타 블로그등등을 돌아다니며, 빌드해보고 안되는 것 없애고 필요한 것 덧붙인 누더기 클래스이지만, 누군가에게는 도움이 될지 모르니ㅠㅠ 올려봄.

//VertSeekBar.java로 만들고 메인java에서 임포트하여 사용

package ioio.app.rover;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.SeekBar;

public class VertSeekBar extends SeekBar {
  
    public VertSeekBar(Context context) {
        super(context);
    }
 
    public VertSeekBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
 
    public VertSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(h, w, oldh, oldw);
    }
 
    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(heightMeasureSpec, widthMeasureSpec);
        setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
    }
 
    protected void onDraw(Canvas c) {
        c.rotate(-90);
        c.translate(-getHeight(), 0);
 
        super.onDraw(c);
    }
    
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) {
            return false;
        }
 
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            // onChangeListener.onStartTrackingTouch(this);
            setPressed(true);
            setSelected(true);
            break;
        case MotionEvent.ACTION_MOVE:
            super.onTouchEvent(event);
            int progress = getMax() - (int) (getMax() * event.getY() / getHeight());
             
            // Ensure progress stays within boundaries
            if(progress < 0) {progress = 0;}
            if(progress > getMax()) {progress = getMax();}
            setProgress(progress);  // Draw progress
             
            onSizeChanged(getWidth(), getHeight() , 0, 0);
            setPressed(true);
            setSelected(true);
            break;
        case MotionEvent.ACTION_UP:
            setPressed(false);
            setSelected(false);
            break;
        case MotionEvent.ACTION_CANCEL:
            super.onTouchEvent(event);
            setPressed(false);
            setSelected(false);
            break;
        }
        return true;
    }
 
    public synchronized void setProgressAndThumb(int progress) {
        setProgress(progress);
        onSizeChanged(getWidth(), getHeight() , 0, 0);
    }

    public void updateThumb(){
        onSizeChanged(getWidth(), getHeight(), 0, 0);
    }
    
    public synchronized void setMaximum(int maximum) {
        setMax(maximum);
    }
 
    public synchronized int getMaximum() {
        return getMax();
    }
}

처음이라 아직까진 엉망이지만, 일단 부딪혀 보면서 많은 것을 배울 수 있으리라 기대한다. Java 언어가 가상머신위에 돌아가서 그런지 모르겠으나, High level 언어처럼 좀 더 사람이 쓰기 편하게 구조화 되어있다는 느낌을 받았고, 자바/안드로이드/디자인패턴에 대한 배움욕구(?)가 솟아나고 있다.

댓글 없음:

댓글 쓰기