skip to Main Content

I’m working on a Flutter app and need your help to improve the handling of WhatsApp links. Currently, when I click on a phone number, a bottom sheet (or popup) appears asking if I want to use the dialer or WhatsApp. However, when I choose WhatsApp, it opens a page in the browser and then (on some devices, but not on others) an Android popup that lets me choose between WhatsApp and WhatsApp Business.

This behavior is inconsistent across different devices, and I want to avoid the browser step, as it might confuse less tech-savvy users (which is the majority of my app’s users).

My goal is to make it so that when I press "WhatsApp," a dialog appears directly that allows me to choose between WhatsApp and WhatsApp Business, with the option to do it "only once" or "always." I want to avoid forcing users to change their Android settings to select the default WhatsApp app.

Here’s the code I’m currently using to handle WhatsApp and that is not working as intended:

void _launchWhatsApp(String phoneNumber) async {
  const whatsappBusinessScheme = 'whatsapp://send?phone=';
  const whatsappScheme = 'https://wa.me/';

  final Uri whatsappBusinessUri =
      Uri.parse('$whatsappBusinessScheme$phoneNumber');
  if (await canLaunchUrl(whatsappBusinessUri)) {
    await launchUrl(whatsappBusinessUri);
  } else {
    final Uri whatsappUri = Uri.parse('$whatsappScheme$phoneNumber');
    if (await canLaunchUrl(whatsappUri)) {
      await launchUrl(whatsappUri);
    } else {
      Get.snackbar('error'.tr, 'whatsapp_error'.tr);
    }
  }
}

Do I need to add something in the AndroidManifest or info.plist? Or is there something I’m missing?
Does anyone have suggestions on how to implement this functionality without going through the browser? Any help would be greatly appreciated!

Thanks in advance!

2

Answers


  1. Chosen as BEST ANSWER

    I get it to work on android but i still have problems iOS side.

    On android i modified the MainActivity.kt to include this

    import android.content.Intent
    import android.net.Uri
    import io.flutter.embedding.engine.FlutterEngine
    import io.flutter.plugin.common.MethodChannel
    
    class MainActivity: FlutterActivity() {
      private val CHANNEL = "app.channel.shared.data"
      override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
            .setMethodCallHandler { call, result ->
                if (call.method == "openWhatsApp") {
                    val phoneNumber = call.argument<String>("phoneNumber")
                    openWhatsApp(phoneNumber)
                    result.success(null)
                } else {
                    result.notImplemented()
                }
            }
      }
      private fun openWhatsApp(phoneNumber: String?) {
        try {
            val uri = Uri.parse("whatsapp://send?phone=$phoneNumber")
            val sendIntent = Intent(Intent.ACTION_VIEW, uri)
            val sendIntentWhatsApp = Intent(Intent.ACTION_VIEW, uri)
            sendIntentWhatsApp.setPackage("com.whatsapp")
            val sendIntentBusiness = Intent(Intent.ACTION_VIEW, uri)
            sendIntentBusiness.setPackage("com.whatsapp.w4b")
            val chooserIntent = Intent.createChooser(sendIntent, "Scegli l'app")
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, arrayOf(sendIntentWhatsApp, sendIntentBusiness))
            startActivity(chooserIntent)
        } catch (e: Exception) {
            e.printStackTrace()
        }
      }
    }
    

    then in the phone.dart

    import 'package:flutter/services.dart';
    import 'dart:io';
    
    static const platform = MethodChannel('app.channel.shared.data');
    
    void _launchWhatsApp(String phoneNumber) async {
        if (Platform.isAndroid) {
          try {
            await platform
                .invokeMethod('openWhatsApp', {'phoneNumber': phoneNumber});
          } on PlatformException {
            Get.snackbar('error'.tr, 'whatsapp_error'.tr);
          }
        } else if (Platform.isIOS) {
          _showWhatsAppChoiceDialog(phoneNumber);
        }
      }
    
      void _showWhatsAppChoiceDialog(String phoneNumber) {
        showModalBottomSheet(
          context: Get.context!,
          builder: (BuildContext context) {
            return SafeArea(
              child: Wrap(
                children: <Widget>[
                  ListTile(
                    leading: const FaIcon(FontAwesomeIcons.whatsapp),
                    title: const Text('WhatsApp'),
                    onTap: () {
                      Navigator.pop(context);
                      _launchWhatsAppiOS(phoneNumber, 'whatsapp');
                    },
                  ),
                  ListTile(
                    leading: const FaIcon(FontAwesomeIcons.whatsapp),
                    title: const Text('WhatsApp Business'),
                    onTap: () {
                      Navigator.pop(context);
                      _launchWhatsAppiOS(phoneNumber, 'whatsapp-business');
                    },
                  ),
                ],
              ),
            );
          },
        );
      }
    

    with these mods now when i press on whatsapp button i get a dialog that ask me if i want open it through WA, or WA business .

    i tried to modify swift code too, in a similar way, but it didn't work as expected. I'll keep you updated if i'll manage it to work


  2. Use externalApplication mode in url_launcher

    launchUrl(url, mode: LaunchMode.externalApplication)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search