Bug: 473775 - Occasional NullPointerException in library when network connection changes

Moved the Network info into a temproary variable.

Signed-off-by: James Sutton <james.sutton@uk.ibm.com>
Change-Id: Ia41a4f560a7cba345f704eebb47e623d013d9b7a
This commit is contained in:
James Sutton 2015-08-26 13:45:31 +01:00
parent 3f913d2c55
commit ea42792dcc

View File

@ -3,12 +3,15 @@
* *
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution. * and Eclipse Distribution License v1.0 which accompany this distribution.
* *
* The Eclipse Public License is available at * The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at * and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php. * http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* James Sutton - isOnline Null Pointer (bug 473775)
*/ */
package org.eclipse.paho.android.service; package org.eclipse.paho.android.service;
@ -32,6 +35,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
@ -242,13 +246,13 @@ public class MqttService extends Service implements MqttTraceHandler {
// android docs // android docs
private BackgroundDataPreferenceReceiver backgroundDataPreferenceMonitor; private BackgroundDataPreferenceReceiver backgroundDataPreferenceMonitor;
private volatile boolean backgroundDataEnabled = true; private volatile boolean backgroundDataEnabled = true;
// a way to pass ourself back to the activity // a way to pass ourself back to the activity
private MqttServiceBinder mqttServiceBinder; private MqttServiceBinder mqttServiceBinder;
// mapping from client handle strings to actual client connections. // mapping from client handle strings to actual client connections.
private Map<String/* clientHandle */, MqttConnection/* client */> connections = new ConcurrentHashMap<String, MqttConnection>(); private Map<String/* clientHandle */, MqttConnection/* client */> connections = new ConcurrentHashMap<String, MqttConnection>();
public MqttService() { public MqttService() {
super(); super();
} }
@ -256,7 +260,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* pass data back to the Activity, by building a suitable Intent object and * pass data back to the Activity, by building a suitable Intent object and
* broadcasting it * broadcasting it
* *
* @param clientHandle * @param clientHandle
* source of the data * source of the data
* @param status * @param status
@ -285,7 +289,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Get an MqttConnection object to represent a connection to a server * Get an MqttConnection object to represent a connection to a server
* *
* @param serverURI specifies the protocol, host name and port to be used to connect to an MQTT server * @param serverURI specifies the protocol, host name and port to be used to connect to an MQTT server
* @param clientId specifies the name by which this connection should be identified to the server * @param clientId specifies the name by which this connection should be identified to the server
* @param contextId specifies the app conext info to make a difference between apps * @param contextId specifies the app conext info to make a difference between apps
@ -304,7 +308,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Connect to the MQTT server specified by a particular client * Connect to the MQTT server specified by a particular client
* *
* @param clientHandle * @param clientHandle
* identifies the MqttConnection to use * identifies the MqttConnection to use
* @param connectOptions * @param connectOptions
@ -321,9 +325,9 @@ public class MqttService extends Service implements MqttTraceHandler {
throws MqttSecurityException, MqttException { throws MqttSecurityException, MqttException {
MqttConnection client = getConnection(clientHandle); MqttConnection client = getConnection(clientHandle);
client.connect(connectOptions, invocationContext, activityToken); client.connect(connectOptions, invocationContext, activityToken);
} }
/** /**
* Request all clients to reconnect if appropriate * Request all clients to reconnect if appropriate
*/ */
@ -337,10 +341,10 @@ public class MqttService extends Service implements MqttTraceHandler {
} }
} }
} }
/** /**
* Close connection from a particular client * Close connection from a particular client
* *
* @param clientHandle * @param clientHandle
* identifies the MqttConnection to use * identifies the MqttConnection to use
*/ */
@ -351,7 +355,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Disconnect from the server * Disconnect from the server
* *
* @param clientHandle * @param clientHandle
* identifies the MqttConnection to use * identifies the MqttConnection to use
* @param invocationContext * @param invocationContext
@ -365,7 +369,7 @@ public class MqttService extends Service implements MqttTraceHandler {
client.disconnect(invocationContext, activityToken); client.disconnect(invocationContext, activityToken);
connections.remove(clientHandle); connections.remove(clientHandle);
// the activity has finished using us, so we can stop the service // the activity has finished using us, so we can stop the service
// the activities are bound with BIND_AUTO_CREATE, so the service will // the activities are bound with BIND_AUTO_CREATE, so the service will
// remain around until the last activity disconnects // remain around until the last activity disconnects
@ -374,7 +378,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Disconnect from the server * Disconnect from the server
* *
* @param clientHandle * @param clientHandle
* identifies the MqttConnection to use * identifies the MqttConnection to use
* @param quiesceTimeout * @param quiesceTimeout
@ -398,7 +402,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Get the status of a specific client * Get the status of a specific client
* *
* @param clientHandle * @param clientHandle
* identifies the MqttConnection to use * identifies the MqttConnection to use
* @return true if the specified client is connected to an MQTT server * @return true if the specified client is connected to an MQTT server
@ -410,7 +414,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Publish a message to a topic * Publish a message to a topic
* *
* @param clientHandle * @param clientHandle
* identifies the MqttConnection to use * identifies the MqttConnection to use
* @param topic * @param topic
@ -440,7 +444,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Publish a message to a topic * Publish a message to a topic
* *
* @param clientHandle * @param clientHandle
* identifies the MqttConnection to use * identifies the MqttConnection to use
* @param topic * @param topic
@ -464,7 +468,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Subscribe to a topic * Subscribe to a topic
* *
* @param clientHandle * @param clientHandle
* identifies the MqttConnection to use * identifies the MqttConnection to use
* @param topic * @param topic
@ -484,7 +488,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Subscribe to one or more topics * Subscribe to one or more topics
* *
* @param clientHandle * @param clientHandle
* identifies the MqttConnection to use * identifies the MqttConnection to use
* @param topic * @param topic
@ -504,7 +508,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Unsubscribe from a topic * Unsubscribe from a topic
* *
* @param clientHandle * @param clientHandle
* identifies the MqttConnection * identifies the MqttConnection
* @param topic * @param topic
@ -522,7 +526,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Unsubscribe from one or more topics * Unsubscribe from one or more topics
* *
* @param clientHandle * @param clientHandle
* identifies the MqttConnection * identifies the MqttConnection
* @param topic * @param topic
@ -540,7 +544,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Get tokens for all outstanding deliveries for a client * Get tokens for all outstanding deliveries for a client
* *
* @param clientHandle * @param clientHandle
* identifies the MqttConnection * identifies the MqttConnection
* @return an array (possibly empty) of tokens * @return an array (possibly empty) of tokens
@ -552,7 +556,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Get the MqttConnection identified by this client handle * Get the MqttConnection identified by this client handle
* *
* @param clientHandle identifies the MqttConnection * @param clientHandle identifies the MqttConnection
* @return the MqttConnection identified by this handle * @return the MqttConnection identified by this handle
*/ */
@ -567,7 +571,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Called by the Activity when a message has been passed back to the * Called by the Activity when a message has been passed back to the
* application * application
* *
* @param clientHandle identifier for the client which received the message * @param clientHandle identifier for the client which received the message
* @param id identifier for the MQTT message * @param id identifier for the MQTT message
*/ */
@ -616,7 +620,7 @@ public class MqttService extends Service implements MqttTraceHandler {
} }
unregisterBroadcastReceivers(); unregisterBroadcastReceivers();
if (this.messageStore !=null ) if (this.messageStore !=null )
this.messageStore.close(); this.messageStore.close();
@ -645,14 +649,14 @@ public class MqttService extends Service implements MqttTraceHandler {
// run till explicitly stopped, restart when // run till explicitly stopped, restart when
// process restarted // process restarted
registerBroadcastReceivers(); registerBroadcastReceivers();
return START_STICKY; return START_STICKY;
} }
/** /**
* Identify the callbackId to be passed when making tracing calls back into * Identify the callbackId to be passed when making tracing calls back into
* the Activity * the Activity
* *
* @param traceCallbackId identifier to the callback into the Activity * @param traceCallbackId identifier to the callback into the Activity
*/ */
public void setTraceCallbackId(String traceCallbackId) { public void setTraceCallbackId(String traceCallbackId) {
@ -661,16 +665,16 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Turn tracing on and off * Turn tracing on and off
* *
* @param traceEnabled set <code>true</code> to turn on tracing, <code>false</code> to turn off tracing * @param traceEnabled set <code>true</code> to turn on tracing, <code>false</code> to turn off tracing
*/ */
public void setTraceEnabled(boolean traceEnabled) { public void setTraceEnabled(boolean traceEnabled) {
this.traceEnabled = traceEnabled; this.traceEnabled = traceEnabled;
} }
/** /**
* Check whether trace is on or off. * Check whether trace is on or off.
* *
* @return the state of trace * @return the state of trace
*/ */
public boolean isTraceEnabled(){ public boolean isTraceEnabled(){
@ -679,7 +683,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Trace debugging information * Trace debugging information
* *
* @param tag * @param tag
* identifier for the source of the trace * identifier for the source of the trace
* @param message * @param message
@ -693,7 +697,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* Trace error information * Trace error information
* *
* @param tag * @param tag
* identifier for the source of the trace * identifier for the source of the trace
* @param message * @param message
@ -718,7 +722,7 @@ public class MqttService extends Service implements MqttTraceHandler {
/** /**
* trace exceptions * trace exceptions
* *
* @param tag * @param tag
* identifier for the source of the trace * identifier for the source of the trace
* @param message * @param message
@ -733,13 +737,13 @@ public class MqttService extends Service implements MqttTraceHandler {
dataBundle.putString(MqttServiceConstants.CALLBACK_ACTION, MqttServiceConstants.TRACE_ACTION); dataBundle.putString(MqttServiceConstants.CALLBACK_ACTION, MqttServiceConstants.TRACE_ACTION);
dataBundle.putString(MqttServiceConstants.CALLBACK_TRACE_SEVERITY, MqttServiceConstants.TRACE_EXCEPTION); dataBundle.putString(MqttServiceConstants.CALLBACK_TRACE_SEVERITY, MqttServiceConstants.TRACE_EXCEPTION);
dataBundle.putString(MqttServiceConstants.CALLBACK_ERROR_MESSAGE, message); dataBundle.putString(MqttServiceConstants.CALLBACK_ERROR_MESSAGE, message);
dataBundle.putSerializable(MqttServiceConstants.CALLBACK_EXCEPTION, e); //TODO: Check dataBundle.putSerializable(MqttServiceConstants.CALLBACK_EXCEPTION, e); //TODO: Check
dataBundle.putString(MqttServiceConstants.CALLBACK_TRACE_TAG, tag); dataBundle.putString(MqttServiceConstants.CALLBACK_TRACE_TAG, tag);
//dataBundle.putString(MqttServiceConstants.CALLBACK_TRACE_ID, traceCallbackId); //dataBundle.putString(MqttServiceConstants.CALLBACK_TRACE_ID, traceCallbackId);
callbackToActivity(traceCallbackId, Status.ERROR, dataBundle); callbackToActivity(traceCallbackId, Status.ERROR, dataBundle);
} }
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private void registerBroadcastReceivers() { private void registerBroadcastReceivers() {
if (networkConnectionMonitor == null) { if (networkConnectionMonitor == null) {
@ -761,13 +765,13 @@ public class MqttService extends Service implements MqttTraceHandler {
} }
} }
} }
private void unregisterBroadcastReceivers(){ private void unregisterBroadcastReceivers(){
if(networkConnectionMonitor != null){ if(networkConnectionMonitor != null){
unregisterReceiver(networkConnectionMonitor); unregisterReceiver(networkConnectionMonitor);
networkConnectionMonitor = null; networkConnectionMonitor = null;
} }
if (Build.VERSION.SDK_INT < 14 /**Build.VERSION_CODES.ICE_CREAM_SANDWICH**/) { if (Build.VERSION.SDK_INT < 14 /**Build.VERSION_CODES.ICE_CREAM_SANDWICH**/) {
if(backgroundDataPreferenceMonitor != null){ if(backgroundDataPreferenceMonitor != null){
unregisterReceiver(backgroundDataPreferenceMonitor); unregisterReceiver(backgroundDataPreferenceMonitor);
@ -801,26 +805,27 @@ public class MqttService extends Service implements MqttTraceHandler {
} else { } else {
notifyClientsOffline(); notifyClientsOffline();
} }
wl.release(); wl.release();
} }
} }
/** /**
* @return whether the android service can be regarded as online * @return whether the android service can be regarded as online
*/ */
public boolean isOnline() { public boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
if (cm.getActiveNetworkInfo() != null NetworkInfo networkInfo = cm.getActiveNetworkInfo();
&& cm.getActiveNetworkInfo().isAvailable() if (networkInfo != null
&& cm.getActiveNetworkInfo().isConnected() && networkInfo.isAvailable()
&& backgroundDataEnabled) { && networkInfo.isConnected()
&& backgroundDataEnabled) {
return true; return true;
} }
return false; return false;
} }
/** /**
* Notify clients we're offline * Notify clients we're offline
*/ */