728x90
[1] MQTT 통신
1. 안드로이드에서 MQTT
1) build.gradle(module) 파일에 라이브러리 등록 (dependencies 목록에 추가) 및 Sync now 클릭
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.0'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
2) MQTT는 외부 서버와 통신을 하기 때문에 권한 추가
- AndroidManifest.xml 파일에 추가
<!--인터넷 접속할 수 있는 권한-->
<uses-permission android:name="android.permission.INTERNET"/>
<!--네트워크에 연결됐는지 확인할 수 있게 하는 권한-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--디바이스가 sleep 상태에 빠지지 않도록-->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
3) MQTT 라이브러리 내부에서 제공되는 Service 클래스를 AndroidManifest.xml 파일에 추가
- 백그라운드에서 지속적으로 연결을 수행하는 기능이 구현된 라이브러리에서 제공하는 안드로이드 클래스
- LoopForever와 같은 기능을 별도로 주지 않아도 되도록
<service android:name="org.eclipse.paho.android.service.MqttService"/>
4) MQTT 통신을 수행할 클래스를 만들고 기능 구현하기
① 클라이언트 객체 생성
② callback 메소드 정의하고 등록
③ connect : connect 하면서 subscribe 하기 위해 topic 등록
5) publish 할 수 있도록 구현하기
- Message 객체 만들어서 publish
- publish한 후 콜백이 필요한 경우 등록
6) 서버와의 통신을 하면서 문제없이 통신을 하고 있는지 확인 위해 callback 메소드를 작성하고 등록하고 사용
- IMqttActionListener의 하위를 작성하고 등록
- 서버와 connect 후 결과 확인
- publish 후 확인
- subscribe 후 확인
2. Publish
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MqttTestActivity">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/btn_led_on"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="led켜기"/>
<Button
android:id="@+id/btn_led_off"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="led끄기"/>
</LinearLayout>
<EditText
android:id="@+id/showdata"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MyMqtt.kt
package com.example.mqtttestpro
import android.content.Context
import android.util.Log
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.client.mqttv3.*
class MyMqtt(context:Context, uri:String) {
// 안드로이드에서 mqtt통신을 수행할 객체 -> MqttAndroidClient
var mqttClient:MqttAndroidClient = MqttAndroidClient(context, uri, MqttClient.generateClientId())
// mqtt통신을 하기 위해 브로커 서버와 연결, 연결이 끝난 후 콜백메소드 설정
fun connect(topic:Array<String>){
// 연결하기 위해서 필요한 여러가지 정보를 담고 있는 객체
val mqttConnectOptions = MqttConnectOptions()
// mqttAndroidClient 객체의 connect를 호출하며 브로커에 연결을 시도
// 안드로이드 내부에서 브로커에 연결을 성공하면 자동으로 이벤트가 발생하며 이를 처리하는 리스너가 IMqttActionListener
mqttClient.connect(mqttConnectOptions,null, object:IMqttActionListener{
override fun onSuccess(asyncActionToken: IMqttToken?) {
// 접속 성공
Log.d("mymqtt", "브로커 접속 성공....")
}
override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
// 접속 실패
Log.d("mymqtt", "브로커 접속 실패....")
}
})
}
fun publish(topic:String, payload:String, qos:Int=0){
if(!mqttClient.isConnected){
mqttClient.connect()
}
val message = MqttMessage()
// 메시지객체에 payload와 메시지 전송 품질(qos) 설정
// 네트워크로 전송되도록 byte로 변경
message.payload = payload.toByteArray()
message.qos = qos
// 메시지 전송하기 (publish) - publish가 성공/실패하는 경우 이벤트가 발생하기 때문에 리스너 등록
// mqttClient.publish(topic, message) // 이렇게만 publish해도 됨
// publish 후 콜백이 실행되도록 하고 싶다면 다음과 같이 publish
mqttClient.publish(topic, message, null, object:IMqttActionListener{
override fun onSuccess(asyncActionToken: IMqttToken?) {
Log.d("mymqtt", "메시지 전송 성공...")
}
override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
Log.d("mymqtt", "메시지 전송 실패...")
}
})
}
}
MqttTestActivity.kt
package com.example.mqtttestpro
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import kotlinx.android.synthetic.main.activity_main.*
// 화면디자인 - 화면에 있는 위젯들의 이벤트에 반응하는 처리만 구현
class MqttTestActivity : AppCompatActivity(), View.OnClickListener {
val sub_topic = "iot/#"
val server_uri = "tcp://XXX.XXX.XXX.XXX:1883" // broker의 ip와 port
var mymqtt:MyMqtt? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// MQTT 통신을 수행할 MQTT 객체를 생성
mymqtt = MyMqtt(this, server_uri)
// broker 연결
mymqtt?.connect(arrayOf<String>(sub_topic))
// 이벤트 연결
btn_led_on.setOnClickListener(this)
btn_led_off.setOnClickListener(this)
}
override fun onClick(v: View?) {
var data:String = ""
data = if(v?.id==R.id.btn_led_on){
"led_on"
}else{
"led_off"
}
mymqtt?.publish("android/led", data)
}
}
- 끝 -
728x90