Mervin Hemaraju
Mervin Hemaraju

Reputation: 2187

Flutter launchUrl for tel scheme is just opening dialer with the number and not actually dialing the call

I have a flutter app where I want to dial a phone number directly.

But instead of dialing the number, it just opens it on the dialer and I then have to press dial which is not the required behavior.

I have tried the below codes and it didn't work:

final Uri uri = Uri.parse('tel:$number');
                await launchUrl(
                  uri,
                );


final Uri uri = Uri.parse('tel:$number');
                await launchUrl(
                  uri,
                  mode: LaunchMode.platformDefault,
                  webViewConfiguration:
                      const WebViewConfiguration(enableJavaScript: true),
                );

// Build the URI
                final uri = Uri(
                  scheme: 'tel',
                  path: number.replaceAll(RegExp(r'[^\d+]'), ''),
                );

                // Launch the URL with explicit LaunchMode
                if (!await launchUrl(uri,
                    mode: LaunchMode.externalNonBrowserApplication)) {
                  print('Could not launch $uri');
                }

However, it works with this:

if (Platform.isAndroid) {
                  final AndroidIntent intent = AndroidIntent(
                    action: 'android.intent.action.CALL',
                    data: 'tel:$number',
                  );
                  await intent.launch();
                }

But I don't want to check for the platform every time. I want it to work on both Android and IOS using the launcher functionality. Can someone help me ?

Upvotes: 0

Views: 25

Answers (1)

Survil Dhaduk
Survil Dhaduk

Reputation: 11

Using flutter_phone_direct_caller

This package is specifically designed for direct dialing (at least on Android). Here's how to use it:

  1. Add the package to your pubspec.yaml:

    dependencies:
      flutter_phone_direct_caller: ^2.0.5
    
  2. Code Example:

    import 'package:flutter_phone_direct_caller/flutter_phone_direct_caller.dart';
    
    void dialNumber(String number) async {
      bool? result = await FlutterPhoneDirectCaller.callNumber(number);
      if (result == false || result == null) {
        print('Failed to dial $number');
      }
    }
    

This will directly dial the number on Android. However, on iOS, direct dialing won't work, so you'll need a fallback.


Fallback for iOS

For iOS, you can use url_launcher as a fallback to open the dialer:

import 'package:url_launcher/url_launcher.dart';

void dialFallback(String number) async {
  final Uri uri = Uri(
    scheme: 'tel',
    path: number,
  );
  if (await canLaunchUrl(uri)) {
    await launchUrl(uri);
  } else {
    print('Could not launch $uri');
  }
}

Combined Approach

You can combine both solutions to handle platform-specific behaviors:

import 'dart:io';
import 'package:flutter_phone_direct_caller/flutter_phone_direct_caller.dart';
import 'package:url_launcher/url_launcher.dart';

void dialNumber(String number) async {
  if (Platform.isAndroid) {
    // Try direct dialing on Android
    bool? result = await FlutterPhoneDirectCaller.callNumber(number);
    if (result == false || result == null) {
      print('Direct call failed. Opening dialer instead.');
      await openDialer(number);
    }
  } else if (Platform.isIOS) {
    // Use the fallback for iOS
    await openDialer(number);
  }
}

Future<void> openDialer(String number) async {
  final Uri uri = Uri(
    scheme: 'tel',
    path: number,
  );
  if (await canLaunchUrl(uri)) {
    await launchUrl(uri);
  } else {
    print('Could not launch $uri');
  }
}

Upvotes: 0

Related Questions