Android로 Bluetooth HID 장치(Joystick) 만들기 - 03

들어가면서

첫번째 포스트에서 우리는 Bluetoooth HID 장치를 구현하기 위해 모든 것을 설정했습니다.

두번째 포스트에서는 제어 입력을 연결된 장치로 전송하는 법을 살펴보았습니다.

해당 소스는 https://github.com/Jung-Max/BleHidJoystick를 참고하시면 됩니다.

앱 다운로드는 https://play.google.com/store/apps/details?id=com.ckbs.blehidjoystick를 참고하세요.

이번 포스트에서는 조이스틱의 UI를 구성하는 법에 대해서 살펴보겠습니다.

조이스틱 앱에서 특이한 UI 구성으로는 크게 2가지가 있습니다.

하나는 조이스틱(방향) UI이고 또 하나는 버튼 UI 입니다.

조이스틱 UI

먼저 조이스틱 UI에 대해서 설명하겠습니다.

조이스틱 UI는 open source 기반으로 구성하였습니다.

출처는 아래와 같습니다.

https://github.com/controlwear/virtual-joystick-android

조이스틱 UI를 사용하기 위한 설명은 해당 사이트에 설명되어 있습니다.

여기서는 angle과 strength를 사용해서 x,y 값을 구하는 방법을 설명하겠습니다.

일단 예제를 살펴보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

...

JoystickView joystick = (JoystickView) findViewById(R.id.joystickView);
joystick.setOnMoveListener(new JoystickView.OnMoveListener() {
@Override
public void onMove(int angle, int strength) {
// do whatever you want
}
});
}

해당 구현을 위해서는 onMove에 구현을 해야합니다.

여기서 받는 파라미터값은 angle과 strength입니다.

github 소스를 보시면 아래와 같은 그림으로 설명되어 있습니다.

angle and strength

여기서 angle은 각도이고 strength는 퍼센트값입니다.

angle은 계산을 위해서 라디안 값으로 변경하고 strength는 퍼센트값이기 때문에 상수로 변경합니다.

1
2
double rad = Math.toRadians(angle);
double dist = strength / 100.0;

그 후 거리(dist)에 cos와 sin을 곱하여 조이스틱베이스가 같은 각도의 x와 y 끝 좌표를 얻을 수 있습니다.

1
2
joystick.setTag(R.id.tag_x_pos, dist * Math.cos(rad));
joystick.setTag(R.id.tag_y_pos, dist * Math.sin(rad));

x,y 좌표를 구한 후 Range클래스의 clamp 함수를 사용해 byte의 범위인 -127~127 범위로 한정시켜 줍니다.

byte값으로 한정시켜 주는 이유는 앞서 포스트에서 설명한 것처럼 Joystick의 descriptor를 정의할 때

x,y의 min, max값을 1바이트 값인 -127, 127로 정했기 때문입니다.

1
2
3
Range<Integer> bounds = new Range<>(-127, 127);
int adjX = bounds.clamp((int) ((double) joystick.getT(R.id.tag_x_pos) * 127));
int adjY = bounds.clamp((int) ((double) joystick.getT(R.id.tag_y_pos) * -127));

이제 변환한 x, y값을 sendReport()를 사용해 송신하면 됩니다.

버튼 UI

두번째는 버튼 UI입니다.

버튼 UI는 ImageButton클래스를 써 사용했기 때문에 크게 고려할 점은 없습니다.

여기서 살펴볼 것으로는 버튼의 그림인 △, □, ○, X를 구현하는데 사용한 vector에 있습니다.

해당 구현은 물론 png같은 이미지로 구성해도 되지만 여기서는 vector에 대해서 간단히 살펴보겠습니다.

일단 vector를 사용하기 위해서는 xml(android vector drawable)를 사용해야 합니다.

가지고 있는 svg 포멧이 있다면 안드로이드 스튜디오에 있는 vector asset studio 에서 변환 가능합니다.

xml 은 /res/drawable/ 에 넣으면 됩니다.

vector로 구현된 예제는 아래와 같습니다.

1
2
3
4
5
6
7
8
9
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
</vector>

여기서 pathData값은 SGV 튜토리얼인 http://tutorials.jenkov.com/svg/index.html에서 공부할 수 있습니다.

보통은 인터넷에 예제를 찾아보는 것을 추천합니다.

다음은 추천 블로그입니다.
https://blog.naver.com/ljeljy/220420083431

공유하기