我现在正在尝试使用mutt库,并且它能够让另外两个本地主机可以相互通信 (此示例代码:https://github.com/bytehala/android-mqtt-quickstart)
但我唯一需要解决的是
关闭时,无法接收消息
请告诉我如何在后台操作
我的代码mqttcallbackhandler.java
public class MqttCallbackHandler implements MqttCallback {
/** {@link Context} for the application used to format and import external strings**/
private Context context;
/** Client handle to reference the connection that this handler is attached to**/
private String clientHandle;
MainActivity main;
/**
* Creates an <code>MqttCallbackHandler</code> object
* @param context The application's context
* @param clientHandle The handle to a {@link Connection} object
*/
public MqttCallbackHandler(Context context, String clientHandle)
{
this.context = context;
this.clientHandle = clientHandle;
}
/**
* @see org.eclipse.paho.client.mqttv3.MqttCallback#connectionLost(java.lang.Throwable)
*/
@Override
public void connectionLost(Throwable cause) {
// cause.printStackTrace();
if (cause != null) {
Connection c = Connections.getInstance(context).getConnection(clientHandle);
c.addAction("Connection Lost");
c.changeConnectionStatus(ConnectionStatus.DISCONNECTED);
//format string to use a notification text
Object[] args = new Object[2];
args[0] = c.getId();
args[1] = c.getHostName();
String message = context.getString(R.string.connection_lost, args);
//build intent
Intent intent = new Intent();
intent.setClassName(context, "org.eclipse.paho.android.service.sample.MainActivity");
intent.putExtra("handle", clientHandle);
//notify the user
Notify.notifcation(context, message, intent, R.string.notifyTitle_connectionLost);
}
}
/**
* @see org.eclipse.paho.client.mqttv3.MqttCallback#messageArrived(java.lang.String, org.eclipse.paho.client.mqttv3.MqttMessage)
*/
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
//Get connection object associated with this object
Connection c = Connections.getInstance(context).getConnection(clientHandle);
//create arguments to format message arrived notifcation string
String[] args = new String[2];
args[0] = new String(message.getPayload());
args[1] = topic+";qos:"+message.getQos()+";retained:"+message.isRetained();
//get the string from strings.xml and format
String messageString = context.getString(R.string.messageRecieved, (Object[]) args);
//create intent to start activity
Intent intent = new Intent();
intent.setClassName(context, "org.eclipse.paho.android.service.sample.ConnectionDetails");
intent.putExtra("handle", clientHandle);
//format string args
Object[] notifyArgs = new String[3];
notifyArgs[0] = c.getId();
notifyArgs[1] = new String(message.getPayload());
notifyArgs[2] = topic;
Log.d("won", "msg2=" + notifyArgs[1] + "");
MainActivity.MessageReceive(notifyArgs[1] + "");
//notify the user
// Notify.notifcation(context, context.getString(R.string.notification, notifyArgs), intent, R.string.notifyTitle);
//update client history
c.addAction(messageString);
}
/**
* @see org.eclipse.paho.client.mqttv3.MqttCallback#deliveryComplete(org.eclipse.paho.client.mqttv3.IMqttDeliveryToken)
*/
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
// Do nothing
}
}
答案 0 :(得分:1)
您可以使用服务来处理应用程序开始时执行的服务
在您的清单中添加此内容,以便声明您的服务
<service
android:enabled="true"
android:name=".Mqttservice"
/>
Mqttservice.java
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
import org.eclipse.paho.client.mqttv3.IMqttAsyncClient;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttSecurityException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
public class Mqttservice extends Service {
private String ip="brokerip",port="1883";
private final IBinder mBinder = new LocalBinder();
private Handler mHandler;
private class ToastRunnable implements Runnable {//to toast to your main activity for some time
String mText;
int mtime;
public ToastRunnable(String text, int time) {
mText = text;
mtime = time;
}
@Override
public void run() {
final Toast mytoast = Toast.makeText(getApplicationContext(), mText, Toast.LENGTH_LONG);
mytoast.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
mytoast.cancel();
}
}, mtime);
}
}
private static final String TAG = "mqttservice";
private static boolean hasWifi = false;
private static boolean hasMmobile = false;
private ConnectivityManager mConnMan;
private volatile IMqttAsyncClient mqttClient;
private String uniqueID;
class MQTTBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
IMqttToken token;
boolean hasConnectivity = false;
boolean hasChanged = false;
NetworkInfo infos[] = mConnMan.getAllNetworkInfo();
for (int i = 0; i < infos.length; i++) {
if (infos[i].getTypeName().equalsIgnoreCase("MOBILE")) {
if ((infos[i].isConnected() != hasMmobile)) {
hasChanged = true;
hasMmobile = infos[i].isConnected();
}
Log.d(TAG, infos[i].getTypeName() + " is " + infos[i].isConnected());
} else if (infos[i].getTypeName().equalsIgnoreCase("WIFI")) {
if ((infos[i].isConnected() != hasWifi)) {
hasChanged = true;
hasWifi = infos[i].isConnected();
}
Log.d(TAG, infos[i].getTypeName() + " is " + infos[i].isConnected());
}
}
hasConnectivity = hasMmobile || hasWifi;
Log.v(TAG, "hasConn: " + hasConnectivity + " hasChange: " + hasChanged + " - " + (mqttClient == null || !mqttClient.isConnected()));
if (hasConnectivity && hasChanged && (mqttClient == null || !mqttClient.isConnected())) {
doConnect();
}
}
}
public class LocalBinder extends Binder {
public Mqttservice getService() {
// Return this instance of LocalService so clients can call public methods
return Mqttservice.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public void publish(String topic, MqttMessage message) {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);// we create a 'shared" memory where we will share our preferences for the limits and the values that we get from onsensorchanged
try {
mqttClient.publish(topic, message);
} catch (MqttException e) {
e.printStackTrace();
}
}
@Override
public void onCreate() {
mHandler = new Handler();//for toasts
IntentFilter intentf = new IntentFilter();
setClientID();
intentf.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(new MQTTBroadcastReceiver(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
mConnMan = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
Log.d(TAG, "onConfigurationChanged()");
android.os.Debug.waitForDebugger();
super.onConfigurationChanged(newConfig);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("Service", "onDestroy");
}
private void setClientID() {
uniqueID = android.provider.Settings.Secure.getString(getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
Log.d(TAG, "uniqueID=" + uniqueID);
}
private void doConnect() {
String broker = "tcp://" + ip + ":" + port;
Log.d(TAG, "mqtt_doConnect()");
IMqttToken token;
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
options.setMaxInflight(100);//handle more messages!!so as not to disconnect
options.setAutomaticReconnect(true);
options.setConnectionTimeout(1000);
try {
mqttClient = new MqttAsyncClient(broker, uniqueID, new MemoryPersistence());
token = mqttClient.connect(options);
token.waitForCompletion(3500);
mqttClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable throwable) {
try {
mqttClient.disconnectForcibly();
mqttClient.connect();
} catch (MqttException e) {
e.printStackTrace();
}
}
@Override
public void messageArrived(String topic, MqttMessage msg) throws Exception {
Log.i(TAG, "Message arrived from topic " + topic);
if (topic.equals("Sensors/message")) {
} else if (topic.equals("Sensors/" + uniqueID)) {
}
else{
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
System.out.println("published");
}
});
mqttClient.subscribe("Sensors/" + uniqueID, 0);
mqttClient.subscribe("Sensors/message", 0);
} catch (MqttSecurityException e) {
e.printStackTrace();
} catch (MqttException e) {
switch (e.getReasonCode()) {
case MqttException.REASON_CODE_BROKER_UNAVAILABLE:
mHandler.post(new ToastRunnable("WE ARE OFFLINE BROKER_UNAVAILABLE!", 1500));
break;
case MqttException.REASON_CODE_CLIENT_TIMEOUT:
mHandler.post(new ToastRunnable("WE ARE OFFLINE CLIENT_TIMEOUT!", 1500));
break;
case MqttException.REASON_CODE_CONNECTION_LOST:
mHandler.post(new ToastRunnable("WE ARE OFFLINE CONNECTION_LOST!", 1500));
break;
case MqttException.REASON_CODE_SERVER_CONNECT_ERROR:
Log.v(TAG, "c" + e.getMessage());
e.printStackTrace();
break;
case MqttException.REASON_CODE_FAILED_AUTHENTICATION:
Intent i = new Intent("RAISEALLARM");
i.putExtra("ALLARM", e);
Log.e(TAG, "b" + e.getMessage());
break;
default:
Log.e(TAG, "a" + e.getMessage());
}
}
mHandler.post(new ToastRunnable("WE ARE ONLINE!", 500));
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v(TAG, "onStartCommand()");
return START_STICKY;
}
}
在你的主要increate中 添加这个
Intent mymqttservice_intent = new Intent(this, Mqttservice.class);
startService(mymqttservice_intent);
答案 1 :(得分:0)
从Android Oreo开始,由于诸如Doze,App Stanby,Battery Optimization,App Bucket和Battery Saver之类的功能,不能保证正常服务和Job Scheduler可以访问网络并在后台连续运行。要使用MQTT,我们需要将前台服务与唤醒锁一起使用,以始终保持与服务器的连接以检查消息,即使在电话屏幕关闭时也是如此。 https://developer.android.com/guide/components/services#Foreground