Search code examples
androidfluttergoogle-mapsandroid-intentnavigation

Not able to open Google Maps Turn By Turn Navigation: Flutter


I am trying to integrate the following functionality into my flutter app- **When a user clicks a Navigate button, it should redirect the user to Google Maps App and start Turn by Turn Navigation (which we generally use) **
I am using the following code- (just an example error message although I am using latitude and longitude which gives similar error)

               ElevatedButton(
                              onPressed: () async {
                                String mapsUrl =
                                    'https://www.google.com/maps/dir/?api=1&origin=${appState.position.latitude},${appState.position.longitude}&destination=${riderLocation.latitude},${appState.position.longitude}&travelmode=driving&dir_action=navigate';
                                 Uri uri = Uri.parse(mapsUrl);  
                               
                              
                                if (await canLaunchUrl(mapsUrl)) {
                                  print('can launch url true');
                                  await launchUrl(
                                    Uri.parse(mapsUrl),
                                  );
                                } else {
                                  print('Could not launch url');
                                  throw 'Could not launch $mapsUrl';
                                }
                              },

Problem: When I press the navigate button, google maps gets opened in WebView, showing the complete path and an option Navigate in App. When I click it, I get an error message like-

Web page not available The web page at intent://maps.app.goo.gl/?link=https://www.google.com/maps/dir/Barcelona,%2BSpain/Zaragoza,%2BSpain/Huesca,%2BSpain/Madrid,%2BSpain/@41.2603069,-0.7768843,5z/data%3D!4m14!4m13!1m2!1m1!1s0x12a49816718e30e5:0x44b0fb3d4f47660a!1m2!1m1!1s0xd5914dd5e618e91:0x49df13f1158489a8!1m2!1m1!1s0xd584449d1d84db5:0x2c8dfd864aa74791!1m2!1m1!1s0xd422997800a3c81:0xc436dec1618c2269!3e0?entry%3Dml&apn=com.google.android.apps.maps&amv=965100030&isi=585027354&ibi=com.google.Maps&ius=comgooglemapsurl&utm_campaign=ml_promo&ct=ml-dr-wv-msc&mt=8&pt=9008&efr=1#Intent;package=com.google.android.gms;scheme=https;S.browser_fallback_url=https://play.google.com/store/apps/details%3Fid%3Dcom.google.android.apps.maps&pcampaignid%3Dfdl_long&url%3Dhttps://www.google.com/maps/dir/Barcelona,%252BSpain/Zaragoza,%252BSpain/Huesca,%252BSpain/Madrid,%252BSpain/@41.2603069,-0.7768843,5z/data%253D!4m14!4m13!1m2!1m1!1s0x12a49816718e30e5:0x44b0fb3d4f47660a!1m2!1m1!1s0xd5914dd5e618e91:0x49df13f1158489a8!1m2!1m1!1s0xd584449d1d84db5:0x2c8dfd864aa74791!1m2!1m1!1s0xd422997800a3c81:0xc436dec1618c2269!3e0%3Fentry%253Dml&min_version%3D965100030;end; could not be loaded because:

net::ERR_UNKNOWN_URL_SCHEME

An image of what I want on button press- https://www.google.com/imgres?imgurl=https%3A%2F%2Fi.stack.imgur.com%2Fuy1dU.png&imgrefurl=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F35967239%2Fandroid-google-map-turn-by-turn-navigation&tbnid=DZTxUO10KEw4_M&vet=12ahUKEwiE4Oji-rf5AhU9i9gFHVOXCeIQMygAegUIARCwAQ..i&docid=vB080_l2mo_iNM&w=480&h=854&q=google%20maps%20turn%20by%20turn%20navigation&ved=2ahUKEwiE4Oji-rf5AhU9i9gFHVOXCeIQMygAegUIARCwAQ


Solution

  • Last year Google had a major incident with this feature on both iOs and Android, and they changed something about how it behaves.

    For Android the only working way to open the actual app instead of the web representation is to make a proper Android Intent that targets the Google Maps application, while for iOs the old URL launching should work as it was before. The difference is in the URI of what should be launched.

    For Android:

    Uri get uri => Uri(
            scheme: 'google.navigation',
            host: '',
            queryParameters: {
              'q': '${destination.latitude},${destination.longitude}',
              'mode': 'd',
            },
          );
    
        AndroidIntent intent;
        const action = AndroidIntentAction.view;
        // https://stackoverflow.com/a/39037306/1627511
        final flags = [
          Flag.FLAG_ACTIVITY_CLEAR_TASK,
          Flag.FLAG_ACTIVITY_NEW_TASK,
        ];
        intent = AndroidIntent(
          action: action,
          flags: flags,
          data: uri.toString(),
          package: 'com.google.android.apps.maps',
        );
        if (await intent.canResolveActivity() == true) {
            await intent.launch();
          }
    

    For iOs

    Uri get uri => Uri(
            scheme: 'comgooglemaps',
            host: '',
            queryParameters: {
              'daddr': '${destination.latitude},${destination.longitude}',
              'directionsmode': 'driving',
            },
          );
    await launchUrlString(uri.toString()); // launch this via https://pub.dev/packages/url_launcher
    
    

    Bonus For browser

    Uri get uri => Uri(
            scheme: 'https',
            host: 'www.google.com',
            path: 'maps/dir/',
            queryParameters: {
              'api': '1',
              'destination': '${destination.latitude},${destination.longitude}',
              'travelmode': 'driving',
              'dir_action': 'navigate',
            },
          );
    await launchUrlString(uri.toString()); // launch this via https://pub.dev/packages/url_launcher
    
    

    Hope it helps