{"id":3242,"date":"2023-12-15T12:00:17","date_gmt":"2023-12-15T06:30:17","guid":{"rendered":"https:\/\/www.enablex.io\/insights\/?p=3242"},"modified":"2025-07-24T14:38:11","modified_gmt":"2025-07-24T09:08:11","slug":"app-to-app-calling-feature","status":"publish","type":"post","link":"https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/","title":{"rendered":"Building an App-to-App Calling Feature with Flutter and EnableX\u00a0"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><strong>Building an App-to-App Calling Feature with Flutter and EnableX<\/strong>&nbsp;<\/h2>\n\n\n\n<p>Are you a developer looking to create an app with audio and video calling capabilities? You have come to the right place! This blog explores the seamless creation of an app-to-app calling feature using Flutter and EnableX, a robust platform for real-time communication solutions. However, in this blog, we will address all your questions and provide you with a roadmap using these technologies to get started on this exciting journey.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Introduction to Flutter and EnableX<\/strong>&nbsp;<\/h3>\n\n\n\n<p>Flutter is a popular open-source UI software development kit created by Google, perfect for developing natively compiled applications. When combined with EnableX, a powerful communication platform, it enables the creation of feature-rich <a href=\"https:\/\/www.enablex.io\/developer\/video-api\/client-api\/flutter-toolkit\/\">flutter based calling applications<\/a>.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Why Choose Flutter with EnableX?<\/strong>&nbsp;<\/h3>\n\n\n\n<p><strong>Flutter&#8217;s Cross-Platform Excellence:<\/strong> Flutter has emerged as a leading framework for mobile app development, allowing developers to write a single codebase for both iOS and Android platforms. Therefore, its hot reload feature, rich set of pre-built widgets, and ability to integrate with existing code make it an ideal choice for modern app development.&nbsp;<\/p>\n\n\n\n<p><strong>EnableX&#8217;s Real-Time Communication Capabilities:<\/strong> EnableX provides a suite of APIs and SDKs for embedding video, voice, and messaging functionalities. However, it stands out for its ease of integration, scalability, and reliable backend support, essential for real-time communication features.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Practical Use Cases: Flutter and WebRTC in Action<\/strong>&nbsp;<\/h3>\n\n\n\n<p>The combination of Flutter and WebRTC opens up a plethora of practical use cases across various industries.&nbsp;&nbsp;<\/p>\n\n\n\n<p><strong>Healthcare:<\/strong> With Flutter&#8217;s cross-platform capabilities and WebRTC&#8217;s real-time communication, telehealth apps can facilitate secure, efficient video consultations between doctors and patients, making healthcare more accessible.&nbsp;<\/p>\n\n\n\n<p><strong>Education:<\/strong> E-learning platforms can harness these technologies to create interactive virtual classrooms. Therefore, flutter ensures a consistent user experience across devices, while WebRTC enables real-time student-teacher interactions.&nbsp;<\/p>\n\n\n\n<p><strong>Customer Service:<\/strong> Customer support systems can be greatly enhanced. Flutter allows for the development of smooth, intuitive interfaces, while WebRTC&#8217;s real-time video and voice capabilities enable direct customer-agent communication, elevating the service experience.&nbsp;<\/p>\n\n\n\n<p><strong>Social Networking:<\/strong> For social apps, integrating Flutter with WebRTC means creating engaging, real-time communication experiences, from video calls to live streaming, enhancing social interaction in the digital age.&nbsp;<\/p>\n\n\n\n<p><strong>Financial Services:<\/strong> Banks and financial institutions can use these technologies for secure, real-time customer interactions, including video-based KYC processes and customer advisories, offering convenience and enhancing trust.&nbsp;<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Essential Features of Your App to App Calling video call flutter app<\/strong>&nbsp;<\/h4>\n\n\n\n<p><strong>Peer-to-Peer (P2P) Calls:<\/strong> EnableX ensures high-quality, low-latency P2P communication, essential for a seamless calling experience.&nbsp;<\/p>\n\n\n\n<p><strong>Remote Push Notifications:<\/strong> Essential for alerting users about incoming calls.&nbsp;<\/p>\n\n\n\n<p><strong>Call kit Integration:<\/strong> For Android and iOS, seamlessly integrate the telecom UI to manage call interactions.&nbsp;<\/p>\n\n\n\n<p><strong>EnableX&#8217;s Flutter UI kit:<\/strong> Using Flutter\u2019s widgets and EnableX\u2019s UI kit, developers can design intuitive calling interfaces with responsive controls and engaging visuals.&nbsp;<\/p>\n\n\n\n<p><strong>Scalability and Reliability:<\/strong> EnableX\u2019s cloud infrastructure is designed to handle a high volume of concurrent calls, providing scalability and reliability.&nbsp;<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Enhance video calls with flutter with EnableX&#8217;s UI Kits and Callkit Integration<\/strong>&nbsp;<\/h4>\n\n\n\n<p><strong>EnableX&#8217;s UI Kits for Flutter<\/strong>&nbsp;<\/p>\n\n\n\n<p><strong>Optimized for Flutter:<\/strong> EnableX provides UI kits that are specifically optimized for Flutter, ensuring seamless integration into Flutter-based applications.&nbsp;<\/p>\n\n\n\n<p><strong>Customizable Design:<\/strong> These kits offer customizable UI components, making it easier for developers to tailor the app&#8217;s look and feel according to specific design requirements.&nbsp;<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Callkit Integration for Android and iOS in Flutter Apps<\/strong>&nbsp;<\/h4>\n\n\n\n<p><strong>Native Mobile Experience:<\/strong> EnableX supports Callkit integration for Android and iOS, allowing Flutter apps to deliver a native-like call handling experience on mobile devices.&nbsp;<\/p>\n\n\n\n<p><strong>Advanced Call Management: <\/strong>This integration enables sophisticated features like call waiting and integration with the mobile contacts, enhancing the functionality of the app.&nbsp;<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Getting Started: Your Roadmap<\/strong>&nbsp;<\/h4>\n\n\n\n<p><strong>Create an EnableX Account:<\/strong> Head to <a href=\"https:\/\/www.enablex.io\/free-trial\/?utm_source=www.enablex.io&amp;utm_medium=organic&amp;utm_campaign=header-link\" target=\"_blank\" rel=\"noreferrer noopener\">EnableX&#8217;s sign-up page<\/a> to get your API credentials, including your App ID and App Key.&nbsp;<\/p>\n\n\n\n<p><strong>Set Up Your Flutter Environment:<\/strong> Ensure you have Flutter installed and set up on your machine. If you are new to Flutter, check out the official <a href=\"https:\/\/docs.flutter.dev\/get-started\/install\" target=\"_blank\" rel=\"noreferrer noopener\">Flutter installation guide.<\/a>&nbsp;<\/p>\n\n\n\n<p><strong>Set Up Remote Notification<\/strong>: Set up remote notifications to alert users of incoming calls. Note that EnableX Will not provide any push service for notification. Therefore, app User need to integrate the notification service and handle the notifications based on their business logics.&nbsp;<\/p>\n\n\n\n<p><strong>Flutter to Native Communication:<\/strong> Learn to create method channels in Flutter for sending events to native platforms. This is crucial for events like initiating a call or receiving a call.&nbsp;<\/p>\n\n\n\n<p><strong>Native to Flutter Communication:<\/strong> This involves setting up event channels to send events from native platforms back to Flutter. However, this is used for functionalities like updating the UI based on call status.&nbsp;<\/p>\n\n\n\n<p>Create a Video Project<strong>\u202f\u202f<\/strong>&nbsp;<\/p>\n\n\n\n<p>\u202f&nbsp;<\/p>\n\n\n\n<p>To develop a video conferencing App using Android UI Kit, first, you need to create a Video Project with EnableX Platform. Thus, to create a Video project, do the following:\u202f\u202f&nbsp;<\/p>\n\n\n\n<ul>\n<li>Navigate to <strong>My Dashboard<\/strong>, go to <strong>My Projects<\/strong> section and click on <strong>CREATE PROJECT<\/strong> button\u202f\u202f&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>\u202f&nbsp;<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" width=\"562\" height=\"200\" src=\"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/12\/image-3.png\" alt=\"\" class=\"wp-image-3243\" srcset=\"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/12\/image-3.png 562w, https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/12\/image-3-300x107.png 300w\" sizes=\"(max-width: 562px) 100vw, 562px\" \/><\/figure><\/div>\n\n\n<p>\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>\u202f\u202f&nbsp;<\/p>\n\n\n\n<ul>\n<li>A <strong>Create Project<\/strong> form will open. Enter the project-related information like <em>project name, application<\/em> and <em>description<\/em> and enable <em>Video <\/em>in the Channels section.\u202f\u202f&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>\u202f\u202f&nbsp;<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" width=\"745\" height=\"470\" src=\"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/12\/image-5.png\" alt=\"\" class=\"wp-image-3245\" srcset=\"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/12\/image-5.png 745w, https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/12\/image-5-300x189.png 300w\" sizes=\"(max-width: 745px) 100vw, 745px\" \/><\/figure><\/div>\n\n\n<p>\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>\u202f&nbsp;<\/p>\n\n\n\n<p>Once you have filled in all the necessary information, click on the <strong>CREATE PROJECT<\/strong> button to create your project. Now, a confirmation popup will then appear, confirming the successful creation of your project. Click on <strong>GET STARTED<\/strong> to proceed further.\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>\u202f\u202f&nbsp;<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" width=\"527\" height=\"251\" src=\"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/12\/image-4.png\" alt=\"\" class=\"wp-image-3244\" srcset=\"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/12\/image-4.png 527w, https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/12\/image-4-300x143.png 300w\" sizes=\"(max-width: 527px) 100vw, 527px\" \/><\/figure><\/div>\n\n\n<p>\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>Get APP ID and APP KEY for Android based Video API Conferencing<strong>\u202f\u202f<\/strong>&nbsp;<\/p>\n\n\n\n<p>\u202fThe App ID and App Key, serve as the username and password, respectively, in the HTTP Base Authentication Request Header of our Video Server API Call.\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>When you create a project, the API Access Credentials are sent to you via email. However, you may need to reset API Key or resend API Credentials. To know more, read our comprehensive <a href=\"https:\/\/www.enablex.io\/developer\/video\/solutions\/video-ui-kit\/android-video-ui-kit\/\" target=\"_blank\" rel=\"noreferrer noopener\">developer documentation<\/a>.\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>\u202f&nbsp;<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Create Virtual rooms and Generate Token<strong>\u202f\u202f<\/strong>&nbsp;<\/h5>\n\n\n\n<p><strong>\u202fHow to Create virtual meeting Rooms\u202f&nbsp;using video API<\/strong><\/p>\n\n\n\n<p>To create a room, make an <strong>HTTP POST<\/strong> request to the following API route: <a href=\"https:\/\/api.enablex.io\/video\/v2\/rooms\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/api.enablex.io\/video\/v2\/rooms<\/a>. You need to include the necessary parameters and values in the request body, which should be in JSON format. For example:\u202f\u202f&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>{\u202f\u202f \n\n\u202f \"name\": \"Topic or Room Title\",\u202f\u202f \n\n\u202f \"owner_ref\": \"xyz\",\u202f\u202f \n\n\u202f \"settings\": {\u202f\u202f \n\n\u202f \u202f \"description\": \"Descriptive text\",\u202f\u202f \n\n\u202f \u202f \"mode\": \"group\",\u202f\u202f \n\n\u202f \u202f \"scheduled\": false,\u202f\u202f \n\n\u202f \u202f \"adhoc\": false,\u202f\u202f \n\n\u202f \u202f \"duration\": 30,\u202f\u202f \n\n\u202f \u202f \u2026\u2026\u2026.\u202f\u202f \n\n\u202f\u202f\u202f \u2026\u2026..\u202f\u202f \n\n}\u202f\u202f <\/code><\/pre>\n\n\n\n<p>To know more about Create Rooms, please read <a href=\"https:\/\/www.enablex.io\/developer\/video-api\/server-api\/rooms-route\/#create-room\" target=\"_blank\" rel=\"noreferrer noopener\">Create Room to carry out RTC Session <\/a>.\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>\u202f&nbsp;<\/p>\n\n\n\n<p><strong>Generate Token<\/strong>\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>\u202f&nbsp;<\/p>\n\n\n\n<p>To create a token for joining an RTC session on the EnableX platform, make a POST request to the API route: <a href=\"https:\/\/api.enablex.io\/v2\/rooms\/%7broom-id%7d\/tokens\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/api.enablex.io\/v2\/rooms\/{room-id}\/tokens<\/a> where {room-id} is the ID of the room you want to join. For example:\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>\u202f&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">POST<code> https:\/\/api.enablex.io\/video\/v2\/rooms\/{room_id}\/tokens\u202f\u202f&nbsp;\n\nAuthorization: Basic XXXXXXX\u202f\u202f&nbsp;\n\nContent-Type: application\/json\u202f\u202f&nbsp;\n\n\u202f\u202f&nbsp;\n\n{\u202f\u202f&nbsp;\n\n\u202f \u202f \u202f\"name\": \"User Name\",\u202f\u202f&nbsp;\n\n\u202f \u202f \u202f\"role\": \"participant\",\u202f\u202f&nbsp;\n\n\u202f \u202f \u202f\"user_ref\": \"XXX\",\u202f\u202f&nbsp;\n\n\u202f \u202f \u202f\"data\": {\u202f\u202f&nbsp;\n\n\u202f \u202f \u202f \u202f \"custom_key\": \"String\",\u202f\u202f&nbsp;\n\n\u202f \u202f \"any_key\": \"String\"\u202f\u202f&nbsp;\n\n\u202f \u202f \u202f}\u202f\u202f&nbsp;\n\n}<\/code><\/pre>\n\n\n\n<p>\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>Upon successful creation, the API will respond with a JSON object containing the result and the generated token (<strong><em>JWT_WEB_TOKEN<\/em><\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>{\u202f\u202f \n\n\u202f \u202f \u202f\"result\": 0,\u202f\u202f\u202f \n\n\u202f \u202f \u202f\"token\": \"JWT_WEB_TOKEN\"\u202f\u202f \n\n\u202f}<\/code><\/pre>\n\n\n\n<p>\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>To know more about Token, please read <a href=\"https:\/\/www.enablex.io\/developer\/video-api\/server-api\/rooms-route\/#create-token\" target=\"_blank\" rel=\"noreferrer noopener\">Create Token to join a Room<\/a>.\u202f\u202f&nbsp;<\/p>\n\n\n\n<p>Integrate Flutter UI Kit into project<strong>\u202f<\/strong>&nbsp;<\/p>\n\n\n\n<p>\u202f&nbsp;<\/p>\n\n\n\n<p>Once you have created a video project with the EnableX Platform and established a virtual video meeting room, the next step is to integrate the Flutter UI Kit into your project. Following are the steps:\u202f&nbsp;<\/p>\n\n\n\n<ol start=\"1\">\n<li>Install <a href=\"https:\/\/pub.dev\/packages\/enx_uikit_flutter\" target=\"_blank\" rel=\"noreferrer noopener\">Flutter UI Kit<\/a> through pub. V1. 3.&nbsp;<\/li>\n<\/ol>\n\n\n\n<ol start=\"2\">\n<li><strong>Add Dependency<\/strong>&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>Add <strong><em>enx_uikit_flutter<\/em><\/strong> as a dependency to your <strong><em>pubspec.yaml<\/em><\/strong> file.&nbsp;<\/p>\n\n\n\n<ol start=\"3\">\n<li><strong>Define required Device Permissions<\/strong>&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>Firstly, EnableX Flutter UI Kit requires camera and microphone permission to start video call.&nbsp;<\/p>\n\n\n\n<p><strong>For Android:<\/strong>&nbsp;<\/p>\n\n\n\n<p>Open your <strong><em>AndroidManifest.xml<\/em><\/strong> file and add the required permissions:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>&lt;uses-permission android:name=\"android.permission.CAMERA\" \/&gt;&nbsp;\n\n&lt;uses-permission android:name=\"android.permission.RECORD_AUDIO\" \/&gt;<\/code><\/pre>\n\n\n\n<p>&#8230;&nbsp;<\/p>\n\n\n\n<p><strong>For iOS:<\/strong>&nbsp;<\/p>\n\n\n\n<p>In the <strong><em>info.plist<\/em><\/strong>, add entries for microphone and camera usage descriptions.&nbsp;<\/p>\n\n\n\n<ol start=\"4\">\n<li><strong>Handle Camera and Microphone Permissions in Flutter<\/strong>&nbsp;<\/li>\n<\/ol>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>Create a Common Method for Permissions:<\/strong>&nbsp;<\/h5>\n\n\n\n<p>Implement a method to request and check camera and microphone permissions using the <strong><em>permission_handler<\/em><\/strong> package.<strong>&nbsp;<\/strong>&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>Future&lt;bool&gt; handlePermissionsForCall(BuildContext context) async {&nbsp;\n\n\u202f ...&nbsp;\n\n\u202f \/\/ Permission handling logic&nbsp;\n\n}<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>Implement a Custom Dialog for Permission Handling:<\/strong>&nbsp;<\/h5>\n\n\n\n<p>Show a dialog to the user if permissions are denied or not granted.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>void showCustomDialog(BuildContext context, String title, String message, Function okPressed) {&nbsp;\n\n\u202f ...&nbsp;\n\n\u202f \/\/ Dialog implementation&nbsp;\n\n}<\/code><\/pre>\n\n\n\n<p>For more information, please read <a href=\"https:\/\/www.enablex.io\/developer\/video\/solutions\/video-ui-kit\/flutter-video-ui-kit\/\" target=\"_blank\" rel=\"noreferrer noopener\">Flutter UI Kit<\/a>.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Once device permission is granted, move to the next steps.&nbsp;<\/p>\n\n\n\n<ol start=\"5\">\n<li><strong>Implement Flutter UI Kit<\/strong>&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>Import Package at the top of your Dart file and Initialize <strong><em>EnxVideoView <\/em><\/strong>with a valid token and handle callbacks for connection errors or disconnections.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>import 'package:enx_uikit_flutter\/enx_uikit_flutter.dart';&nbsp;\n\nEnxVideoView(&nbsp;\n\n\u202f token: token,&nbsp;\n\n\u202f connectError: (Map&lt;dynamic, dynamic&gt; map) {&nbsp;\n\n\u202f \u202f ...&nbsp;\n\n\u202f },&nbsp;\n\n\u202f disconnect: (Map&lt;dynamic, dynamic&gt; map) {&nbsp;\n\n\u202f \u202f ...&nbsp;\n\n\u202f },&nbsp;\n\n);<\/code><\/pre>\n\n\n\n<ol start=\"6\">\n<li><strong>UI Customization<\/strong>&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>Utilize <strong><em>EnxSetting<\/em><\/strong> in your Flutter app to customize UI elements such as bottom and top options, configure participant lists, and create extra buttons.&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>var setting = EnxSetting.instance;&nbsp;\n\nsetting.createBottomOption(BottomOption.audio);&nbsp;\n\n...&nbsp;\n\nsetting.configureParticipantList(ParticipantListOption.disconnect);&nbsp;\n\n...<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>Import the Native Call Kit Component into Your Project<\/strong>&nbsp;<\/h5>\n\n\n\n<p><strong>Please read:&nbsp;&nbsp;<\/strong>&nbsp;<\/p>\n\n\n\n<ul>\n<li><strong>EnableX\u2019s <\/strong><a href=\"https:\/\/www.enablex.io\/developer\/video\/solutions\/calling-ui-framework\/android-calling-ui-framework\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Android Calling UI Framework<\/strong><\/a><strong><\/strong>&nbsp;<\/li>\n\n\n\n<li><strong>EnableX\u2019s <\/strong><a href=\"https:\/\/www.enablex.io\/developer\/video\/solutions\/calling-ui-framework\/ios-calling-ui-framework\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>iOS Calling UI Framework<\/strong><\/a><strong><\/strong>&nbsp;<\/li>\n<\/ul>\n\n\n\n<p><strong>Bridging Flutter with Native Platforms:<\/strong>&nbsp;<\/p>\n\n\n\n<p>To develop a real-time Flutter communication application, it\u2019s crucial to understand how Flutter communicates with native code. This is achieved through two primary channels: Method Channels and Event Channels.&nbsp;<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>Notifying Events from Flutter to Native: Using Method Channels<\/strong>&nbsp;<\/h5>\n\n\n\n<p>Method Channels serve as a communication bridge between Flutter and native code. Moreover, method Channels are used to send data from Flutter to the native side (iOS or Android). This is particularly useful when you need to trigger native functions from your Flutter app.&nbsp;<\/p>\n\n\n\n<p><strong>In Flutter:<\/strong>&nbsp;<\/p>\n\n\n\n<ul>\n<li>Create a <strong><em>MethodChannel <\/em><\/strong>with a unique identifier.&nbsp;<\/li>\n\n\n\n<li>Send data or trigger events using this channel.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>Flutter code snippet for reference:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>static const platform = MethodChannel('flutter.native\/helper');&nbsp;&nbsp;\n\n\/\/Sent event to iOS\/Android&nbsp;&nbsp;\n\nFuture _getInformation() async {&nbsp;\n\n\u202f \u202f try {&nbsp;&nbsp;\n\n\u202f \u202f \u202f \u202f var result = await platform.invokeMethod('Event NAme');&nbsp;&nbsp;\n\n\u202f \u202f \u202f \u202f tokenValue = result;&nbsp;\n\n\u202f \u202f \u202f \u202f } on PlatformException catch (e) {&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f tokenValue = \"Failed to get battery level: '${e.message}'.\";&nbsp;\n\n\u202f \u202f \u202f \u202f }&nbsp;&nbsp;\n\n\u202f \u202f print(tokenValue);&nbsp;\n\n}<\/code><\/pre>\n\n\n\n<p><strong>In iOS (Swift):<\/strong>&nbsp;<\/p>\n\n\n\n<ul>\n<li>In the <strong><em>AppDelegate<\/em><\/strong>, register the <strong><em>FlutterMethodChannel<\/em><\/strong> with the same identifier.&nbsp;<\/li>\n\n\n\n<li>Set a method call handler to respond to Flutter events.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>An iOS sample code in Swift:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>In AppDelegate.swift class&nbsp;&nbsp;\n\nAt didFinishLaunchingWithOptions method&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f var flutterChannel \u202f= FlutterMethodChannel(name: \"flutter.native\/helper\",&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f binaryMessenger: controller.binaryMessenger)&nbsp;\n\nRegister the event listener from the flutter&nbsp;&nbsp;\n\n\u202f \u202f \u202f \u202f flutterChannel.setMethodCallHandler({[weak self] (call: FlutterMethodCall , result : FlutterResult) -&gt; Void in&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f if call.method.caseInsensitiveCompare(\"Your Event Name which you have set in flutter\") == .orderedSame{&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \/\/Take Action in iOS Native&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f }&nbsp;\n\n\u202f \u202f \u202f })<\/code><\/pre>\n\n\n\n<p><strong>In Android (Kotlin):<\/strong>&nbsp;<\/p>\n\n\n\n<ul>\n<li>In the <strong><em>MainActivity<\/em><\/strong>, set up the MethodChannel and override the <strong><em>onMethodCall<\/em><\/strong> to handle calls from Flutter.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>Example Kotlin code:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>In Main Activity class&nbsp;&nbsp;\n\n\u202f \u202f private val channel = \"flutter.native\/helper\"&nbsp;\n\n\u202f \u202f \/\/Override methods&nbsp;\n\n\u202f \u202f override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {&nbsp;\n\n\u202f \u202f \u202f \u202f super.configureFlutterEngine(flutterEngine)&nbsp;\n\n\u202f \u202f \u202f \u202f EventChannel(flutterEngine.dartExecutor, eventHandlerChannel).setStreamHandler(&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f object : StreamHandler(), EventChannel.StreamHandler {&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f override fun onListen(arguments: Any?, events: EventSink?) {&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f if (events != null) {&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f eventsL=events&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f events.success(arguments);&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f }&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f }&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f override fun onCancel(arguments: Any?) {&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f eventsL=null&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f }&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f }&nbsp;\n\n\u202f \u202f \u202f \u202f )&nbsp;\n\n\u202f \u202f \u202f \u202f MethodChannel(flutterEngine.dartExecutor.binaryMessenger, channel).setMethodCallHandler {&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \/\/ This method is invoked on the main thread.&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f call, result -&gt;&nbsp;\n\n\u202f \u202f \u202f \u202f }&nbsp;\n\n\u202f \u202f }<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>Communication from Native to Flutter: Using Event Channels&nbsp;<\/strong>&nbsp;<\/h5>\n\n\n\n<p>Event Channels are used for streaming continuous data or events from the native side back to Flutter. This is important for updating the Flutter UI based on native events.&nbsp;<\/p>\n\n\n\n<p><strong>Setting Up Event Channels<\/strong>&nbsp;<\/p>\n\n\n\n<p><strong>In Flutter:<\/strong>&nbsp;<\/p>\n\n\n\n<ul>\n<li>Define an <strong><em>EventChannel <\/em><\/strong>with a specific channel name.&nbsp;<\/li>\n\n\n\n<li>Listen to this channel to receive events from the native platform.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>Flutter code snippet for reference:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>static const EventChannel eventChannel = EventChannel('flutter.native\/helperCallBacks');&nbsp;\n\n\u202f \u202f void _onEvent(Object event) {&nbsp;\n\n\u202f \u202f print(\"Test Callback$event\");&nbsp;\n\n\u202f }<\/code><\/pre>\n\n\n\n<p>In this code, Flutter listens to an event channel named <strong><em>flutter.native\/helperCallBacks<\/em><\/strong> and prints any events received.&nbsp;<\/p>\n\n\n\n<p><strong>In iOS (Swift):<\/strong>&nbsp;<\/p>\n\n\n\n<ul>\n<li>Set up a <strong><em>FlutterEventChannel <\/em><\/strong>in the <strong><em>AppDelegate.swift<\/em><\/strong> class with the same channel name.&nbsp;<\/li>\n\n\n\n<li>Handle the listener from Flutter and use an <strong><em>eventSink <\/em><\/strong>to send events back to Flutter.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>An iOS sample code in Swift:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>In AppDelegate.swift class&nbsp;&nbsp;\n\n\u202f \u202f private var eventSink: FlutterEventSink?&nbsp;\n\nAt didFinishLaunchingWithOptions method&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f let chargingChannel = FlutterEventChannel(name: \"flutter.native\/helperCallBacks\",&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f binaryMessenger: controller.binaryMessenger)&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f chargingChannel.setStreamHandler(self)&nbsp;&nbsp;\n\n*Handel the listener from Flutter to iOS&nbsp;\n\n\/\/Update the eventSink on the listener&nbsp;\n\n\u202f \u202f func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -&gt; FlutterError? {&nbsp;\n\n\u202f \u202f \u202f \u202f self.eventSink1 = events&nbsp;\n\n\u202f \u202f \u202f \u202f return nil&nbsp;\n\n\u202f \u202f }&nbsp;\n\n\u202f \u202f func onCancel(withArguments arguments: Any?) -&gt; FlutterError? {&nbsp;\n\n\u202f \u202f \u202f \u202f \/\/ to do&nbsp;\n\n\u202f \u202f \u202f \u202f eventSink1 = nil&nbsp;\n\n\u202f \u202f \u202f \u202f return nil&nbsp;\n\n\u202f \u202f }&nbsp;\n\n\u202f \u202f\/\/Send event back to flutter&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202feventSink(\"callAnswer\")<\/code><\/pre>\n\n\n\n<p>This Swift code snippet listens for Flutter&#8217;s requests and can send data back to Flutter through the <strong><em>eventSink<\/em><\/strong>.&nbsp;<\/p>\n\n\n\n<p><strong>In Android (Kotlin):<\/strong>&nbsp;<\/p>\n\n\n\n<ul>\n<li>In the main Android activity, set up an <strong><em>EventChannel<\/em><\/strong> and override its methods to handle communication with Flutter.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>For example Kotlin code:&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>In Main Activity class&nbsp;&nbsp;\n\n\u202f \u202f private val eventHandlerChannel = \"flutter.native\/helperCallBacks\"&nbsp;\n\n\u202f \u202f private var eventsL: EventSink? = null&nbsp;\n\n\u202f \u202f \/\/Override methods&nbsp;\n\n\u202f \u202f var enxCallKitStateObserver= \u202fobject : EnxCallKitStateObserver {&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202f \u202feventsL?.success(\"callAnswer\")&nbsp;\n\n\u202f \u202f \u202f \u202f \u202f \u202f}<\/code><\/pre>\n\n\n\n<p>This Kotlin code sets up an EventChannel and provides mechanisms to send events back to the Flutter side.&nbsp;<\/p>\n\n\n\n<p>We have explored the realms of Flutter and EnableX, uncovering the potential of these powerful platforms in building app-to-app calling features.&nbsp;&nbsp;<\/p>\n\n\n\n<p>For those eager to explore more, I recommend visiting the official <a href=\"https:\/\/docs.flutter.dev\/get-started\/install\" target=\"_blank\" rel=\"noreferrer noopener\">Flutter documentation<\/a> , <a href=\"https:\/\/www.enablex.io\/developer\/video\/solutions\/video-ui-kit\/flutter-video-ui-kit\/\" target=\"_blank\" rel=\"noreferrer noopener\">EnableX resources<\/a> and <a href=\"https:\/\/github.com\/EnableX\/App_To_App_calling_flutter\" target=\"_blank\" rel=\"noreferrer noopener\">App to App Calling with Flutter sample App<\/a>. However, these resources offer extensive guides and community support to aid your development journey.&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Building an App-to-App Calling Feature with Flutter and EnableX&nbsp; Are you a developer looking to create an app with audio and video calling capabilities? You have come to the right place! This blog explores the seamless creation of an app-to-app calling feature using Flutter and EnableX, a robust platform for real-time communication solutions. However, in &#8230;<\/p>\n","protected":false},"author":25,"featured_media":3307,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":true,"footnotes":""},"categories":[15],"tags":[],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v21.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>How to build App to App Calling with Flutter | EnableX<\/title>\n<meta name=\"description\" content=\"Build App to App calling feature with flutter by simply following the step-by-step process to enhance user experience! Free Trial included!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to build App to App Calling with Flutter | EnableX\" \/>\n<meta property=\"og:description\" content=\"Build App to App calling feature with flutter by simply following the step-by-step process to enhance user experience! Free Trial included!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/\" \/>\n<meta property=\"og:site_name\" content=\"Insights about video API, SMS API; WhatsApp for Business API\" \/>\n<meta property=\"article:published_time\" content=\"2023-12-15T06:30:17+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-07-24T09:08:11+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/12\/App-to-App-Call-feature-Flutter-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1536\" \/>\n\t<meta property=\"og:image:height\" content=\"541\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Jason Wills\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@enablexio\" \/>\n<meta name=\"twitter:site\" content=\"@enablexio\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jason Wills\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to build App to App Calling with Flutter | EnableX","description":"Build App to App calling feature with flutter by simply following the step-by-step process to enhance user experience! Free Trial included!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/","og_locale":"en_US","og_type":"article","og_title":"How to build App to App Calling with Flutter | EnableX","og_description":"Build App to App calling feature with flutter by simply following the step-by-step process to enhance user experience! Free Trial included!","og_url":"https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/","og_site_name":"Insights about video API, SMS API; WhatsApp for Business API","article_published_time":"2023-12-15T06:30:17+00:00","article_modified_time":"2025-07-24T09:08:11+00:00","og_image":[{"width":1536,"height":541,"url":"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/12\/App-to-App-Call-feature-Flutter-1.png","type":"image\/png"}],"author":"Jason Wills","twitter_card":"summary_large_image","twitter_creator":"@enablexio","twitter_site":"@enablexio","twitter_misc":{"Written by":"Jason Wills","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/#article","isPartOf":{"@id":"https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/"},"author":{"name":"Jason Wills","@id":"https:\/\/www.enablex.io\/insights\/#\/schema\/person\/422d2b153c3c96827da141c6446d11a3"},"headline":"Building an App-to-App Calling Feature with Flutter and EnableX\u00a0","datePublished":"2023-12-15T06:30:17+00:00","dateModified":"2025-07-24T09:08:11+00:00","mainEntityOfPage":{"@id":"https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/"},"wordCount":1890,"publisher":{"@id":"https:\/\/www.enablex.io\/insights\/#organization"},"articleSection":["Blog"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/","url":"https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/","name":"How to build App to App Calling with Flutter | EnableX","isPartOf":{"@id":"https:\/\/www.enablex.io\/insights\/#website"},"datePublished":"2023-12-15T06:30:17+00:00","dateModified":"2025-07-24T09:08:11+00:00","description":"Build App to App calling feature with flutter by simply following the step-by-step process to enhance user experience! Free Trial included!","breadcrumb":{"@id":"https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.enablex.io\/insights\/app-to-app-calling-feature\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.enablex.io\/insights\/"},{"@type":"ListItem","position":2,"name":"Building an App-to-App Calling Feature with Flutter and EnableX\u00a0"}]},{"@type":"WebSite","@id":"https:\/\/www.enablex.io\/insights\/#website","url":"https:\/\/www.enablex.io\/insights\/","name":"Enablex","description":"","publisher":{"@id":"https:\/\/www.enablex.io\/insights\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.enablex.io\/insights\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.enablex.io\/insights\/#organization","name":"Enablex","url":"https:\/\/www.enablex.io\/insights\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.enablex.io\/insights\/#\/schema\/logo\/image\/","url":"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/05\/EnableX-Logo-01.png","contentUrl":"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2023\/05\/EnableX-Logo-01.png","width":17382,"height":3567,"caption":"Enablex"},"image":{"@id":"https:\/\/www.enablex.io\/insights\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/twitter.com\/enablexio","https:\/\/www.linkedin.com\/company\/vcloudx"]},{"@type":"Person","@id":"https:\/\/www.enablex.io\/insights\/#\/schema\/person\/422d2b153c3c96827da141c6446d11a3","name":"Jason Wills","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.enablex.io\/insights\/#\/schema\/person\/image\/","url":"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2025\/05\/envato-labs-ai-f14f6981-d7f8-4c3e-9234-00323c7d5ca0-96x96.jpg","contentUrl":"https:\/\/www.enablex.io\/insights\/wp-content\/uploads\/2025\/05\/envato-labs-ai-f14f6981-d7f8-4c3e-9234-00323c7d5ca0-96x96.jpg","caption":"Jason Wills"},"description":"Jason works behind the scenes at EnableX, helping to turn complex tech into practical tools that developers and businesses can actually use. With several years of experience in product development and platform architecture, he focuses on making communication technologies simpler, smarter and easier to build with. Whether he's writing step-by-step guides, product tips or explaining how our APIs work, Jason keeps things clear and useful.","sameAs":["https:\/\/www.enablex.io\/","https:\/\/www.linkedin.com\/company\/vcloudx\/"],"url":"https:\/\/www.enablex.io\/insights\/author\/jason-wills\/"}]}},"_links":{"self":[{"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/posts\/3242"}],"collection":[{"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/comments?post=3242"}],"version-history":[{"count":0,"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/posts\/3242\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/media\/3307"}],"wp:attachment":[{"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/media?parent=3242"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/categories?post=3242"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.enablex.io\/insights\/wp-json\/wp\/v2\/tags?post=3242"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}