Fix: url_launcher can't launch for Android (#947)

Always require activity instead of using application context
diff --git a/packages/url_launcher/CHANGELOG.md b/packages/url_launcher/CHANGELOG.md
index e8f3883..f91c384 100644
--- a/packages/url_launcher/CHANGELOG.md
+++ b/packages/url_launcher/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 4.0.3
+
+* Fixed launch url fail for Android: `launch` now assert activity not null and using activity to startActivity.
+* Fixed `WebViewActivity has leaked IntentReceiver` for Android.
+
 ## 4.0.2
 
 * Added `closeWebView` function to programmatically close the current WebView.
diff --git a/packages/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java b/packages/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java
index 7d856d9..851b9b5 100644
--- a/packages/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java
+++ b/packages/url_launcher/android/src/main/java/io/flutter/plugins/urllauncher/UrlLauncherPlugin.java
@@ -39,7 +39,6 @@
 
   @Override
   public void onMethodCall(MethodCall call, Result result) {
-    Context context = mRegistrar.context();
     String url = call.argument("url");
     if (call.method.equals("canLaunch")) {
       canLaunch(url, result);
@@ -47,22 +46,24 @@
       Intent launchIntent;
       boolean useWebView = call.argument("useWebView");
       boolean enableJavaScript = call.argument("enableJavaScript");
+      Activity activity = mRegistrar.activity();
+      if (activity == null) {
+        result.error("NO_ACTIVITY", "Launching a URL requires a foreground activity.", null);
+        return;
+      }
       if (useWebView) {
-        launchIntent = new Intent(context, WebViewActivity.class);
+        launchIntent = new Intent(activity, WebViewActivity.class);
         launchIntent.putExtra("url", url);
         launchIntent.putExtra("enableJavaScript", enableJavaScript);
       } else {
         launchIntent = new Intent(Intent.ACTION_VIEW);
         launchIntent.setData(Uri.parse(url));
       }
-      if (mRegistrar.activity() == null) {
-        launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-      }
-      context.startActivity(launchIntent);
+      activity.startActivity(launchIntent);
       result.success(null);
     } else if (call.method.equals("closeWebView")) {
       Intent intent = new Intent("close");
-      context.sendBroadcast(intent);
+      mRegistrar.context().sendBroadcast(intent);
       result.success(null);
     } else {
       result.notImplemented();
@@ -85,6 +86,7 @@
   /*  Launches WebView activity */
   public static class WebViewActivity extends Activity {
     private WebView webview;
+    private BroadcastReceiver broadcastReceiver;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -110,17 +112,23 @@
           });
 
       // Set broadcast receiver to handle calls to close the web view
-      BroadcastReceiver broadcast_receiver =
+      broadcastReceiver =
           new BroadcastReceiver() {
             @Override
             public void onReceive(Context arg0, Intent intent) {
               String action = intent.getAction();
-              if (action.equals("close")) {
+              if ("close".equals(action)) {
                 finish();
               }
             }
           };
-      registerReceiver(broadcast_receiver, new IntentFilter("close"));
+      registerReceiver(broadcastReceiver, new IntentFilter("close"));
+    }
+
+    @Override
+    protected void onDestroy() {
+      super.onDestroy();
+      unregisterReceiver(broadcastReceiver);
     }
 
     @Override
diff --git a/packages/url_launcher/example/lib/main.dart b/packages/url_launcher/example/lib/main.dart
index 1ebb13e..365c453 100644
--- a/packages/url_launcher/example/lib/main.dart
+++ b/packages/url_launcher/example/lib/main.dart
@@ -34,6 +34,7 @@
 
 class _MyHomePageState extends State<MyHomePage> {
   Future<void> _launched;
+  String _phone = '';
 
   Future<void> _launchInBrowser(String url) async {
     if (await canLaunch(url)) {
@@ -72,6 +73,14 @@
     }
   }
 
+  Future<void> _makePhoneCall(String url) async {
+    if (await canLaunch(url)) {
+      await launch(url);
+    } else {
+      throw 'Could not launch $url';
+    }
+  }
+
   @override
   Widget build(BuildContext context) {
     const String toLaunch = 'https://flutter.io';
@@ -83,6 +92,19 @@
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
           children: <Widget>[
+            Padding(
+              padding: const EdgeInsets.all(16.0),
+              child: TextField(
+                  onChanged: (String text) => _phone = text,
+                  decoration: const InputDecoration(
+                      hintText: 'Input the phone number to launch')),
+            ),
+            RaisedButton(
+              onPressed: () => setState(() {
+                    _launched = _makePhoneCall('tel:$_phone');
+                  }),
+              child: const Text('Make phone call'),
+            ),
             const Padding(
               padding: EdgeInsets.all(16.0),
               child: Text(toLaunch),
diff --git a/packages/url_launcher/pubspec.yaml b/packages/url_launcher/pubspec.yaml
index 83ad771..e07d3dc 100644
--- a/packages/url_launcher/pubspec.yaml
+++ b/packages/url_launcher/pubspec.yaml
@@ -3,7 +3,7 @@
   web, phone, SMS, and email schemes.
 author: Flutter Team <flutter-dev@googlegroups.com>
 homepage: https://github.com/flutter/plugins/tree/master/packages/url_launcher
-version: 4.0.2
+version: 4.0.3
 
 flutter:
   plugin: