4

I would like to implement a broadcast receiver for my internet connection checking. If connection is not present just finish(); it. But i am still messing up the context . Please check on my below codes.

/**
 * This broadcast receiver is awoken after boot and registers the service that
 * checks for new photos from all the known contacts.
 */


public class ConnectionDetector extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent) {



    boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,false);

     if(noConnectivity){

         ((Activity)context).finish();
         //Show Warning Message
         //Close Application the way i suggested
     }

    }


}

AndroidManifest

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

LogCat :

11-01 22:40:29.179: E/AndroidRuntime(29531): FATAL EXCEPTION: main
11-01 22:40:29.179: E/AndroidRuntime(29531): java.lang.RuntimeException: Unable to start receiver in.wptrafficanalyzer.actionbarsherlocknavtab.ConnectionDetector: java.lang.ClassCastException: android.app.ReceiverRestrictedContext
11-01 22:40:29.179: E/AndroidRuntime(29531):    at android.app.ActivityThread.handleReceiver(ActivityThread.java:1809)
11-01 22:40:29.179: E/AndroidRuntime(29531):    at android.app.ActivityThread.access$2400(ActivityThread.java:117)
11-01 22:40:29.179: E/AndroidRuntime(29531):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:985)
11-01 22:40:29.179: E/AndroidRuntime(29531):    at android.os.Handler.dispatchMessage(Handler.java:99)
11-01 22:40:29.179: E/AndroidRuntime(29531):    at android.os.Looper.loop(Looper.java:130)
11-01 22:40:29.179: E/AndroidRuntime(29531):    at android.app.ActivityThread.main(ActivityThread.java:3691)
11-01 22:40:29.179: E/AndroidRuntime(29531):    at java.lang.reflect.Method.invokeNative(Native Method)
11-01 22:40:29.179: E/AndroidRuntime(29531):    at java.lang.reflect.Method.invoke(Method.java:507)
11-01 22:40:29.179: E/AndroidRuntime(29531):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
11-01 22:40:29.179: E/AndroidRuntime(29531):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
11-01 22:40:29.179: E/AndroidRuntime(29531):    at dalvik.system.NativeStart.main(Native Method)
11-01 22:40:29.179: E/AndroidRuntime(29531): Caused by: java.lang.ClassCastException: android.app.ReceiverRestrictedContext
11-01 22:40:29.179: E/AndroidRuntime(29531):    at in.wptrafficanalyzer.actionbarsherlocknavtab.ConnectionDetector.onReceive(ConnectionDetector.java:29)
11-01 22:40:29.179: E/AndroidRuntime(29531):    at android.app.ActivityThread.handleReceiver(ActivityThread.java:1798)
11-01 22:40:29.179: E/AndroidRuntime(29531):    ... 10 more
KC Chai
  • 1,607
  • 9
  • 30
  • 59

1 Answers1

7

The context you get in BroadcastReciever is not an Activity. BroadcastReciever works outside of activity and isn't tied to one, unless you specifically make it.

Putting aside bad practice of just finishing activity on internet problem without notifying user you can do the following:

public abstract class ConnectionAwareActivity extends Activity {

protected final IntentFilter mIntentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); // A filter for a BR. We want to listen to internet changes
protected final ConnectionDetector mConnectionDetector = new ConnectionDetector(); // Creating an instance of our BR for activity to use

@Override
protected void onResume() {
    super.onResume();
    try {
        registerReceiver(mConnectionDetector, mIntentFilter); // Activity gets shown, we register a BR and it starts to receive notifications about internet changes
    } catch (Exception exc) {
        // whoops
    }
}

@Override
protected void onPause() {
    super.onPause();
    try {
        unregisterReceiver(mConnectionDetector); // Try to unregister BR, since when activity is not visible to user, we don't want to perform any operations on internet change
    } catch (Exception exc) {
        // whoops
    }
}

// Your BR that is encapsulated in Activity and therefore has access to it's methods, since it has access to Activity instance
protected class ConnectionDetector extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
        if (noConnectivity) {
            finish();
        }

    }
}

}

Use it as a superclass for your other activities (this one extends from Activity, change it to whatever), that must be terminated on connectivity errors.

It's very basic variant and somewhat wrong, since you better prefer composition over superclasses

Alex Orlov
  • 18,077
  • 7
  • 55
  • 44
  • Thanks Alex. The codes you provided are too advanced for me. Do you have a tutorial on this ? or an example? – KC Chai Nov 01 '12 at 15:16
  • We just encapsulate broadcast receiver in activity. When activity is shown to user it registers broadcastreceiver and when it paused it unregisters it. In your example, the BR was registered for all application, in my case, we only register it for duration of activity – Alex Orlov Nov 01 '12 at 15:21