我正在使用MqttAndroidClient处理包含聊天功能的应用,我在初始化客户端时遇到了问题。
我想要实现的是运行一个单独的进程(使用:remote )来运行mqtt客户端以订阅代理,以便从我的聊天服务器获取消息。 远程服务在主活动中创建,我使用AIDL设置IPC。 我知道错误代码指出IPC存在错误;但是,我似乎无法找到原因,因为我非常确定我已经正确设置了AIDL。
长话短说,这是我的服务代码:
private static final String MQTT_BROKER = "________(blank on purpose)";
private String userId;
private String publishTopic;
private String subscribeTopic;
MqttAndroidClient client;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new Chat_AIDL.Stub() {
@Override
public String passString(String message) throws RemoteException {
return message;
}
};
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
userId = intent.getStringExtra("userId");
publishTopic = "chat/+/" + userId + "/";
subscribeTopic = "chat/#/" + userId + "/";
Log.d("publishTopic", publishTopic);
Log.d("subscribeTopic", subscribeTopic);
establishMqttConnection();
client.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
}
@Override
public void messageArrived(String topic, MqttMessage receivedMessage) throws Exception {
Intent in = new Intent();
String msg = new String(receivedMessage.getPayload(), "UTF-8");
in.putExtra("resultCode", Activity.RESULT_OK);
in.putExtra("chatMsg", msg);
Log.d("MQTT_RECEIVED", msg);
LocalBroadcastManager.getInstance(getBaseContext()).sendBroadcast(in);
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
}
});
Log.d("SERVICE_CHAT", "STICKY");
super.onStartCommand(intent, flags, startId);
return Service.START_STICKY;
}
private void establishMqttConnection() {
MemoryPersistence memPer = new MemoryPersistence();
client = new MqttAndroidClient(this, MQTT_BROKER, userId, memPer);
try {
client.connect(null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.d("MQTT", "SUCCESS");
subscribeMessage();
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.d("MQTT", "FAILURE");
exception.printStackTrace();
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}
private void subscribeMessage() {
try {
client.subscribe(subscribeTopic, 0, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
}
});
} catch (MqttSecurityException e) {
e.printStackTrace();
} catch (MqttException e) {
e.printStackTrace();
}
}
答案 0 :(得分:2)
我遇到了同样的问题,我发现我无法像本地服务那样处理远程服务,请参阅此issue。当mqtt服务在不同的进程中创建时,官方的示例方式将不起作用。
我解决这个问题的方法是创建自己的服务,并使用mqtt服务在相同的进程中创建此服务:
<application>
<!-- skipped... -->
<service
android:name=".MyService"
android:exported="false"
android:process=":background" />
<service
android:name="org.eclipse.paho.android.service.MqttService"
android:process=":background" />
</application>
希望这可以帮到你。
答案 1 :(得分:0)
我今天遇到了这个例外,我做了很多改动,但大多数都破坏了我的代码及其逻辑。这是我的逻辑,我有一个应用程序(说客户端),它将数据发送到另一个应用程序(说服务器)。要完成这项工作,请跟进this tutorial。我必须在我的AndroidManifest.xml
服务器
<service android:name=".service.RemoteService"
android:process=":remote">
<intent-filter>
<action android:name="full.package.name.service.RemoteService" >
</action>
</intent-filter>
</service>
作为@L。 Swifter说,问题是因为我们试图从remote listening
的服务连接到MQTT。
要解决此问题,我可以解决此问题。
public int onStartCommand(Intent intent, int flags, int startId)
,您可以在其中添加将数据发送到mqtt的方法。那是
public class RemoteServiceForMqtt extends Service
{
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
MqttClientUtil.getInstance(RemoteServiceForMqtt.this).reconnect(); // MqttClientUtil is a class that content all the necessary informations needed to connect to mqtt
if (intent != null){
Bundle bundle = intent.getExtras();
sendToMQTT(bundle.getString("data1"),bundle.getString("data2"),bundle.getString("data3"));
}
return 0b1;
}
public void sendToMQTT(String data1, String data2,String data3) {
JSONObject object = new JSONObject();
try {
object.put("data1", data1);
object.put("data2", data2);
object.put("data3", data3);
} catch (JSONException e) {
e.printStackTrace();
}
MqttClientUtil.getInstance( RemoteServiceForMqtt.this).publish(object.toString());
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
在<service android:name=".service.RemoteServiceForMqtt"/>
服务器中添加AndroidManifest.xml
。
在RemoteService中(发生异常的地方)替换为
Intent service = new Intent(getApplicationContext(), RemoteServiceForMqtt.class);
service.putExtra("data1","data1");
service.putExtra("data2","data2");
service.putExtra("data3","data3");
startService(service);
希望这有助于某人。
答案 2 :(得分:0)
我遇到了这个问题,因为在我们的代码中我们有两个服务:一个用于MQTT,另一个用于与服务器同步。
我们试图加入单独的流程,但它没有起作用。我们也尝试将它们放在同一个过程中,但它也没有用。
在寻找解决方案后,因为它是一个简单的ClassCastException,我们决定下载paho.mqtt.android的源代码并检查该转换。
所以,我们采取的步骤:
在MqttAndroidClient
类包org.eclipse.paho.android.service
}中修改此方法并将其放在此处:
@Override public void onServiceConnected(ComponentName name, IBinder binder) { if (MqttServiceBinder.class.isAssignableFrom(binder.getClass())) { mqttService = ((MqttServiceBinder) binder).getService(); bindedService = true; // now that we have the service available, we can actually // connect... doConnect(); } }
编译并制作模块paho.mqtt.android.service'
并使用IDE生成的aar。
有了这个,我们没有问题,问题已经消失。
希望这有帮助。