Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
How to handle 3rd-Party Apps in a plugin packag...
Search
Katsumi Onishi
August 28, 2018
Technology
1.2k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
How to handle 3rd-Party Apps in a plugin packages in Flutter
Katsumi Onishi
August 28, 2018
More Decks by Katsumi Onishi
See All by Katsumi Onishi
Material Design と Product UI Design
katsummy
2
880
Flutter at Google I/O 2019
katsummy
8
1.5k
TechCon Official App on Flutter
katsummy
1
1k
Other Decks in Technology
See All in Technology
脆弱性診断って、何をしているの? 〜弱点を見つけて、会社の改善につなげるまで〜
keeg
0
680
Lambda MicroVMsが分からなすぎたので使い所を1から考えてみた
tsukuboshi
2
430
[AWS 秋のクラウドオペレーション祭り 2026]AWS DevOps Agentで変わるリリースと運用対応 ~リリース管理機能と Directed actions のご紹介~
furuton
4
1.1k
The seven pitfalls of AI (revised version)
ufried
0
300
しろおびから始める!ログ活用の第一歩
shumei_ito
0
690
購入ドメインでの課題と取り組み
ykagano
0
150
AI時代だからこそ推したい!Gitコマンド再入門
munakata
0
160
UniFi(ユニファイ)AIカメラの現場活用
ludicmind
1
270
AI Made Us Faster at Solving the Wrong Problems
marceloancelmo
0
190
全PRの83%が AIレビューだけでマージできるようになった開発組織は その後どうなったか @2026/10
athug
0
130
自分で立ててみるLLMサービス
y_sera15
0
150
MCPゲートウェイを作って運用してわかったこと — Agent時代の権限管理の現在地
mtpooh
10
3.2k
Featured
See All Featured
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
320
KATA
mclloyd
PRO
35
16k
Un-Boring Meetings
codingconduct
0
440
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
760
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
1
620
Building Adaptive Systems
keathley
44
3.2k
Are puppies a ranking factor?
jonoalderson
2
4k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
Test your architecture with Archunit
thirion
2
2.4k
Embracing the Ebb and Flow
colly
88
5.2k
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
1
550
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
490
Transcript
Handling 3rd-Party Apps in a plugin packages @katsummy - Android
Engineer
Flutter Plugin Package Plugin Package iOS Host FlutterViewController AppDelegate iOS
platform APIs 3rd-Party App Android Host FlutterView Activity Android platform APIs 3rd-Party App App Platform Channels
App / Package / Plugin app : アプリケーション package :
共有モジュール(Dart) plugin : プラットフォームの実装を持つ共有モジュール
Platform Channels プラットフォーム固有のAPIと通信する - Method Channel - Event Channel
Method Channel ホストのメソッドを呼び出してプラットフォームのAPIを実行し、結 果を戻り値として受け取ります。 Flutter App iOS/Android Call Method Return
Value (Synchronous)
Event Channel ブロードキャストストームの受信者をホストに登録し、コールバッ クで非同期にプラットフォームイベントを受信します。 Flutter App iOS/Android BroadcastStream Listener Event
(Asynchronous) Event
Method Channel Implementation
Method Channel - Android Implement (1/2) public class HelloPlugin implements
MethodCallHandler { // static method. public static void registerWith(Registrar registrar) { // 1. MethodChannelを作成 final MethodChannel channel = new MethodChannel(registrar.messenger(), "hello"); // 2. MethodChannelにPluginを登録 HelloPlugin instance = new HelloPlugin(); channel.setMethodCallHandler(instance); } $ flutter create --template=plugin hello
Method Channel - Android Implement (2/2) @Override public void onMethodCall(MethodCall
call, Result result) { // 3. FlutterからのMethodCallを受け取る if (call.method.equals("getPlatformVersion")) { // 4. Flutterへ結果をコールバックする if (/*condition*/) { // 4-1. Success result.success("Android " + android.os.Build.VERSION.RELEASE); } else { // 4-2. Error result.error("ERROR", "errorMessage", null): } } else { // 4-2. NotImplemented Error result.notImplemented(); } } }
Method Channel - iOS Implement (1/2) @interface HelloPlugin : NSObject<FlutterPlugin>
@end @implementation HelloPlugin // Implemented by the iOS part of a FlutterPlugin. + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar { // 1. MethodChannelを作成 FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:@"hello" binaryMessenger:[registrar messenger]]; // 2. MethodChannelにPluginを登録 HelloPlugin* instance = [[HelloPlugin alloc] init]; [registrar addMethodCallDelegate:instance channel:channel]; }
Method Channel - iOS Implement (2/2) - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
// 3. FlutterからのMethodCallを受け取る if ([@"getPlatformVersion" isEqualToString:call.method]) { // 4. Flutterへ結果をコールバックする if (/*condition*/) { // 4-1. Success result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); } else { // 4-2. Error result([FlutterError errorWithCode:@"ERROR" message:"errorMessage" details:nil]); } } else { // 4-2. NotImplemented Error result(FlutterMethodNotImplemented); }
Method Channel - Flutter Implement class Hello { // 1.
MethodChannelを作成 static const MethodChannel _channel = const MethodChannel('hello'); static Future<String> get platformVersion async { // Platform messages may fail, so we use a try/catch PlatformException. try { // 2. メソッドの呼び出し final String version = await _channel.invokeMethod('getPlatformVersion'); return version; } on PlatformException catch (e) { debugPrint(${e}); return null; } } }
Event Channel Implementation
Event Channel - Android Implement (1/4) public class HelloPlugin implements
EventChannel.StreamHandler { // 1. StreamHandlerのメソッドを実装 @Override public void onListen(Object arguments, EventChannel.EventSink events) { } @Override public void onCancel(Object arguments) { }
Event Channel - Android Implement (2/4) public class HelloPlugin implements
EventChannel.StreamHandler { private EventChannel.EventSink _eventSink; public static void registerWith(Registrar registrar) { // 2. EventChannelの作成 final EventChannel eventChannel = EventChannel(registrar.messenger(), "hello"); // 3. EventChannelにPluginを登録 HelloPlugin instance = new HelloPlugin(); eventChannel.setStreamHandler(instance); }
Event Channel - Android Implement (3/4) public class HelloPlugin implements
EventChannel.StreamHandler { // 1. StreamHandlerのメソッドを実装 @Override public void onListen(Object arguments, EventChannel.EventSink events) { // 4. イベントストリームを設定 _eventSink = events; } @Override public void onCancel(Object arguments) { _eventSink = null; }
Event Channel - Android Implement (4/4) final Runnable runnable =
new Runnable() { @Override public void run() { if(_eventSink != null) { // 5. イベントをFlutterにエミット if (/*condition*/) { // 5-1. Success _eventSink.success("Hello"); } else { // 5-2. Error _eventSink.error("ERROR", "errorMessage", null); } } } };
Event Channel - iOS Implement (1/4) @interface HelloPlugin : NSObject<FlutterPlugin,
FlutterStreamHandler> @end // Implemented by the iOS part of a FlutterPlugin and FlutterStreamHandler. @implementation HelloPlugin // 1. StreamHandlerのメソッドを実装 // イベントストリームの設定する要求を処理 - (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink { return nil; } // イベントストリームを破棄する要求を処理 - (FlutterError *)onCancelWithArguments:(id)arguments { return nil; }
Event Channel - iOS Implement (2/4) // Implemented by the
iOS part of a FlutterPlugin and FlutterStreamHandler. @implementation HelloPlugin + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar { // 2. EventChannelの作成 FlutterEventChannel* channel = [FlutterEventChannel eventChannelWithName:@"hello" binaryMessenger:[registrar messenger]]; // 3. EventChannelにPluginを登録 HelloPlugin* instance = [[HelloPlugin alloc] init]; [registrar addMethodCallDelegate:instance channel:methodChannel]; }
Event Channel - iOS Implement (3/4) // イベントストリームの設定する要求を処理 - (FlutterError
*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink { // 4. イベントストリームを設定 _eventSink = eventSink; return nil; } // イベントストリームを破棄する要求を処理 - (FlutterError *)onCancelWithArguments:(id)arguments { _eventSink = nil; return nil; }
Event Channel - iOS Implement (4/4) - (void)emit { [[[NSOperationQueue
alloc] init] addOperationWithBlock:^{ if(_eventSink != null) { // 5. イベントをFlutterにエミット if (/*condition*/) { // 5-1. Success _eventSink("Hello"); } else { // 5-2. Error _eventSink([FlutterError errorWithCode:@"ERROR" message:"errorMessage" details:nil]); } } }]; } @end
Event Channel - Flutter Implement class Hello { // 1.
EventChannelの作成 static const EventChannel _channel = const EventChannel('hello'); Hello() { // 2. ブロードキャストストリームのリスナーを設定 _eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError); } // 3. イベントストリームの処理 void _onEvent(Object event) { debugPrint(${event}); } // 4. エラーストリームの処理 void _onError(Object error) { debugPrint(${error}); }
How to handle 3rd-Party Apps in a plugin packages
Flutter Plugin Package Plugin Package iOS Host FlutterViewController AppDelegate iOS
platform APIs 3rd-Party App Android Host FlutterView Activity Android platform APIs 3rd-Party App App Platform Channels
3rd-Party App Login App Package Login Requeste Plugin 3rd-Party App
startActivityForResult Result Login Result Result <Method Channel> <Event Channel>
Start Activity of 3rd-Party App in Plugin (1/4) class FlutterLineLoginPlugin(registrar:
Registrar) : MethodCallHandler, EventChannel.StreamHandler, PluginRegistry.ActivityResultListener { companion object { // static method. @JvmStatic fun registerWith(registrar: Registrar): Unit { FlutterLineLoginPlugin(registrar) } } Registrar + activeContext() + activity() + addActivityResultListener()
Start Activity of 3rd-Party App in Plugin (2/4) init {
// 1. MethodChannelの作成 val methodChannel = MethodChannel(registrar.messenger(), "net.granoeste/flutter_line_login") // 2. EventChannelの作成 val eventChannel = EventChannel(registrar.messenger(), "net.granoeste/flutter_line_login_result") // 3. MethodChannelとEventChannelにPluginを登録 methodChannel.setMethodCallHandler(this) eventChannel.setStreamHandler(this) // 4. ActivityResultListenerにPluginを登録 registrar.addActivityResultListener(this) }
Start Activity of 3rd-Party App in Plugin (3/4) override fun
onMethodCall(call: MethodCall, result: Result) { // 5. FlutterからのMethodCallを受け取る when (call.method) { "startLogin" -> { // 6. Activityの起動 val loginIntent = LineLoginApi.getLoginIntent(activity, channelId) activity.startActivityForResult(loginIntent, REQUEST_CODE) // 7. Flutterへは成功を返す result.success(null) } // 8. StreamHandlerのメソッドを実装 override fun onListen(arguments: Any?, events: EventChannel.EventSink) { // 9. EventSinkを保管 _eventSink = events }
Start Activity of 3rd-Party App in Plugin (4/4) // 10.
onActivityResultを実装 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean { val result = LineLoginApi.getLoginResultFromIntent(data) when (result.responseCode) { LineApiResponseCode.SUCCESS -> { // 10. EventSinkに成功を流す eventSink.success(null) } else -> { // 11. EventSinkにエラーを流す eventSink.error(result.responseCode.toString(), result.errorData.message, result.errorData.toString()) } } return true
Start Activity of 3rd-Party App in Package (1/3) class FlutterLineLogin
{ // 1. MethodChannelを作成 static const MethodChannel _methodChannel = const MethodChannel('net.granoeste/flutter_line_login'); // 2. EventChannelの作成 static const EventChannel _eventChannel = const EventChannel('net.granoeste/flutter_line_login_result');
Start Activity of 3rd-Party App in Package (2/3) FlutterLineLogin() {
// 3. ブロードキャストストリームのリスナーを設定 _eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError); } // 4. イベントストリームの処理 void _onEvent(Object event) { _onLoginSuccess(event); } // 5. エラーストリームの処理 void _onError(Object error) { _onLoginError(error); }
Start Activity of 3rd-Party App in Package (3/3) Function _onLoginSuccess;
Function _onLoginError; // 6. ログインメソッド startLogin(Function onSuccess, Function onError) async { _onLoginSuccess = onSuccess; _onLoginError = onError; await _methodChannel.invokeMethod('startLogin'); }
Start Activity of 3rd-Party App in App (1/3) // 1.
インスタンス作成 var _flutterLineLogin = new FlutterLineLogin(); // 2. ログイン await _flutterLineLogin.startLogin( (data) => { // LoginSuccess }, (error) => { // LoginError });
flutter_line_login | Flutter Package https://pub.dartlang.org/packages/flutter_line_login FirebaseSignInWithLine https://github.com/granoeste/FirebaseSignInWithLine