我刚开始学习使用Android Studio的MQTT协议。使用 mosquitto 代理,我可以在 pub / sub 窗口之间交换消息。但是当我通过android studio向经纪人发送消息时,该应用程序构建成功,但在经纪人的终端上没有显示任何内容。系统打印连接失败。相同的代码在eclipse java应用程序上运行正常,但是在Android上没有工作,尽管已经添加了所需的库和依赖项。
请帮助,我在这个基本步骤中缺少什么,这样我才能向前学习。谢谢!
应用-的build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.2.0'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
// have added following dependencies
provided 'com.google.android.things:androidthings:0.2-devpreview'
provided 'com.google.android.things:androidthings:0.1-devpreview'
compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2'
}
项目的build.gradle
repositories {
jcenter()
maven {
url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
}
}
的AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.zoha.mqttandroidiot">
<!-- Permissions the Application Requires -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".HomeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- Launch activity automatically on boot -->
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.IOT_LAUNCHER"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<service android:name="org.eclipse.paho.android.service.MqttService"/>
</application>
</manifest>
HomeActivity
public class HomeActivity extends AppCompatActivity{
MqttAndroidClient client;
// private static final MemoryPersistence persistence = new MemoryPersistence();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MqttAndroidClient mqttAndroidClient = new MqttAndroidClient(this.getApplicationContext(), "tcp://localhost:1883", "androidSampleClient");
mqttAndroidClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
System.out.println("Connection was lost!");
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
System.out.println("Message Arrived!: " + topic + ": " + new String(message.getPayload()));
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
System.out.println("Delivery Complete!");
}
});
try {
mqttAndroidClient.connect(null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
System.out.println("Connection Success!");
try {
System.out.println("Subscribing to /test");
mqttAndroidClient.subscribe("/test", 0);
System.out.println("Subscribed to /test");
System.out.println("Publishing message..");
mqttAndroidClient.publish("/test", new MqttMessage("Hello world testing..!".getBytes()));
} catch (MqttException ex) {
}
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
System.out.println("Connection Failure!");
}
});
} catch (MqttException ex) {
}
}
}
答案 0 :(得分:3)
好的,所以你需要两个库来在Android中使用MQTT。一个是mqtt paho客户端,另一个是Android服务库。
compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.0.2'
compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2'
然后,使用MqttAndroidClient
代替MqttClient
。
new MqttAndroidClient(...)
。
我发布了一个完整的Android MQTT服务示例here,如果有帮助的话。
创建新编辑:完整活动示例
MemoryPersistence
时添加了(1)MqttAndroidClient
(2)在.connect()
(MqttAndroidClient
和mqttConnectOptions
)的null
方法中添加了两个参数。
(3)另外,在onFailure()
public class HomeActivity extends AppCompatActivity {
private MqttAndroidClient client;
private final MemoryPersistence persistence = new MemoryPersistence();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MqttAndroidClient mqttAndroidClient = new MqttAndroidClient(this.getApplicationContext(), "tcp://localhost:1883", "androidSampleClient", persistence);
mqttAndroidClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
System.out.println("Connection was lost!");
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
System.out.println("Message Arrived!: " + topic + ": " + new String(message.getPayload()));
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
System.out.println("Delivery Complete!");
}
});
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setCleanSession(true);
try {
mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
System.out.println("Connection Success!");
try {
System.out.println("Subscribing to /test");
mqttAndroidClient.subscribe("/test", 0);
System.out.println("Subscribed to /test");
System.out.println("Publishing message..");
mqttAndroidClient.publish("/test", new MqttMessage("Hello world testing..!".getBytes()));
} catch (MqttException ex) {
}
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
System.out.println("Connection Failure!");
System.out.println("throwable: " + exception.toString());
}
});
} catch (MqttException ex) {
System.out.println(ex.toString());
}
}
}
答案 1 :(得分:2)
我想添加评论,但我的代表太低了......所以我将其作为答案发布。
你说你有一切正常但由于IllegalArgumentException
无法连接。我遇到了同样的问题,发现你还需要定义协议。
因此,而不是"192.168.0.103:1883"
尝试:
String serverURI = "tcp://192.168.0.103:1883"
从我读到的你已经做了其他必要的步骤,但为了给出一个完整的答案:
修改AndroidManifest.xml
以包含:
<service android:name="org.eclipse.paho.android.service.MqttService" />
(来自application
标签内)
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
修改build.gradle
以包含(在dependencies
部分中):
compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1'
compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
使用MqttAndroidClient
(不是MqttClient
)
将您的代码放入&#34; onSuccess&#34;回调,以避免由于方法异步导致的任何问题(如THEPATEL的回答所示):
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setKeepAliveInterval(60);//seconds
mqttConnectOptions.setCleanSession(true);
mqttConnectOptions.setAutomaticReconnect(true);
mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
//Treat success here (subscribe, publish etc)
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
//Treat failure here
}
});
答案 2 :(得分:0)
我在Android设备上的MQTT发布者遇到了相同的问题。在从Android模拟器引用tcp://localhost:1883
时,我不得不使用http://10.0.2.2:1883
,因为模拟器在其自己的VM上运行,而localhost将是模拟器自己的环回地址。
答案 3 :(得分:0)
我遇到了相同的错误,但是我已经解决了。 这是工作代码。
在gradle中:
compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.0'
在清单中:
<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" />
应用程序内部的服务标签:
<service android:name="org.eclipse.paho.android.service.MqttService" >
</service>
活动代码:
MqttAndroidClient client;
Button btnsub,btnpublish;
与Mqtt客户端连接:
String clientId = MqttClient.generateClientId();
client = new MqttAndroidClient(getApplicationContext(), "tcp://www.domain.in/ip:11883",clientId);
client.connect().setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
// We are connected
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
}
});
要订阅按钮,请点击:
client.subscribe("topic", 0, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
}
});
client.subscribe("topic", 0, new IMqttMessageListener() {
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
}
});
要发布按钮,请点击:
MqttMessage message = new MqttMessage();
message.setPayload("message".getBytes());
client.publish("topic", message);