Flutter Plugin Creation for Native Functionality

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Flutter Plugin Creation for Native Functionality
Complex
~5 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Creating Flutter Plugins for Native Functionality

Flutter provides an extensive set of packages on pub.dev, but eventually you encounter functionality no ready plugin offers: a vendor's proprietary SDK, device-specific work, integration with a corporate system via native agent. This is where custom plugin development via Platform Channels begins.

Platform Channel Architecture

Flutter communicates with native code through MethodChannel, EventChannel, and BasicMessageChannel. Choice depends on interaction pattern:

  • MethodChannel—call native method and get result (request/response)
  • EventChannel—stream of events from native code to Dart (hardware event subscriptions)
  • BasicMessageChannel—bidirectional arbitrary data transfer with custom codec

Typical example: BLE device plugin. Device scanning—EventChannel (continuous stream of discovered devices). Connect/disconnect—MethodChannel. Characteristic notifications—again EventChannel.

Plugin Structure

Create via flutter create --template=plugin my_plugin. Structure:

my_plugin/
  lib/my_plugin.dart          — Dart API
  android/src/.../MyPlugin.kt — Android implementation
  ios/Classes/MyPlugin.swift  — iOS implementation
  example/                    — example app for testing

Dart side declares the contract:

class MyPlugin {
  static const MethodChannel _channel = MethodChannel('my_plugin');

  static Future<String?> getPlatformVersion() async {
    return await _channel.invokeMethod<String>('getPlatformVersion');
  }

  static Stream<ScanResult> get scanResults {
    return const EventChannel('my_plugin/scan_results')
        .receiveBroadcastStream()
        .map((data) => ScanResult.fromMap(Map<String, dynamic>.from(data)));
  }
}

Android Implementation: FlutterPlugin + ActivityAware

On Android, plugin implements FlutterPlugin for lifecycle, MethodCallHandler for call handling. If Activity is needed (permission request), also add ActivityAware:

class MyPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
    private lateinit var channel: MethodChannel
    private var activity: Activity? = null

    override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        channel = MethodChannel(binding.binaryMessenger, "my_plugin")
        channel.setMethodCallHandler(this)
    }

    override fun onMethodCall(call: MethodCall, result: Result) {
        when (call.method) {
            "getPlatformVersion" -> result.success("Android ${android.os.Build.VERSION.RELEASE}")
            else -> result.notImplemented()
        }
    }

    override fun onAttachedToActivity(binding: ActivityPluginBinding) {
        activity = binding.activity
    }
}

Critical detail: result.success(), result.error(), and result.notImplemented() must be called exactly once. Calling result.success() twice causes IllegalStateException: Reply already submitted.

iOS Implementation in Swift

public class MyPlugin: NSObject, FlutterPlugin {
    public static func register(with registrar: FlutterPluginRegistrar) {
        let channel = FlutterMethodChannel(
            name: "my_plugin",
            binaryMessenger: registrar.messenger()
        )
        let instance = MyPlugin()
        registrar.addMethodCallDelegate(instance, channel: channel)
    }

    public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
        switch call.method {
        case "getPlatformVersion":
            result("iOS " + UIDevice.current.systemVersion)
        default:
            result(FlutterMethodNotImplemented)
        }
    }
}

Passing Complex Types

StandardMessageCodec (default) supports primitives, List, Map. For custom objects—serialize to Map<String, dynamic> on Dart side and get HashMap on Kotlin / [String: Any] on Swift. Alternative: Pigeon—a Flutter tool for generating type-safe API from .dart specification. Pigeon generates Kotlin/Swift with typed classes—prevents runtime errors from typos.

EventChannel and Memory Leaks

Using EventChannel on Android, the native side gets EventSink. Typical leak: hold EventSink in a field, Activity recreates on screen rotation, old EventSink isn't validated—calling sink.success() after destruction throws. Solution: nullify sink in onCancel() and check before each call.

Publishing and Versioning

For internal use, plugins live in git and connect via path or git dependency in pubspec.yaml. For pub.dev—flutter pub publish with mandatory pubspec.yaml with homepage, repository, full CHANGELOG.md.

Plugin development: simple (1–2 methods, one platform)—2–4 days. Full cross-platform with EventChannel, permissions, edge-case handling—2–4 weeks. Cost calculated individually.