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_CHANGE
broadcast is sent by the system. This means a couple of things for your current setup.
The instance of your BroadcastReceiver
that you're registering with LocalBroadcastManager
will never receive that broadcast, as LocalBroadcastManager
only 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 Activity
as a listener, networkStateListener
will be null in onReceive()
, which is most likely where your current NullPointerException
is 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 Activity
is running:
Register an instance of the Receiver with the Context#registerReceiver()
method instead, and remove the <receiver>
entry from the manifest. If you make NetworkStateReceiver
an inner class of HomeActivity
, you won't need the interface.
Use LocalBroadcastManager
to communicate between NetworkStateReceiver
and your Activity
, instead of your listener interface
. You could use an extra on the Intent
to 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:
Activity
from the Receiver with an extra attached to the Intent
to indicate connectivity state. This could also handle the case of your Activity
already running, if you set the Activity
's launchMode
to singleTask
or singleTop
, and override its onNewIntent()
method. In any case, passing your Activity
as a listener to your BroadcastReceiver
isn't really necessary.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.