https://www.youtube.com/watch?v=BAkGm02WBc0&list=PLaqXbTT0YCZGlZ6G7puu189Jz3XDAW7kx&index=1
위 영상을 참고로 제작
프로젝트 생성 및 paho 라이브러리 설치
MQTT_publish라는 이름의 새로운 프로젝트 생성
build.gradle에 아래 코드를 추가
repositories {
maven {
url "https://repo.eclipse.org/content/repositories/paho-releases/"
}
}
depandencies {
compile('org.eclipse.paho:org.eclipse.paho.android.service:1.0.2') {
exclude module: 'support-v4'
}
...
}
첫번째 코드는 paho라는 mqtt repository를 추가하고
두번째 코드는 paho 서비스 depandency를 앱에 추가한다
이후 external libraries에서 두개가 추가된 것을 확인할 수 있다
AndroidManifest.xml의 <application> 태그 위에 권한 설정 코드 추가
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
마지막으로<application> 태그 안에 아래 코드를 추가
<service android:name="org.eclipse.paho.android.service.MqttService" >
</service>
MainActivity.java 코드 작성
아래 코드를 추가하고 import를 모두 추가해준다
package com.example.mqtt_publish;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import static android.content.ContentValues.TAG;
public class MainActivity extends AppCompatActivity {
static String MQTTHOST = "IP_ADDRESS";
static String USERNAME = "";
static String PASSWORD = "";
String pubTopic = "test";
MqttAndroidClient client;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String clientId = MqttClient.generateClientId();
client = new MqttAndroidClient(this.getApplicationContext(), MQTTHOST, clientId);
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName(USERNAME);
options.setPassword(PASSWORD.toCharArray());
try {
IMqttToken token = client.connect(options);
token.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Toast.makeText(MainActivity.this, "connected", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Toast.makeText(MainActivity.this, "connection failed", Toast.LENGTH_SHORT).show();
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}
public void pub(View v)
{
String topic = pubTopic;
String message = "hello";
try {
client.publish(topic, message.getBytes(), 0, false);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
![](https://blog.kakaocdn.net/dn/cBuiPF/btq9mms9hyf/klgE7Q9PZJrnoQGRowyNB0/img.png)
MQTT broker의 주소와 접속할 USERNAME, PASSWORD 선언
publish할 topic 선언
MqttAndroidClient 전역변수 선언
![](https://blog.kakaocdn.net/dn/dFKk2h/btq9fdknWk0/PHQczDigzkrkToviOQOua1/img.png)
clientID를 생성하고 MQTT broker에 접속할 client 생성
연결 옵션 설정
![](https://blog.kakaocdn.net/dn/DGdjz/btq9iATqI3K/NrGORK3VvidCqXWKvQVXyk/img.png)
연결 여부에 따른 Toast 메세지 팝업
![](https://blog.kakaocdn.net/dn/ln9aL/btq9iAy75np/DfxZ7yO3KaVdkjmeKIquD1/img.png)
메세지 publish 함수
Publish 버튼 추가
버튼을 추가하고 상하좌우로 체인은 연결한 뒤 text와 onClick를 설정
그리고 앱을 빌드해봤다
오류
07/11 17:47:34: Launching 'app' on Nexus 5 API 22.
Install successfully finished in 5 s 845 ms.
$ adb shell am start -n "com.example.mqtt_publish/com.example.mqtt_publish.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Connected to process 5721 on device 'Nexus_5_API_22 [emulator-5554]'.
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I/art: Not late-enabling -Xcheck:jni (already on)
W/System: ClassLoader referenced unknown path: /data/app/com.example.mqtt_publish-1/lib/x86_64
W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter androidx.vectordrawable.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
I/art: Background partial concurrent mark sweep GC freed 15904(1124KB) AllocSpace objects, 9(320KB) LOS objects, 39% free, 2MB/4MB, paused 17.009ms total 54.046ms
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.mqtt_publish, PID: 5721
java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/content/LocalBroadcastManager;
at org.eclipse.paho.android.service.MqttAndroidClient.registerReceiver(MqttAndroidClient.java:450)
at org.eclipse.paho.android.service.MqttAndroidClient.connect(MqttAndroidClient.java:428)
at org.eclipse.paho.android.service.MqttAndroidClient.connect(MqttAndroidClient.java:334)
at com.example.mqtt_publish.MainActivity.onCreate(MainActivity.java:43)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.content.LocalBroadcastManager" on path: DexPathList[[zip file "/data/app/com.example.mqtt_publish-1/base.apk"],nativeLibraryDirectories=[/data/app/com.example.mqtt_publish-1/lib/x86_64, /vendor/lib64, /system/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at org.eclipse.paho.android.service.MqttAndroidClient.registerReceiver(MqttAndroidClient.java:450)
at org.eclipse.paho.android.service.MqttAndroidClient.connect(MqttAndroidClient.java:428)
at org.eclipse.paho.android.service.MqttAndroidClient.connect(MqttAndroidClient.java:334)
at com.example.mqtt_publish.MainActivity.onCreate(MainActivity.java:43)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Suppressed: java.lang.ClassNotFoundException: android.support.v4.content.LocalBroadcastManager
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 17 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
분명 영상을 그래도 따라했는데 위와 같은 오류가 나오면서 앱이 튕긴다...
여러가지를 시도해봤다
1. 아래 코드를 추가해보자 https://github.com/firebase/quickstart-unity/issues/402
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
오류 그대로...
2. 아래 코드를 추가해보자 https://github.com/AltBeacon/android-beacon-library/issues/919
implementation 'com.android.support:localbroadcastmanager:28.0.0'
실패
3. 저번에 썼던 방법으로 해보자
complie 부분을 아래와 같이 교체
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
실패...
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
되는게 없네
5. 아래 코드를 추가하고 Migrate to AndroidX
implementation group: 'com.android.support', name: 'support-v4', version: '28.0.0'
성공...
코드 수정
package com.example.mqtt_publish;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
public class MainActivity extends AppCompatActivity {
static String MQTTHOST = "broker.mqtt.com";
static String USERNAME = "";
static String PASSWORD = "";
String pubTopic = "test";
MqttAndroidClient client;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String clientId = MqttClient.generateClientId();
client = new MqttAndroidClient(this.getApplicationContext(), MQTTHOST, clientId);
MqttConnectOptions options = new MqttConnectOptions();
options.setUserName(USERNAME);
options.setPassword(PASSWORD.toCharArray());
try {
//IMqttToken token = client.connect();
IMqttToken token = client.connect(options);
token.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Toast.makeText(MainActivity.this, "connected", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Toast.makeText(MainActivity.this, "connection failed", Toast.LENGTH_SHORT).show();
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}
public void pub(View v)
{
String topic = pubTopic;
String message = "hello";
try {
client.publish(topic, message.getBytes(), 0, false);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
이제 튕기지는 않는데... 계속 연결이 되지 않는다...
유튜브 댓글과 영상에 나온 블로그(?), 구글링을 통해 아래와 같이 변수 부분을 조금 수정했다
static String MQTTHOST = "tcp://192.168.1.104:1883";
static String USERNAME = "test";
static String PASSWORD = "test";
tcp://와 :1883를 추가하고
USERNAME과 PASSWORD에 아무거나 넣어줬다. 왜인지 공백으로 두면 안된다...
앱을 빌드해보면 connection failed가 뜬다..?
MQTT broker를 안켰구나
MQTT broker에서 확인
mosquitto로 MQTT broker를 시작한다음 앱을 실행
connected가 뜨는 것을 확인했다
이제 버튼을 누르면...!
publish 성공!
'프로젝트 > SEDP' 카테고리의 다른 글
MQTT 테스트 애플리케이션 제작(3) - 백그라운드 서비스 (0) | 2021.07.12 |
---|---|
MQTT 테스트 애플리케이션 제작(2) - subscribe (0) | 2021.07.11 |
ESP8266 NodeMCU Publish 테스트 (0) | 2021.06.02 |
MQTT broker 테스트 (0) | 2021.05.31 |
SEDP 프로젝트 개요 (0) | 2021.05.22 |