Sid Singh Sid Singh - 5 months ago 21
Android Question

Check for internet on all activity and show message WHILE net is disconnected

AIM



Here is what I want to do:


  1. Check for internet connection at all the times in all the activities of my application (I have like 13 activities so far).

  2. If net is working then all is fine.

  3. If net is not working, show a message (using RelativeLayout) which will be displayed WHILE user is offline i.e. until net works again, that message will be there (on whatever activity user goes to)



Previous Attempts



Here is what I tried:


  1. I tried to create a class that extends
    Broadcast Receiver
    . I created an object of that class on all the activities and registered the receiver.

  2. In my class, whenever net status changes, the main class sends a message through Intent to activity and then activity receives and checks the message (Code is below).



Here is the problem:




  1. I never unregistered receiver which of course gave me an error.

    Are you missing a call to unregisterReceiver()?

  2. If I unregistered the receiver, it gave me following error:

    java.lang.IllegalArgumentException: Receiver not registered



Code in Activites



// The onCreate function (Just a sample)

onCreate(){
registerReceiver(broadcastReceiver, new IntentFilter("broadCastName"));
}

// Outside OnCreate
NetworkStatus broadcastReceiver = new NetworkStatus() {
@Override
public void onReceive(Context context, Intent intent) {
String message;
Bundle b = intent.getExtras();
message = b.getString(KEY_NET_MESSAGE);

if (message.equals(KEY_NET_DISCONNECTED)){
Toast.makeText(SignupActivity.this, MESSAGE_NET_DISCONNECTED, Toast.LENGTH_SHORT).show();
btnSignup.setEnabled(false);
Network_disconnection.setVisibility(View.VISIBLE);
}
if (message.equals(KEY_NET_CONNECTED)){
btnSignup.setEnabled(true);
Network_disconnection.setVisibility(View.INVISIBLE);
}

}
};

//onStop, just a sample
@Override
protected void onStop() {
unregisterReceiver(broadcastReceiver);
super.onStop();
}


AndroidManifest.xml



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


NetworkStatus.java



public class NetworkStatus extends BroadcastReceiver implements Keys.UniversalKeys{

@Override
public void onReceive(Context context, Intent arg1) {

boolean isConnected = arg1.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
if(isConnected){
Intent i = new Intent("broadCastName");
// Data you need to pass to activity
i.putExtra(KEY_NET_MESSAGE, KEY_NET_DISCONNECTED);

context.sendBroadcast(i);
}
else{

Intent i = new Intent("broadCastName");
// Data you need to pass to activity
i.putExtra(KEY_NET_MESSAGE, KEY_NET_CONNECTED);

context.sendBroadcast(i);
Toast.makeText(context, KEY_NET_CONNECTED, Toast.LENGTH_LONG).show();
}
}
}


Question



What am I doing wrong? One thing is clear to me that maybe I should not create new receiver on each activity! Also, why do I need to make an extra java file? I mean why I just can't create a BroadcastReceiver object on each activity and go on with it?

Answer

Understanding XML vs JAVA

When you register a receiver in AndroidMainfest.XML, it's static. It will run even if application is closed.

When you register a receiver in JAVA (Activity) it's dynamic and it can be registered and unregistered via coding dynamically.

Solution

  1. Create a class SampleActivity.java with following code:

    public class SampleActivity extends AppCompatActivity {
        // Declare BroadcastReceiver and RelativeLayout
        BroadcastReceiver breceiver;
        RelativeLayout NoNetBar;
    
    
        @Override
            protected void onResume() {
                Toast.makeText(SampleActivity.this, "App has Resumed", Toast.LENGTH_SHORT).show();
    
                // Register your receiver upon resume.
                registerReceiver(breceiver, new IntentFilter("broadCastName"));
                Toast.makeText(SampleActivity.this, "Broadcast Registered", Toast.LENGTH_SHORT).show();
                super.onResume();
            }
    
            public void setRelative(RelativeLayout param_bar) {
                Toast.makeText(SampleActivity.this, "NoNetBar has been setup", Toast.LENGTH_SHORT).show();
                // This will set RelativeLayout to your desired RelativeLayout from your main activity
                NoNetBar = param_bar;
            }
    
            @Override
            protected void onCreate(@Nullable Bundle savedInstanceState) {
                // Call super oncreate and then set RelativeLayout to invisible initially
                super.onCreate(savedInstanceState);
    
                NoNetBar.setVisibility(View.INVISIBLE);
    
                // Initialize broadcast receiver
                breceiver = new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
            boolean isConnected = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
                        if (isConnected){
                            NoNetBar.setVisibility(View.VISIBLE);
                        } else if (!isConnected){
                            NoNetBar.setVisibility(View.INVISIBLE);
                        }
    
                    }
                };
                Toast.makeText(SampleActivity.this, "Broadcast Initialized", Toast.LENGTH_SHORT).show();
    
    
                Toast.makeText(SampleActivity.this, "App is Created", Toast.LENGTH_SHORT).show();
            }
    
            @Override
            protected void onPause() {
                super.onPause();
                Toast.makeText(SampleActivity.this, "App has Paused", Toast.LENGTH_SHORT).show();
    
                // Unregister your receiver
                unregisterReceiver(breceiver);
                Toast.makeText(SampleActivity.this, "Broadcast UnRegistered", Toast.LENGTH_SHORT).show();
            }
    }
    

This class extends AppCompatActivity (as usual). You can use this class to create an activity wherever you want your receiver to work with a few exception.

  1. Use this class in other activities as follow:

    public class MainActivity extends SampleActivity {
    
        Button btnNext;
        RelativeLayout Network_disconnection;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // Make sure that you can setRelative before calling super.onCreate or you will get a NULL POINTER EXCEPTION
            setRelative(Network_disconnection);
    
            Toast.makeText(MainActivity.this, "Now Calling Supper", Toast.LENGTH_SHORT).show();
            super.onCreate(savedInstanceState);
    
        }
    }
    
  2. You can check this link to understand Activity life cycle:
    https://developer.android.com/training/basics/activity-lifecycle/starting.html or if in hurry, check this image: Activity Life Cycle