Purpose of the article: To get the knowledge on creating plugins in Flutter which can be communicated from the Native side (Android)
Intended Audience: Technology Experts
Tools and Technology: Android Studio (IDE), Dart, Flutter, Android, Java, Yaml.
Key words: MethodChannel, Publish, Pub.dev, Plugin, Android Studio (IDE), Dart, Flutter, Android, Java, Yaml.
What is the Flutter Plugin?
The plugin is a wrapper of Native Code (Android & iOS) which is written in Java or Kotlin (for Android) and Objective C or Swift (for iOS). Using the Flutter plugin, you can perform a platform-specific action.
Flutter plugin uses a Method Channel (which acts as a bridge between iOS and Android).
How to create a Custom Plugin for platform-specific in Flutter?
- Let us get started with creating a Plugin
- Choose Flutter Plugin from the popup form as shown below
- Click next and choose your ‘project name’; in this case, it is ‘cc_avenue’
- Make sure you select your comfortable language and platform Android & iOS
- And move to Finish. Please refer the image below
Let us talk about the structure.
If you observe, we have two projects embedded in another. The outer folder contains the platform-specific code, where the embedded project named ‘example’ includes the actual implementation, and other developers can take this folder as an example for implementation. Move ahead and look into the design architecture first.
Flutter Platform Channel Architectural
The block on the left represents the Flutter code where the implementation occurs, and the right-side block is the android code, which has activity and underlying implementations. We can connect the activity through a method channel, and then we can have access to work with the activity, which is of type FlutterView. Let us look into code implementation.
Step1:
Create a Method Channel Use case
In this case, I tried to create a package for ‘cc_avenue,’ the payment gateway.
Step2:
Create a Method that has the arguments to pass the values from Flutter to native platforms.
For a scenario, let us consider a pizza delivery guy who checks for the customer’s name & address and delivers the Pizza. Similarly, the ‘_channel.invokeMethod’ checks with the native platform “Is this CC_Avenue?” If Yes, here are the values. Enjoy the data.😊
Note: You can invoke multiple methods using a single channel.
Now it is time for the android native platform.
Navigate to Android>src>main>com.packagename>{$ProjectName}Plugin in this case it will be ‘CCAvenuePlugin’.
You need to extend the class with FlutterActivity and implement it with FlutterPlugin, MethodCallHandler, and ActivityAware.
Next, you have to declare
Method Channel for registering the channel name
Activity for running the screen as Activity Class Type
Variable for storing the values which come from Flutter
Initialize the Method Channel
You have an Override method called ‘OnMethodCall’. Whenever you invoke the channel, you get a call here, and it checks with the Method Name mentioned in the Flutter side and runs the set of steps appropriately.
In this case, I am checking if the method call is equal to ‘CC_Avenue’ then I am going to receive the call arguments.
You may be wondering what this ‘cCAvenueInit()’ is?
I am actually passing those values to the ‘WebViewActivity’ using ‘Intent.putExtra.’ and starting a web activity from the native side.
In ‘example’ Project
Now come to check the package by specifying the dependency as shown below:
In the ‘example’ project ‘main.dart’ you have to call the package static method as below:
Now the App is running successfully, good job buddy!
It is time to publish the Flutter package to ‘pub.dev’. Before you publish, please ensure to make some changes in ‘pubspec.yaml’ file.
Write a small description about the Package and update the ‘Readme.md’ file with the API documentation and sample code if you like to describe that. Make sure you specify the version and the repository of the package you host.
Step 1:
Run the command in terminal
‘dart pub publish –dry-run’ it is always better to do a dry run, to check and review before you publish. Here is the sample code you can use with the structure.
avinashgo@MTLP-2478 cc_avenue % dart pub publish –dry-run
Publishing cc_avenue 1.0.0
|– .gitignore
|– .idea
| |– .gitignore
| |– copyright
| | |– Avinash_Gotluru.xml
| | ‘– profiles_settings.xml
| |– libraries
| | |– Dart_SDK.xml
| | ‘– Flutter_Plugins.xml
| |– misc.xml
| |– modules.xml
| |– runConfigurations
| | ‘– example_lib_main_dart.xml
| |– runConfigurations.xml
| ‘– vcs.xml
|– .metadata
|– CHANGELOG.md
|– LICENSE
|– README.md
|– android
| |– .gitignore
| |– build.gradle
| |– gradle
| | ‘– wrapper
| | |– gradle-wrapper.jar
| | ‘– gradle-wrapper.properties
| |– gradle.properties
| |– gradlew
| |– gradlew.bat
| |– settings.gradle
| ‘– src
| ‘– main
| |– AndroidManifest.xml
| |– java
| | ‘– com
| | ‘– avinash
| | ‘– gotluru
| | ‘– cc_avenue
| | |– CcAvenuePlugin.java
| | |– Framework
| | | |– ActionDialog.java
| | | |– ApproveOTPFragment.java
| | | |– CityBankFragment.java
| | | |– Communicator.java
| | | |– OtpFragment.java
| | | |– SmsReceiver.java
| | | |– StatusActivity.java
| | | ‘– WebViewActivity.java
| | ‘– Utility
| | |– AvenuesParams.java
| | |– Constants.java
| | |– LoadingDialog.java
| | |– RSAUtility.java
| | ‘– ServiceUtility.java
| ‘– res
| |– layout
| | |– activity_main.xml
| | |– activity_status.xml
| | |– approve_otp_layout.xml
| | |– city_bank_layout.xml
| | ‘– otp_fragment.xml
| ‘– values
| |– arrays.xml
| ‘– strings.xml
|– cc_avenue.iml
|– example
| |– .gitignore
| |– .metadata
| |– README.md
| |– android
| | |– .gitignore
| | |– app
| | | |– build.gradle
| | | ‘– src
| | | |– debug
| | | | ‘– AndroidManifest.xml
| | | |– main
| | | | |– AndroidManifest.xml
| | | | |– java
| | | | | ‘– com
| | | | | ‘– avinash
| | | | | ‘– gotluru
| | | | | ‘– cc_avenue_example
| | | | | ‘– MainActivity.java
| | | | ‘– res
| | | | |– drawable
| | | | | ‘– launch_background.xml
| | | | |– drawable-v21
| | | | | ‘– launch_background.xml
| | | | |– mipmap-hdpi
| | | | | ‘– ic_launcher.png
| | | | |– mipmap-mdpi
| | | | | ‘– ic_launcher.png
| | | | |– mipmap-xhdpi
| | | | | ‘– ic_launcher.png
| | | | |– mipmap-xxhdpi
| | | | | ‘– ic_launcher.png
| | | | |– mipmap-xxxhdpi
| | | | | ‘– ic_launcher.png
| | | | |– values
| | | | | ‘– styles.xml
| | | | ‘– values-night
| | | | ‘– styles.xml
| | | ‘– profile
| | | ‘– AndroidManifest.xml
| | |– build.gradle
| | |– gradle
| | | ‘– wrapper
| | | ‘– gradle-wrapper.properties
| | |– gradle.properties
| | |– settings.gradle
| | ‘– settings_aar.gradle
| |– ios
| | |– .gitignore
| | |– Flutter
| | | |– AppFrameworkInfo.plist
| | | |– Debug.xcconfig
| | | ‘– Release.xcconfig
| | |– Podfile
| | |– Runner
| | | |– AppDelegate.h
| | | |– AppDelegate.m
| | | |– Assets.xcassets
| | | | |– AppIcon.appiconset
| | | | | |– Contents.json
| | | | | |– Icon-App-1024×1024@1x.png
| | | | | |– Icon-App-20×20@1x.png
| | | | | | (10 more…)
| | | | | |– Icon-App-76×76@1x.png
| | | | | |– Icon-App-76×76@2x.png
| | | | | ‘– Icon-App-83.5×83.5@2x.png
| | | | ‘– LaunchImage.imageset
| | | | |– Contents.json
| | | | |– LaunchImage.png
| | | | |– LaunchImage@2x.png
| | | | |– LaunchImage@3x.png
| | | | ‘– README.md
| | | |– Base.lproj
| | | | |– LaunchScreen.storyboard
| | | | ‘– Main.storyboard
| | | |– Info.plist
| | | ‘– main.m
| | |– Runner.xcodeproj
| | | |– project.pbxproj
| | | |– project.xcworkspace
| | | | |– contents.xcworkspacedata
| | | | ‘– xcshareddata
| | | | |– IDEWorkspaceChecks.plist
| | | | ‘– WorkspaceSettings.xcsettings
| | | ‘– xcshareddata
| | | ‘– xcschemes
| | | ‘– Runner.xcscheme
| | ‘– Runner.xcworkspace
| | |– contents.xcworkspacedata
| | ‘– xcshareddata
| | |– IDEWorkspaceChecks.plist
| | ‘– WorkspaceSettings.xcsettings
| |– lib
| | ‘– main.dart
| |– pubspec.yaml
| ‘– test
| ‘– widget_test.dart
|– ios
| |– .gitignore
| |– Assets
| | ‘– .gitkeep
| |– Classes
| | |– CcAvenuePlugin.h
| | ‘– CcAvenuePlugin.m
| ‘– cc_avenue.podspec
|– lib
| ‘– cc_avenue.dart
|– pubspec.yaml
‘– test
‘– cc_avenue_test.dart
The package has zero warnings. Now you have zero errors. It is time to Deploy. Run ‘dart pub publish’ to publish the package.
Type Y for yes.
Click the link to Authenticate, and it will automatically redirect pub.
You can see your published package under My Packages section.
That is it, and your job is done.