1

My Class NetworkListener should check, if Internet Connection is available or not. Then, It should show a Snackbar with the InternetState. For this, I'm using an interface.

My whole code:

[MainActivity.java]:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    setTitle(R.string.Inbox);

    Initialize_NavigationDrawer();

    Initialize_Objects();

    //1. Here, I initialise my NetworkListener and register my Receiver
    NetworkListener mNetworkListener = new NetworkListener();
    mNetworkListener.registerReceiver(this);
}

@Override
public void ToggleSnackbar(boolean ShowHide) {
    if (ShowHide) snbNoInternet.show();
    else snbNoInternet.dismiss();
}

[NetworkListener.java]:

public class NetworkListener extends BroadcastReceiver {

    private SnackbarInterface snbInterface;

    public NetworkListener() {}

    @Override
    public void onReceive(Context context, Intent intent) {
        //4. After toggling the Network-Connection, a NullReferenceException occurs
        //5. System.out.println(snbInterface) shows: null
        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getActiveNetworkInfo();
        if (ni == null || !ni.isConnected()) {
            snbInterface.ToggleSnackbar(true);
        }
        else if (ni != null && ni.isConnected()) {
            snbInterface.ToggleSnackbar(false);
        }
    }

    public void registerReceiver(SnackbarInterface receiver) {
        snbInterface = receiver; //2. Is called from onCreate

        //3. System.out.println(snbInterface) shows: at.guger.email.activities.MainActivity@27472a5e
    }

    public interface SnackbarInterface {
        public void ToggleSnackbar(boolean ShowHide);
    }
}

[AndroidManifest.xml]:

<activity
    android:name=".activities.MainActivity" >

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

</activity>

<activity
    android:name=".activities.WriteActivity" />
<activity
    android:name=".activities.ReadActivity" />

<receiver
    android:name=".NetworkListener">
    <intent-filter>
        <action
            android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>

And the permissions:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

The code is called like the numbers are ordered! I really can't explain, why snbInterface is set to null!

I hope you can help me!

the_dani
  • 2,466
  • 2
  • 20
  • 46

1 Answers1

1

You registered the BroadcastReceiver using the receiver element in the AndroidManifest. Android system creates the BroadcastReceiver instance and calls the onReceive method with the appropriate parameters.

If you want to use a BroadcastReceiver to manipulate UI of your application (like show/hide Snackbar ), you will have to register the receiver within your activity using the registerReceiver(BroadcastReceiver receiver,IntentFilter intentFilter) in the onCreate method and unRegister in the onDestroy method of your activity.

Remove the receiver element from the AndroidManifest.xml file and create the BroadcastReceiver through code.

This question here has a clear explanation on how BroadcastReceivers can be created and registered : Broadcast Receiver class and registerReceiver method

In the onReceive method of the BroadcastReceiver, call the toggleSnackbar method in your Activity to toggle the Snackbar.

There is an other method for achieving what you want. It is discussed here: Inform Activity from a BroadcastReceiver ONLY if it is in the foreground

Read more on BroadcastReceivers here

You can write the Receiver as a separate class. Instantiate the Receiver and make a call to registerReceiver with the first parameter as the Receiver and the second parameter as the IntentFilter.

  • can I put the Receiver in a external Class? – the_dani Feb 28 '16 at 19:35
  • @the_dani Updated the answer. – Krishna Pradyumna Mokshagundam Feb 28 '16 at 20:20
  • So if I'm right: A BroadcastReceiver has to be instantiated in the Class to which it should have access? – the_dani Feb 28 '16 at 20:43
  • Instantiation is creating an object of the BroadcastReceiver. It can be done anywhere. Definition of your BroadcastReceiver has to do with member access of Activity class. If you need access to the Activity members, then you should be defining the BroadcastReceiver as an inner class. Inner classes have access to outer class members. If your logic does not require accessing the Activity class, then you can define the BroadcastReceiver independently and call the registerReceiver of the activity, passing it an object of your receiver. – Krishna Pradyumna Mokshagundam Feb 29 '16 at 09:54