Flutter Deeplink to Google maps and Waze

6.7k views Asked by At

I'm implementing a deeplink to a navigation app (like Google Maps or Waze) from a flutter app. I don't have problems doing so for either Google Maps or Waze, my problem is that if I configure the link for Google Maps, the user can still choose to open it in Waze, but obviously no navigation is started since parameters are different.

Is there a way to limit users choice on the app to use? Or is it possible to use a different link depending on which app the user chooses to open? Or even better, is there a universal link for navigation that works on both apps?

4

There are 4 answers

0
atefsawaed On BEST ANSWER

You can force to open the selected application using a Universal link (iOS) / App link (Android) and it should force the selected app to be opened. Of course, If the application you want to launch is not found in the device it will open it in the browser.

Here I assume that you are using latitude and longitude to navigate to the place but you can easily adjust it to something else. I am also using the url_launcher to launch the links.

void launchWaze(double lat, double lng) async {
  var url = 'waze://?ll=${lat.toString()},${lng.toString()}';
  var fallbackUrl =
      'https://waze.com/ul?ll=${lat.toString()},${lng.toString()}&navigate=yes';
  try {
    bool launched =
        await launch(url, forceSafariVC: false, forceWebView: false);
    if (!launched) {
      await launch(fallbackUrl, forceSafariVC: false, forceWebView: false);
    }
  } catch (e) {
    await launch(fallbackUrl, forceSafariVC: false, forceWebView: false);
  }
}

void launchGoogleMaps(double lat, double lng) async {
  var url = 'google.navigation:q=${lat.toString()},${lng.toString()}';
  var fallbackUrl =
      'https://www.google.com/maps/search/?api=1&query=${lat.toString()},${lng.toString()}';
  try {
    bool launched =
        await launch(url, forceSafariVC: false, forceWebView: false);
    if (!launched) {
      await launch(fallbackUrl, forceSafariVC: false, forceWebView: false);
    }
  } catch (e) {
    await launch(fallbackUrl, forceSafariVC: false, forceWebView: false);
  }
}

You also need to add the following to your Info.plist file:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>googlechromes</string>
    <string>comgooglemaps</string>
    <string>waze</string>
</array>
0
Roger Gusmao On

Updating to the url_launcher last version

 import 'package:url_launcher/url_launcher.dart' as url_launcher;

  ...
    
  
  Future<void> launchWazeRoute(double lat, double lng) async {
    var url = 'waze://?ll=${lat.toString()},${lng.toString()}';
    var fallbackUrl =
        'https://waze.com/ul?ll=${lat.toString()},${lng.toString()}&navigate=yes';
    try {
      bool launched = false;
      if (!kIsWeb) {
        launched = await url_launcher.launchUrl(Uri.parse(url));
      }
      if (!launched) {
        await url_launcher.launchUrl(Uri.parse(fallbackUrl));
      }
    } catch (e) {
      await url_launcher.launchUrl(Uri.parse(fallbackUrl));
    }
  }



Future<void> launchGoogleMaps(double lat, double lng) async {
    var url = 'google.navigation:q=${lat.toString()},${lng.toString()}';
    var fallbackUrl =
        'https://www.google.com/maps/search/?api=1&query=${lat.toString()},${lng.toString()}';
    try {
      bool launched = false;
      if (!kIsWeb) {
        launched = await url_launcher.launchUrl(Uri.parse(url));
      }
      if (!launched) {
        await url_launcher.launchUrl(Uri.parse(fallbackUrl));
      }
    } catch (e) {
      await url_launcher.launchUrl(Uri.parse(fallbackUrl));
    }
  }

You also need to put it on info.plist file:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>googlechromes</string>
    <string>comgooglemaps</string>
    <string>waze</string>
</array>
0
tufanlodos On

Anyone who is getting troubled with opening Google Maps due to wrong URL schemes above, can use this updated version (Tested on iOS and Android):

Future<void> launchGoogleMaps(double lat, double lng) async {
  final url = 'comgooglemaps://?q=${lat.toString()},${lng.toString()}';
  final fallbackUrl =
    'https://www.google.com/maps/search/?api=1&query=${lat.toString()},${lng.toString()}';
  try {
    bool launched = await launchUrl(Uri.parse(url));
    if (!launched) {
      await launchUrl(Uri.parse(fallbackUrl));
    }
  } catch (e) {
    await launchUrl(Uri.parse(fallbackUrl));
}

And make sure you have comgooglemaps in your Info.plist file on iOS:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>comgooglemaps</string>
</array>
0
Juanes30 On

In the following code you can see the implementation to open google maps and waze (Updated):

static Future<void> launchGoogleMaps(
    double latitude,
    double longitude,
  ) async {
    final uri = Uri(
        scheme: "google.navigation",
        queryParameters: {'q': '$latitude, $longitude'});
    try {
      if (await canLaunchUrl(uri)) {
        await launchUrl(uri);
      } else {
        // Do something
      }
    } catch (e) {
        // Do something
    }
  }

  static Future<void> launchWazeMaps(
    double latitude,
    double longitude,
  ) async {
    final uri = Uri.https('waze.com', '/ul', {
      'll' : '$latitude,$longitude',
      'navigate' : 'yes'
    });
    try {
      if (await canLaunchUrl(uri)) {
        await launchUrl(uri);
      } else {
        // Do something
      }
    } catch (e) {
        // Do something
    }
  }