4-K. 매직 볼 – ImageView & 가속도 센서
04 안드로이드 기초 2
4-K. 매직 볼 – ImageView & 가속도 센서

 

이번 시간에는 질문에 대답해주는 매직 볼 앱을 만들어 보겠습니다폰을 흔들면 답변 종류가 변경되는 기능도 구현해 보겠습니다.

이번 단원 핵심 포인트 ]

가속도 센서 사용방법

센서 관리자 구하기

ex) SensorManager mSensorMgr = (SensorManager)getSystemService(Context.SENSOR_SERVICE );

 

가속도 센서 지정하기

ex) mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

 

- SensorEventListener sensorListener : 센서 이벤트 리스너

 

- onSensorChanged(SensorEvent event) : 센서 이벤트 함수

 

 

1) 레이아웃 파일에 위젯 추가

 

(1) 새로운 소스 프로젝트를 생성하고 이름을 MagicBall 라고 지정합니다소스 프로젝트를 생성하는 방법은 먼저번 시간에 했던것과 동일합니다.

소스 프로젝트가 생성되면 이미지 파일을 소스 프로젝트로 복사하겠습니다. [ 부록 /Sample Image ] 폴더에서 아래 5개 파일을 소스 프로젝트 /res /drawable ] 폴더로 복사합니다.

btn_orange_n.png / magic_ball1.png / magic_ball2.png / magic_ball3.png / magic_ball4.png

(2) 레이아웃 정보파일에 (/res/layout/activity_main.xml) 1개의 ImageView  1개의 Button 위젯을 추가해 보겠습니다레이아웃 파일에 아래와 같이 코드를 추가합니다.

 

<RelativeLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:background="#777">

 

    <TextView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_marginTop="30dp"

        android:layout_centerHorizontal="true"

        android:textColor="#fff"

        android:textSize="25sp"

        android:text="Ask me anything!" />

 

    <ImageView

        android:id="@+id/imageBall"

        android:layout_width="250dp"

        android:layout_height="250dp"

        android:layout_centerHorizontal="true"

        android:layout_centerVertical="true"

        android:scaleType="fitCenter"

        android:src="@drawable/magic_ball1"/>

 

    <Button

        android:layout_width="160dp"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_alignParentBottom="true"

        android:layout_marginBottom="20dp"

        android:onClick="onClick"

        android:background="@drawable/btn_orange_n"

        android:textColor="#fff"

        android:text="Shake Me~~"/>

 

</RelativeLayout>

 

TextView 를 화면 위쪽 중앙에 생성하였습니다.

ImageView 를 화면 정중앙에 생성하였습니다.

Button 을 화면 아래쪽 중앙에 생성하였습니다.

2) 볼 이미지 변경

 

(1) 위젯 변수 초기화

ImageView 위젯 변수를 생성하겠습니다자바 소스파일 (MainActivity.java) 로 이동해서 아래와 같이 멤버변수를 추가합니다그리고 onCreate() 함수에서 초기화 해줍니다.

 

public class MainActivity extends AppCompatActivity {

      ImageView imageBall;

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

          imageBall = findViewById(R.id.imageBall);

    }

 

 

(2) 랜덤으로 볼 이미지 변경

Button 을 누르면 랜덤으로 볼 이미지가 변경되는 기능을 구현해 보겠습니다소스 파일에 아래와 같이 2개의 함수를 생성합니다.

void onClick(View v) {

        int[] imageId = {R.drawable.magic_ball1, R.drawable.magic_ball2

                , R.drawable.magic_ball3, R.drawable.magic_ball4};

        int rand = getRandom(4, 0);

        imageBall.setImageResource( imageId[rand] );

    }

 

    int getRandom(int range, int min) {

        return (int)(Math.random() * range) + min;

    }

 

onClick() : Button 클릭 이벤트 함수.

 

아래는 4개의 볼 이미지 ID 를 정수형 배열에 저장하는 코드 입니다.

        int[] imageId = {R.drawable.magic_ball1, R.drawable.magic_ball2

                , R.drawable.magic_ball3, R.drawable.magic_ball4};

 

아래는 난수에 해당하는 이미지를 ImageView 에 표시하는 코드 입니다.

        imageBall.setImageResource( imageId[rand] );

 

getRandom() : 난수를 생성하는 함수.

 

예제를 실행하고 Button 을 누르면 매직 볼 이미지가 변경됩니다.

3) 폰을 흔들어서 볼 이미지 변경

 

(1) 가속도 센서

핸드폰을 흔들면 매직 볼 이미지가 변경되는 기능을 구현해 보겠습니다아래와 같이 새로운 멤버변수를 생성하고, onCreate() 함수에서 초기화 해줍니다.

 

public class MainActivity extends AppCompatActivity {

      ImageView imageBall;

SensorManager mSensorMgr = null;

 

  @Override

  protected void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.activity_main);

      imageBall = findViewById(R.id.imageBall);

 

      mSensorMgr = (SensorManager)getSystemService(Context.SENSOR_SERVICE );

      Sensor sensorAcceler =

mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

      if( sensorAcceler != null )

          mSensorMgr.registerListener(sensorListener, sensorAcceler,

SensorManager.SENSOR_DELAY_UI);

 }

 

SensorManager : 모든 센서를 관리하는 클래스이미 생성되어 있기 때문에 getsystemService() 함수로 가져오면 됩니다.

 

SensorManager.getDefaultSensor() : 특정 센서 객체를 반환하는 함수. TYPE_ACCELEROMETER 를 파라미터로 전달하면 가속도 센서가 반환됩니다. null 이 반환되면 핸드폰에 가속도 센서가 없다는 의미입니다.

 

SensorManager.registerListener() : 센서 이벤트를 수신하는 리스너를 지정하는 함수리스너 객체는 지금부터 만들어 보겠습니다.

 

소스파일 내부에 아래와 같이 새로운 코드를 입력합니다센서 이벤트를 수신하는 리스너 객체를 생성하고 이벤트 함수를 정의하는 코드입니다.

 

    SensorEventListener sensorListener = new SensorEventListener() {

        public void onAccuracyChanged(Sensor sensor, int accuracy) {}

 

        public void onSensorChanged(SensorEvent event) {

            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

                float v[] = event.values;

                double sum = Math.abs(v[0]) + Math.abs(v[1]) + Math.abs(v[2]);

                if( sum > 30 ) {

                    onClick(null);

                }

            }

        }

    };

 

SensorEventListener : 센서 이벤트를 수신하는 리스너리스너를 정의할 때는 가상 함수를 모두 생성해 주어야 합니다.

 

onAccuracyChanged() : 센서 정확도가 변경될 때 실행되는 이벤트 함수이번 예제에서는 사용하지 않지만 헤더부분은 만들어 주어야 합니다.

 

onSendorChanged() : 센서 값이 변경될 때 실행되는 이벤트 함수.

 

SensorEvent : 센서 값을 저장하는 클래스.

 

SensorEvent.sensor.getType() : 센서의 종류를 반환하는 함수. TYPE_ACCELEROMETER 이면 가속도 센서를 의미합니다.

 

SensorEvent.values : X, Y, Z축 센서 값이 저장된 배열.

 

Math.abs() : 음수를 양수로 변경해서 절대값을 반환하는 수학 함수.

 

아래는 X, Y, Z축 가속도 값의 합계를 구하는 코드입니다중력이 존재하기 때문에 항상 기본값은 9.8 입니다약하게 흔들때의 가속도 합계는 20, 강하게 흔들때의 가속도 합계는 30 정도입니다사용자가 폰을 흔들면 버튼 클릭 이벤트 함수를 실행합니다.

 

                double sum = Math.abs(v[0]) + Math.abs(v[1]) + Math.abs(v[2]);

                if( sum > 30 ) {

                    onClick(null);

                }

 

예제를 핸드폰에 설치하고폰을 흔들어 봅시다. Button 을 누르지 않아도 매직 볼 이미지가 변경됩니다.

매직 볼 예제가 완성되었습니다전체 소스코드는 다음과 같습니다.

public class MainActivity extends AppCompatActivity {

    ImageView imageBall;

    SensorManager mSensorMgr = null;

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        imageBall = findViewById(R.id.imageBall);

 

        mSensorMgr = (SensorManager)getSystemService( Context.SENSOR_SERVICE );

        Sensor sensorAcceler = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        if( sensorAcceler != null )

            mSensorMgr.registerListener(sensorListener, sensorAcceler,

SensorManager.SENSOR_DELAY_UI);

    }

 

    SensorEventListener sensorListener = new SensorEventListener() {

        public void onAccuracyChanged(Sensor sensor, int accuracy) {}

 

        public void onSensorChanged(SensorEvent event) {

            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {

                float v[] = event.values;

                double sum = Math.abs(v[0]) + Math.abs(v[1]) + Math.abs(v[2]);

                if( sum > 30 ) {

                    onClick(null);

                }

            }

        }

    };

 

    void onClick(View v) {

        int[] imageId = {R.drawable.magic_ball1

                , R.drawable.magic_ball2

                , R.drawable.magic_ball3

                , R.drawable.magic_ball4};

        int rand = getRandom(4, 0);

        imageBall.setImageResource( imageId[rand] );

    }

 

    int getRandom(int range, int min) {

        return (int)(Math.random() * range) + min;

    }

}

 

 

[연습문제매직 볼 확률 변경

매직 볼 예제에서 답변의 확률을 변경해 봅시다세게 흔들면 2번 중에서 1번 ‘YES’ 가 나오고약하게 흔들면 2번 중에서 1번 ‘NO’ 가 나오게 합니다.

질문하기
추가 자료
no files uploaded

추가 자료가 없습니다

여기서 새로운 학습 자료를 확인하세요!
선생님이 추가한 자료들을 바로 확인할 수 있어요.