wifi断开并不会重新连接时,应用程序,服务和mqtt崩溃

我正在制作一个带有mqtt客户端和后台服务的应用程序,当我收到某些mqtt消息时会发出通知。

我使用Paho库和服务作为客户端,只要我连接到wifi并打开代理,一切都可以正常运行。

我不希望通过Internet访问代理,所以当没有wifi可用时,客户端将断开连接,问题是当wifi重新连接时,mqtt客户端将不会重新连接。

我已经尝试了很多事情,但是最新的测试是让处理程序检查是否有互联网以及是否通过wifi,如果是的话,我再次启动服务器" title="mqtt服务器">mqtt服务器。

我在清单中具有以下权限:

    android.permission.INTERNET"

android:name="android.permission.ACCESS_NETWORK_STATE"

android.permission.WAKE_LOCK"

当我运行模拟器并断开wifi连接时,整个应用以及服务均崩溃,并出现以下错误

这是我正在使用的处理程序:

    handler.postDelayed(new Runnable(){

public void run(){

if (isWifiConnected()) {

startMqtt();

}

handler.postDelayed(this, delay);

}

}, delay);

这是isWifiConnected(如果没有Context context =

this;在应用程序中添加我,context.getSystemService将无法正常工作,我也不知道这是否也是一个问题):

    private boolean isWifiConnected() {

boolean isWifi;

ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo activeNetwork = cm.getActiveNetworkInfo();

boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();

return isWifi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;

}

D/AlarmPingSender: Unregister alarmreceiver to MqttServicephone

W/Mqtt: Failed to connect to: tcp://192.168.1.39:1883Unable to connect to server (32103) - java.net.ConnectException: failed to connect to /192.168.1.39 (port 1883) from /:: (port 0) after 30000ms: connect failed: ENETUNREACH (Network is unreachable)

I/chatty: uid=10085(com.iteda.nome) identical 85 lines

W/Mqtt: Failed to connect to: tcp://192.168.1.39:1883Unable to connect to server (32103) - java.net.ConnectException: failed to connect to /192.168.1.39 (port 1883) from /:: (port 0) after 30000ms: connect failed: ENETUNREACH (Network is unreachable)

W/Mqtt: Failed to connect to: tcp://192.168.1.39:1883Unable to connect to server (32103) - java.net.ConnectException: failed to connect to /192.168.1.39 (port 1883) from /:: (port 0) after 30000ms: connect failed: ENETUNREACH (Network is unreachable)

I/chatty: uid=10085(com.iteda.nome) identical 4 lines

W/Mqtt: Failed to connect to: tcp://192.168.1.39:1883Unable to connect to server (32103) - java.net.ConnectException: failed to connect to /192.168.1.39 (port 1883) from /:: (port 0) after 30000ms: connect failed: ENETUNREACH (Network is unreachable)

W/Mqtt: Failed to connect to: tcp://192.168.1.39:1883Unable to connect to server (32103) - java.net.ConnectException: failed to connect to /192.168.1.39 (port 1883) from /:: (port 0) after 30000ms: connect failed: ENETUNREACH (Network is unreachable)

I/chatty: uid=10085(com.iteda.nome) identical 36 lines

W/Mqtt: Failed to connect to: tcp://192.168.1.39:1883Unable to connect to server (32103) - java.net.ConnectException: failed to connect to /192.168.1.39 (port 1883) from /:: (port 0) after 30000ms: connect failed: ENETUNREACH (Network is unreachable)

W/Mqtt: Failed to connect to: tcp://192.168.1.39:1883Unable to connect to server (32103) - java.net.ConnectException: failed to connect to /192.168.1.39 (port 1883) from /:: (port 0) after 30000ms: connect failed: ENETUNREACH (Network is unreachable)

I/chatty: uid=10085(com.iteda.nome) identical 17 lines

W/Mqtt: Failed to connect to: tcp://192.168.1.39:1883Unable to connect to server (32103) - java.net.ConnectException: failed to connect to /192.168.1.39 (port 1883) from /:: (port 0) after 30000ms: connect failed: ENETUNREACH (Network is unreachable)

I/MqttConnection: Requesting Automatic reconnect using New Java AC

D/AndroidRuntime: Shutting down VM

E/AndroidRuntime: FATAL EXCEPTION: main

Process: com.iteda.nome, PID: 7394

java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.conn.CONNECTIVITY_CHANGE flg=0x4200010 (has extras) } in org.eclipse.paho.android.service.MqttService$NetworkConnectionIntentReceiver@5224905

at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0(LoadedApk.java:1401)

at android.app.-$$Lambda$LoadedApk$ReceiverDispatcher$Args$_BumDX2UKsnxLVrE6UJsJZkotuA.run(Unknown Source:2)

at android.os.Handler.handleCallback(Handler.java:873)

at android.os.Handler.dispatchMessage(Handler.java:99)

at android.os.Looper.loop(Looper.java:193)

at android.app.ActivityThread.main(ActivityThread.java:6669)

at java.lang.reflect.Method.invoke(Native Method)

at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void java.util.Timer.cancel()' on a null object reference

at org.eclipse.paho.client.mqttv3.MqttAsyncClient.stopReconnectCycle(MqttAsyncClient.java:1120)

at org.eclipse.paho.client.mqttv3.MqttAsyncClient.reconnect(MqttAsyncClient.java:1057)

at org.eclipse.paho.android.service.MqttConnection.reconnect(MqttConnection.java:1049)

at org.eclipse.paho.android.service.MqttService.reconnect(MqttService.java:342)

at org.eclipse.paho.android.service.MqttService$NetworkConnectionIntentReceiver.onReceive(MqttService.java:827)

at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0(LoadedApk.java:1391)

at android.app.-$$Lambda$LoadedApk$ReceiverDispatcher$Args$_BumDX2UKsnxLVrE6UJsJZkotuA.run(Unknown Source:2) 

at android.os.Handler.handleCallback(Handler.java:873) 

at android.os.Handler.dispatchMessage(Handler.java:99) 

at android.os.Looper.loop(Looper.java:193) 

at android.app.ActivityThread.main(ActivityThread.java:6669) 

at java.lang.reflect.Method.invoke(Native Method) 

at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 

I/Process: Sending signal. PID: 7394 SIG: 9

Application terminated.

我知道您可能需要更多信息,所以与其说我用错误的代码轰炸,不如告诉我您需要了解我做错的事情:)

错误代码似乎给出了答案,但是由于我是android和java的新手。我不知道如何更改方法以使其正确。

回答:

你说:

问题是,当wifi重新连接时,mqtt客户端将不会重新连接。

  1. 您可以BroadcastReceiver在您的Service#onCreate()方法中仅使用a 来侦听WIFI_STATE_CHANGED_ACTION操作,如下所示。

  2. 此外,你必须使用return START_STICKY你的Service#onStartCommand(),这样应用程序被关闭后,在服务类将被运行。

public class MQTTService extends Service {

private MqttAndroidClient clientPhone;

@Override

public void onCreate() {

super.onCreate();

registerReceiver();

new Thread(() -> init()).start();

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

//do something

return START_STICKY;

}

@Override

public IBinder onBind(Intent intent) {

return null;

}

private void registerReceiver(){

m_ScreenOffReceiver = new BroadcastReceiver(){

@Override

public void onReceive(final Context context, Intent intent){

//Log.d(TAG,"onReceive of Wifi_State_Change called");

if(intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION))

{

int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);

if(wifiState != WifiManager.WIFI_STATE_ENABLED)

return;

final WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);

new Handler().postDelayed(() -> {

WifiInfo wifiInfo = wifiManager.getConnectionInfo();

String ssid = wifiInfo.getSSID();

//Toast.makeText(context, "active wifi:"+ssid, Toast.LENGTH_SHORT).show();

//You can connect to the your mqtt broker again:

connectMQTT();

}, 10000);

}

}

};

IntentFilter intentFilter = new IntentFilter();

intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);

registerReceiver(m_ScreenOffReceiver, intentFilter);

}

private void init() {

clientPhone = new MqttAndroidClient(this, "tcp://IP:PORT", "Your-CLIENT-ID");

//clientPhone = new MqttAndroidClient(this, "ssl://IP:PORT", "Your-CLIENT-ID");

clientPhone.setCallback(new MqttCallback() {

@Override

public void connectionLost(Throwable cause) {

//do something - for example reconnnect again

}

@Override

public void messageArrived(String topic, MqttMessage message) throws Exception {

//you can do everything with the received message from broker here

}

@Override

public void deliveryComplete(IMqttDeliveryToken token) {

//do something

}

});

}

private MqttConnectOptions getOptions(){

if(clientPhone.getServerURI().contains("ssl")) {

//set ssl config.for example:

//options.setSocketFactory(clientPhone.getSSLSocketFactory(YOUR_KEYSTORE_FILE, "YOUR_KEYSTORE_PASSWORD"));

//...

}

options.setKeepAliveInterval(...);

options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1);

options.setAutomaticReconnect(true);

options.setCleanSession(...);

//options.setWill(...);

options.setUserName(...));

options.setPassword(...);

return options;

}

private void connectMQTT() {

try {

//getOptions is a method that returns your MqttConnectOptions object

IMqttToken token = clientPhone.connect(getOptions());

token.setActionCallback(new IMqttActionListener() {

@Override

public void onSuccess(IMqttToken asyncActionToken) {

//do something

}

@SuppressWarnings("ThrowableResultOfMethodCallIgnored")

@Override

public void onFailure(IMqttToken asyncActionToken, Throwable exception) {

//do something

}

});

} catch (MqttException e) {

//do something

e.printStackTrace();

}

}

@Override

public void onDestroy() {

if(clientPhone!=null) {

/*unregisterResources is needed,otherwise receive this error:

has leaked ServiceConnection org.eclipse.paho.android.service.MqttAndroidClient*/

try {

clientPhone.unregisterResources();

clientPhone.close();

clientPhone.disconnect();

} catch (Exception e) {

e.printStackTrace();

}

}

unregisterReceiver(m_ScreenOffReceiver);

m_ScreenOffReceiver = null;

...

super.onDestroy();

}

}

  1. 必须声明org.eclipse.paho.android.service.MqttService,并Your Service Class在您的清单文件:

    android:name="org.eclipse.paho.android.service.MqttService"

    android:enabled="true" />

    android:name="YOUR-MQTT-SERVICE-CLASS"

    android:enabled="true"

    android:exported="false" />

我希望这可以帮助你。

最好的祝愿

以上是 wifi断开并不会重新连接时,应用程序,服务和mqtt崩溃 的全部内容, 来源链接: utcz.com/qa/426715.html

回到顶部