[connectivity] Fix IllegalArgumentException (#3235)

* IllegalArgumentException

* IllegalArgumentException

* Update ConnectivityBroadcastReceiver.java

* Add onConnectivityChanged Test

* Format

* Format

* Test registerDefaultNetworkCallback

* Format

* Format

* null != networkCallback
diff --git a/packages/connectivity/connectivity/CHANGELOG.md b/packages/connectivity/connectivity/CHANGELOG.md
index c159f9e..72b6d9b 100644
--- a/packages/connectivity/connectivity/CHANGELOG.md
+++ b/packages/connectivity/connectivity/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 2.0.2
+
+* Android: Fix IllegalArgumentException.
+* Android: Update Example project.
+
 ## 2.0.1
 
 * Remove unused `test` dependency.
diff --git a/packages/connectivity/connectivity/android/build.gradle b/packages/connectivity/connectivity/android/build.gradle
index e1982a0..30ab478 100644
--- a/packages/connectivity/connectivity/android/build.gradle
+++ b/packages/connectivity/connectivity/android/build.gradle
@@ -9,7 +9,7 @@
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.3.0'
+        classpath 'com.android.tools.build:gradle:3.5.0'
     }
 }
 
diff --git a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/Connectivity.java b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/Connectivity.java
index 0a3a6ba..a8902fa 100644
--- a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/Connectivity.java
+++ b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/Connectivity.java
@@ -10,10 +10,10 @@
 import android.os.Build;
 
 /** Reports connectivity related information such as connectivity type and wifi information. */
-class Connectivity {
+public class Connectivity {
   private ConnectivityManager connectivityManager;
 
-  Connectivity(ConnectivityManager connectivityManager) {
+  public Connectivity(ConnectivityManager connectivityManager) {
     this.connectivityManager = connectivityManager;
   }
 
diff --git a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java
index 0c6554c..ca3ccff 100644
--- a/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java
+++ b/packages/connectivity/connectivity/android/src/main/java/io/flutter/plugins/connectivity/ConnectivityBroadcastReceiver.java
@@ -13,7 +13,6 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
-import androidx.annotation.RequiresApi;
 import io.flutter.plugin.common.EventChannel;
 
 /**
@@ -24,15 +23,16 @@
  * io.flutter.plugin.common.EventChannel#setStreamHandler(io.flutter.plugin.common.EventChannel.StreamHandler)}
  * to set up the receiver.
  */
-class ConnectivityBroadcastReceiver extends BroadcastReceiver
+public class ConnectivityBroadcastReceiver extends BroadcastReceiver
     implements EventChannel.StreamHandler {
   private Context context;
   private Connectivity connectivity;
   private EventChannel.EventSink events;
   private Handler mainHandler = new Handler(Looper.getMainLooper());
+  private ConnectivityManager.NetworkCallback networkCallback;
   public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
 
-  ConnectivityBroadcastReceiver(Context context, Connectivity connectivity) {
+  public ConnectivityBroadcastReceiver(Context context, Connectivity connectivity) {
     this.context = context;
     this.connectivity = connectivity;
   }
@@ -41,7 +41,19 @@
   public void onListen(Object arguments, EventChannel.EventSink events) {
     this.events = events;
     if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-      connectivity.getConnectivityManager().registerDefaultNetworkCallback(getNetworkCallback());
+      networkCallback =
+          new ConnectivityManager.NetworkCallback() {
+            @Override
+            public void onAvailable(Network network) {
+              sendEvent();
+            }
+
+            @Override
+            public void onLost(Network network) {
+              sendEvent();
+            }
+          };
+      connectivity.getConnectivityManager().registerDefaultNetworkCallback(networkCallback);
     } else {
       context.registerReceiver(this, new IntentFilter(CONNECTIVITY_ACTION));
     }
@@ -50,7 +62,9 @@
   @Override
   public void onCancel(Object arguments) {
     if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-      connectivity.getConnectivityManager().unregisterNetworkCallback(getNetworkCallback());
+      if (networkCallback != null) {
+        connectivity.getConnectivityManager().unregisterNetworkCallback(networkCallback);
+      }
     } else {
       context.unregisterReceiver(this);
     }
@@ -63,19 +77,8 @@
     }
   }
 
-  @RequiresApi(api = Build.VERSION_CODES.N)
-  ConnectivityManager.NetworkCallback getNetworkCallback() {
-    return new ConnectivityManager.NetworkCallback() {
-      @Override
-      public void onAvailable(Network network) {
-        sendEvent();
-      }
-
-      @Override
-      public void onLost(Network network) {
-        sendEvent();
-      }
-    };
+  public ConnectivityManager.NetworkCallback getNetworkCallback() {
+    return networkCallback;
   }
 
   private void sendEvent() {
diff --git a/packages/connectivity/connectivity/example/android/app/build.gradle b/packages/connectivity/connectivity/example/android/app/build.gradle
index bacbc2f..64f3d06 100644
--- a/packages/connectivity/connectivity/example/android/app/build.gradle
+++ b/packages/connectivity/connectivity/example/android/app/build.gradle
@@ -34,7 +34,7 @@
     defaultConfig {
         applicationId "io.flutter.plugins.connectivityexample"
         minSdkVersion 16
-        targetSdkVersion 28
+        targetSdkVersion 29
         versionCode flutterVersionCode.toInteger()
         versionName flutterVersionName
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -55,4 +55,6 @@
     testImplementation 'junit:junit:4.12'
     androidTestImplementation 'androidx.test:runner:1.1.1'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
+    testImplementation 'org.robolectric:robolectric:3.8'
+    testImplementation 'org.mockito:mockito-core:3.5.13'
 }
diff --git a/packages/connectivity/connectivity/example/android/app/src/test/java/io/flutter/plugins/connectivityexample/ActivityTest.java b/packages/connectivity/connectivity/example/android/app/src/test/java/io/flutter/plugins/connectivityexample/ActivityTest.java
new file mode 100644
index 0000000..f8f4247
--- /dev/null
+++ b/packages/connectivity/connectivity/example/android/app/src/test/java/io/flutter/plugins/connectivityexample/ActivityTest.java
@@ -0,0 +1,53 @@
+package io.flutter.plugins.connectivityexample;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import io.flutter.plugins.connectivity.Connectivity;
+import io.flutter.plugins.connectivity.ConnectivityBroadcastReceiver;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+public class ActivityTest {
+  private ConnectivityManager connectivityManager;
+
+  @Before
+  public void setUp() {
+    connectivityManager =
+        (ConnectivityManager)
+            RuntimeEnvironment.application.getSystemService(Context.CONNECTIVITY_SERVICE);
+  }
+
+  @Test
+  @Config(sdk = 24, manifest = Config.NONE)
+  public void networkCallbackNewApi() {
+    Context context = RuntimeEnvironment.application;
+    Connectivity connectivity = spy(new Connectivity(connectivityManager));
+    ConnectivityBroadcastReceiver broadcastReceiver =
+        spy(new ConnectivityBroadcastReceiver(context, connectivity));
+
+    broadcastReceiver.onListen(any(), any());
+    assertNotNull(broadcastReceiver.getNetworkCallback());
+  }
+
+  @Test
+  @Config(sdk = 23, manifest = Config.NONE)
+  public void networkCallbackLowApi() {
+    Context context = RuntimeEnvironment.application;
+    Connectivity connectivity = spy(new Connectivity(connectivityManager));
+    ConnectivityBroadcastReceiver broadcastReceiver =
+        spy(new ConnectivityBroadcastReceiver(context, connectivity));
+
+    broadcastReceiver.onListen(any(), any());
+    assertNull(broadcastReceiver.getNetworkCallback());
+  }
+}
diff --git a/packages/connectivity/connectivity/example/android/build.gradle b/packages/connectivity/connectivity/example/android/build.gradle
index 541636c..e0d7ae2 100644
--- a/packages/connectivity/connectivity/example/android/build.gradle
+++ b/packages/connectivity/connectivity/example/android/build.gradle
@@ -5,7 +5,7 @@
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:3.3.0'
+        classpath 'com.android.tools.build:gradle:3.5.0'
     }
 }
 
diff --git a/packages/connectivity/connectivity/example/android/gradle/wrapper/gradle-wrapper.properties b/packages/connectivity/connectivity/example/android/gradle/wrapper/gradle-wrapper.properties
index 019065d..01a286e 100644
--- a/packages/connectivity/connectivity/example/android/gradle/wrapper/gradle-wrapper.properties
+++ b/packages/connectivity/connectivity/example/android/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
diff --git a/packages/connectivity/connectivity/pubspec.yaml b/packages/connectivity/connectivity/pubspec.yaml
index d856d10..91d0637 100644
--- a/packages/connectivity/connectivity/pubspec.yaml
+++ b/packages/connectivity/connectivity/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Flutter plugin for discovering the state of the network (WiFi &
   mobile/cellular) connectivity on Android and iOS.
 homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity
-version: 2.0.1
+version: 2.0.2
 
 flutter:
   plugin: