안드로이드에서 MQTT를 이용하여 각종 IoT가 접목된 기기들을 컨트롤하고자 한다. 그러면 어떻게 안드로이드에서 이를 사용할 수 있을까?
1. MQTT 라이브러리(paho mqtt) 설치하기
우선 MQTT 라이브러리를 설치해야 이 기능을 사용할 수 있으므로 설치를 합니다.
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1'
위 코드를 "build gradle" 파일 내에 있는 "dependencies" 에 추가합니다.
2. 코드 작성(Kotlin)
class MainActivity : AppCompatActivity() {
val ServerIP:String = "tcp://192.168.0.254:1883" //1번 서버 IP
val TOPIC:String = "TopicName" //2번 토픽
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_thrid)
var mqttClient: MqttClient? = null
mqttClient = MqttClient(ServerIP, MqttClient.generateClientId(), null) //3번 연결설정
mqttClient.connect()
findViewById<Button>(R.id.button_send).setOnClickListener {
Log.d("MQTTService", "Send")
mqttClient.publish(TOPIC, MqttMessage("hello!".toByteArray())) //4번 메세지 전송
}
mqttClient.subscribe(TOPIC) //5번 구독 설정
mqttClient.setCallback(object : MqttCallback{ //6번 콜백 설정
override fun connectionLost(p0: Throwable?) {
//연결이 끊겼을 경우
Log.d("MQTTService","Connection Lost")
}
override fun messageArrived(p0: String?, p1: MqttMessage?) {
//메세지가 도착했을 때 여기
Log.d("MQTTService","Message Arrived : " + p1.toString()) //7번 메세지 도착
}
override fun deliveryComplete(p0: IMqttDeliveryToken?) {
//메세지가 도착 하였을 때
Log.d("MQTTService","Delivery Complete")
}
})
}
}
1번. 서버주소입니다.
mqtt 서버에 연결하려면 우선 서버의 주소(ip주소 혹은 도메인)가 필요합니다. 구조는 아래와 같습니다.
"tcp://"+ "서버 주소" + ":1883"
이며, 각 부분의 용도는
tcp:// → 통신 방식을 tcp로 설정합니다.
서버 주소 → 서버의 ip주소 혹은 도메인 주소입니다.
:1883 → 통신할 서버의 포트입니다. 기본 설정은 1883번 포트로 통신합니다.
2번. 토픽 이름입니다.
통신하고자 하는 토픽을 작성하면 됩니다.
3번. Mqtt서버와 연결하기 위한 정보 설정입니다.
3가지 인자가 있는데, 순서대로
서버 IP, 클라이언트 ID, 메시지 저장(캐시와 비슷한 개념)
입니다.
보통 서버 IP만 1번에서 맞춘 양식으로 작성 후 대입, 그 외는 위 예시 코드와 동일하게 합니다.
이후 다음 코드인 .connect()를 통해 서버와 연결을 시도합니다.
4번. 메시지 발행(서버로 전송)입니다.
발행을 하기 위해서는 publish란 메서드를 사용하며 인자는 아래와 같습니다.
토픽, 메시지
토픽은 2번에서 설정한 토픽으로 지정하시면 됩니다. 단 여기서 메시지는 String 타입이 아닌 byteArray타입입니다.
그래서 코드에서 보시다 싶이 .toByteArray()로 형 변환을 해야만 발행이 가능합니다.
5번. 구독 설정입니다.
구독을 하고자 하는 토픽을 인자 값으로 넣어주면 됩니다.
6번. 콜백 설정입니다.
구독하는 토픽으로부터 오는 콜백을 처리하는 부분입니다.
연결 끊김, 메시지도착, 전송완료 이렇게 세 메소드가 존재합니다.
7번. 메세지 도착입니다.
6번에서 설명한 메서드 중에서 메소드 도착 관련 메서드입니다.
인자 값으로 받아오는 p0는 토픽을 의미하며, p1은 메시지를 의미합니다.
위 코드처럼 간단하게 구현할 수 있습니다.
실행시켜 화면에 나오는 버튼을 클릭하면 아래와 같이 로그가 발생합니다.
아래는 위 코드 관련 궁금할만한 내용들을 정리했습니다.
● 메시지 발행 토픽과 구독 토픽이 동일해야 하나요?
· 아닙니다. 둘이 별개로 설정할 경우 각자 토픽에 맞게 발행 및 구독이 됩니다. 위 코드에서는 실행 결과를 간편히
보여드리고자 통일했습니다.
● 5번에서 구독 토픽을 설정했는데 이걸로 말고 7번에서 p0로 토픽이 넘어오는 걸 이용해 고를 수 있지 않나요?
· 네 맞습니다. 단 위 코드에서 단순히 5번 과정을 삭제하면 7번으로 넘어오는 것이 아닌, 그 밑에 있는
deliveryComplete 메서드로 아래처럼 단순히 메시지가 도착했다고 알림이 옵니다.
이걸 사용하는 방법은 추후 게시하겠습니다.
● XML 코드는 어떻게 되나요?
· 기존 빈 화면에서 버튼 하나만 추가한 게 없습니다. 그래도 코드가 궁금하시면 아래와 같습니다.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<Button
android:id="@+id/button_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
● 혹시 자바 코드로는 어떻게 작성하나요?
· 자바 코드는 아래와 같습니다.
public class MainActivity extends AppCompatActivity {
private String ServerIP = "tcp://192.168.0.254:1883";
private String TOPIC = "TopicName";
private MqttClient mqttClient = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sub_javaactivity);
Button button = findViewById(R.id.button_send_java);
try {
mqttClient = new MqttClient(ServerIP, MqttClient.generateClientId(), null);
mqttClient.connect();
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
mqttClient.publish(TOPIC, new MqttMessage("hello!".getBytes()));
} catch (MqttException e) {
e.printStackTrace();
}
}
});
mqttClient.subscribe(TOPIC);
mqttClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable throwable) {
Log.d("MQTTService", "Connection Lost");
}
@Override
public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
Log.d("MQTTService", "Message Arrived : " + mqttMessage.toString());
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
Log.d("MQTTService", "Delivery Complete");
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}
}
'홈 IoT > 안드로이드' 카테고리의 다른 글
안드로이드 전등 컨트롤 예시 (0) | 2023.05.24 |
---|