I have been stuck with a problem here.I am trying to listen to connectivity changes by implementing a broadcast receiver.Also I have initialised a custom listener within the broadcast receiver so as to communicate to the activity about the connectivity changes to show a Crouton Toast.The code for the various classes as below :
The broadcast receiver :
public class NetworkStateReceiver extends BroadcastReceiver {
private NetworkStateListener networkStateListener;
public NetworkStateReceiver() {
}
public NetworkStateReceiver(NetworkStateListener networkStateListener) {
this.networkStateListener = networkStateListener;
}
@Override
public void onReceive(Context context, Intent intent) {
Log.d("test", "Network connectivity change ::: " + this.networkStateListener);
if (intent.getExtras() != null) {
NetworkInfo ni = (NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
if (ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
Log.i("test", "Network " + ni.getTypeName() + " connected");
networkStateListener.onConnected();
}
}
if (intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
Log.d("test", "There's no network connectivity");
networkStateListener.onDisconnected();
}
}
}
The custom listener interface :
public interface NetworkStateListener {
public void onConnected();
public void onDisconnected();
}
The activity in which the listener is implemented and receiver is registered for connectivity changes :
public class HomeActivity extends AppCompatActivity implements NetworkStateListener {
private NetworkStateReceiver mReceiver;
private LocalBroadcastManager mBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
mBroadcastManager = LocalBroadcastManager.getInstance(HomeActivity.this);
mReceiver = new NetworkStateReceiver(HomeActivity.this);
}
@Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(android.net.ConnectivityManager.CONNECTIVITY_ACTION);
mBroadcastManager.registerReceiver(mReceiver, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
mBroadcastManager.unregisterReceiver(mReceiver);
}
}
And this is the manifest entry :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<application
android:name=".TestApplication"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
<receiver android:name=".shared.receivers.NetworkStateReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
</application>
</manifest>
I have no idea why the networkstateListener is not getting initialised.It gives a null pointer denoting that NetWorkStateListener may not be initialised.Can someone please help me out with this ? I have achieved this in the past, but with a custom broadcast and not with these kind of system broadcasts.
The
CONNECTIVITY_CHANGEbroadcast is sent by the system. This means a couple of things for your current setup.The instance of your
BroadcastReceiverthat you're registering withLocalBroadcastManagerwill never receive that broadcast, asLocalBroadcastManageronly handles broadcasts originating from within your app.Registering your Receiver class in the manifest means that the system will instantiate a new instance of the Receiver to handle each broadcast. Since those instances will not have been passed an instance of your
Activityas a listener,networkStateListenerwill be null inonReceive(), which is most likely where your currentNullPointerExceptionis coming from.Depending on what your desired behavior is, you have a few options to choose from.
If you just want to be notified of connectivity changes while the
Activityis running:Register an instance of the Receiver with the
Context#registerReceiver()method instead, and remove the<receiver>entry from the manifest. If you makeNetworkStateReceiveran inner class ofHomeActivity, you won't need the interface.Use
LocalBroadcastManagerto communicate betweenNetworkStateReceiverand yourActivity, instead of your listenerinterface. You could use an extra on theIntentto indicate connectivity state, or alternatively use different actions to distinguish.Use some other event bus implementation to communicate between the Receiver and the
Activity.If you want to be notified of changes even when your app isn't running:
Activityfrom the Receiver with an extra attached to theIntentto indicate connectivity state. This could also handle the case of yourActivityalready running, if you set theActivity'slaunchModetosingleTaskorsingleTop, and override itsonNewIntent()method.In any case, passing your
Activityas a listener to yourBroadcastReceiverisn't really necessary.