// Send a binary message from Dart to the platform.
final WriteBuffer buffer = WriteBuffer() ..putFloat64(3.1415) ..putInt32(12345678); final ByteData message = buffer.done(); await BinaryMessages.send('foo', message); print('Message sent, reply ignored');
// Receive binary messages from Dart on Android. // This code can be added to a FlutterActivity subclass, typically // in onCreate.
flutterView.setMessageHandler("foo") { message, reply -> message.order(ByteOrder.nativeOrder()) val x = message.double val n = message.int Log.i("MSG", "Received: $x and $n") reply.reply(null) }
// Receive binary messages from Dart on iOS. // This code can be added to a FlutterAppDelegate subclass, // typically in application:didFinishLaunchingWithOptions:.
let flutterView = window?.rootViewController as! FlutterViewController; flutterView.setMessageHandlerOnChannel("foo") { (message: Data!, reply: FlutterBinaryReply) -> Void in let x : Float64 = message.subdata(in: 0..<8) .withUnsafeBytes { $0.pointee } let n : Int32 = message.subdata(in: 8..<12) .withUnsafeBytes { $0.pointee } os_log("Received %f and %d", x, n) reply(nil) }
// Send a binary message from Android.
val message = ByteBuffer.allocateDirect(12) message.putDouble(3.1415) message.putInt(123456789) flutterView.send("foo", message) { _ -> Log.i("MSG", "Message sent, reply ignored") }
// Send a binary message from iOS.
var message = Data(capacity: 12) var x : Float64 = 3.1415 var n : Int32 = 12345678 message.append(UnsafeBufferPointer(start: &x, count: 1)) message.append(UnsafeBufferPointer(start: &n, count: 1)) flutterView.send(onChannel: "foo", message: message) {(_) -> Void in os_log("Message sent, reply ignored") }
// Receive binary messages from the platform.
BinaryMessages.setMessageHandler('foo', (ByteData message) async { final ReadBuffer readBuffer = ReadBuffer(message); final double x = readBuffer.getFloat64(); final int n = readBuffer.getInt32(); print('Received $x and $n'); return null; });
// String messages
// Dart side
const channel = BasicMessageChannel<String>('foo', StringCodec());
// Send message to platform and receive reply.final String reply = await channel.send('Hello, world'); print(reply);
// Receive messages from platform and send replies. channel.setMessageHandler((String message) async { print('Received: $message'); return 'Hi from Dart'; });
// Android side
val channel = BasicMessageChannel<String>( flutterView, "foo", StringCodec.INSTANCE)
// Send message to Dart and receive reply.channel.send("Hello, world") { reply -> Log.i("MSG", reply) }
// Receive messages from Dart and send replies.channel.setMessageHandler { message, reply -> Log.i("MSG", "Received: $message") reply.reply("Hi from Android") }
// iOS side
let channel = FlutterBasicMessageChannel( name: "foo", binaryMessenger: controller, codec: FlutterStringCodec.sharedInstance())
// Send message to Dart and receive reply.channel.sendMessage("Hello, world") {(reply: Any?) -> Void in os_log("%@", type: .info, reply as! String) }
// Receive messages from Dart and send replies. channel.setMessageHandler { (message: Any?, reply: FlutterReply) -> Void in os_log("Received: %@", type: .info, message as! String) reply("Hi from iOS") }
const codec = StringCodec();
// Send message to platform and receive reply.final String reply = codec.decodeMessage( await BinaryMessages.send( 'foo', codec.encodeMessage('Hello, world'), ), ); print(reply);
// Receive messages from platform and send replies. BinaryMessages.setMessageHandler('foo', (ByteData message) async { print('Received: ${codec.decodeMessage(message)}'); return codec.encodeMessage('Hi from Dart'); });
final String reply1 = await channel.send(msg1); final int reply2 = await channel.send(msg2);
final List<String> reply3 = await channel.send(msg3); // Fails.final List<dynamic> reply3 = await channel.send(msg3); // Works.
Future<String> greet() => channel.send('hello, world'); // Fails.Future<String> greet() async { // Works. final String reply = await channel.send('hello, world'); return reply; }
// Invocation of platform methods, simple case.
// Dart side.
const channel = MethodChannel('foo'); final String greeting = await channel.invokeMethod('bar', 'world'); print(greeting);
// Android side.
val channel = MethodChannel(flutterView, "foo") channel.setMethodCallHandler { call, result -> when (call.method) { "bar" -> result.success("Hello, ${call.arguments}") else -> result.notImplemented() } }
// iOS side.
let channel = FlutterMethodChannel( name: "foo", binaryMessenger: flutterView) channel.setMethodCallHandler { (call: FlutterMethodCall, result: FlutterResult) -> Void in switch (call.method) { case "bar": result("Hello, \(call.arguments as! String)") default: result(FlutterMethodNotImplemented) } }
const codec = StandardMethodCodec();
final ByteData reply = await BinaryMessages.send( 'foo', codec.encodeMethodCall(MethodCall('bar', 'world')), ); if (reply == null) throw MissingPluginException(); else print(codec.decodeEnvelope(reply));
await channel.invokeMethod('bar'); await channel.invokeMethod('bar', <dynamic>['world', 42, pi]); await channel.invokeMethod('bar', <String, dynamic>{ name: 'world', answer: 42, math: pi, }));
// Method calls with error handling.
const channel = MethodChannel('foo');
// Invoke a platform method.const name = 'bar'; // or 'baz', or 'unknown' const value = 'world'; try { print(await channel.invokeMethod(name, value)); } on PlatformException catch(e) { print('$name failed: ${e.message}'); } on MissingPluginException { print('$name not implemented'); }
// Receive method invocations from platform and return results. channel.setMethodCallHandler((MethodCall call) async { switch (call.method) { case 'bar': return 'Hello, ${call.arguments}'; case 'baz': throw PlatformException(code: '400', message: 'This is bad'); default: throw MissingPluginException(); } });
val channel = MethodChannel(flutterView, "foo")
// Invoke a Dart method. val name = "bar" // or "baz", or "unknown" val value = "world" channel.invokeMethod(name, value, object: MethodChannel.Result { override fun success(result: Any?) { Log.i("MSG", "$result") } override fun error(code: String?, msg: String?, details: Any?) { Log.e("MSG", "$name failed: $msg") } override fun notImplemented() { Log.e("MSG", "$name not implemented") } })
// Receive method invocations from Dart and return results. channel.setMethodCallHandler { call, result -> when (call.method) { "bar" -> result.success("Hello, ${call.arguments}") "baz" -> result.error("400", "This is bad", null) else -> result.notImplemented() } }
let channel = FlutterMethodChannel( name: "foo", binaryMessenger: flutterView)
// Invoke a Dart method.let name = "bar" // or "baz", or "unknown" let value = "world" channel.invokeMethod(name, arguments: value) { (result: Any?) -> Void in if let error = result as? FlutterError { os_log("%@ failed: %@", type: .error, name, error.message!) } else if FlutterMethodNotImplemented.isEqual(result) { os_log("%@ not implemented", type: .error, name) } else { os_log("%@", type: .info, result as! NSObject) } }
// Receive method invocations from Dart and return results.channel.setMethodCallHandler { (call: FlutterMethodCall, result: FlutterResult) -> Void in switch (call.method) { case "bar": result("Hello, \(call.arguments as! String)") case "baz": result(FlutterError( code: "400", message: "This is bad", details: nil)) default: result(FlutterMethodNotImplemented) }
// Consuming events on the Dart side.
const channel = EventChannel('foo');
channel.receiveBroadcastStream().listen((dynamic event) { print('Received event: $event'); }, onError: (dynamic error) { print('Received error: ${error.message}'); });
// Producing sensor events on Android.
// SensorEventListener/EventChannel adapter.class SensorListener(private val sensorManager: SensorManager) : EventChannel.StreamHandler, SensorEventListener { private var eventSink: EventChannel.EventSink? = null // EventChannel.StreamHandler methods override fun onListen( arguments: Any?, eventSink: EventChannel.EventSink?) { this.eventSink = eventSink registerIfActive() } override fun onCancel(arguments: Any?) { unregisterIfActive() eventSink = null } // SensorEventListener methods. override fun onSensorChanged(event: SensorEvent) { eventSink?.success(event.values) } override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) { if (accuracy == SensorManager.SENSOR_STATUS_ACCURACY_LOW) eventSink?.error("SENSOR", "Low accuracy detected", null) }
// Lifecycle methods. fun registerIfActive() { if (eventSink == null) return sensorManager.registerListener( this, sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL) } fun unregisterIfActive() { if (eventSink == null) return sensorManager.unregisterListener(this) } }
// Use of the above class in an Activity.class MainActivity: FlutterActivity() { var sensorListener: SensorListener? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) GeneratedPluginRegistrant.registerWith(this) sensorListener = SensorListener( getSystemService(Context.SENSOR_SERVICE) as SensorManager) val channel = EventChannel(flutterView, "foo") channel.setStreamHandler(sensorListener) } override fun onPause() { sensorListener?.unregisterIfActive() super.onPause() } override fun onResume() { sensorListener?.registerIfActive() super.onResume() } }
// Dart: we expect to receive a non-null List of integers. for (final int n in await channel.invokeMethod('getFib', 100)) { print(n * n); }
// Android: we expect non-null name and age arguments for // asynchronous processing, delivered in a string-keyed map. channel.setMethodCallHandler { call, result -> when (call.method) { "bar" -> { val name : String = call.argument("name") val age : Int = call.argument("age") process(name, age, result) } else -> result.notImplemented() } } : fun process(name: String, age: Int, result: Result) { ... }
test('gets greeting from platform', () async { const channel = MethodChannel('foo'); channel.setMockMethodCallHandler((MethodCall call) async { if (call.method == 'bar') return 'Hello, ${call.arguments}'; throw MissingPluginException(); }); expect(await hello('world'), 'Platform says: Hello, world'); });
test('collects incoming arguments', () async { const channel = MethodChannel('foo'); final hello = Hello(); final String result = await handleMockCall( channel, MethodCall('bar', 'world'), ); expect(result, contains('Hello, world')); expect(hello.collectedArguments, contains('world')); });
// Could be made an instance method on class MethodChannel. Future<dynamic> handleMockCall( MethodChannel channel, MethodCall call, ) async { dynamic result; await BinaryMessages.handlePlatformMessage( channel.name, channel.codec.encodeMethodCall(call), (ByteData reply) { if (reply == null) throw MissingPluginException(); result = channel.codec.decodeEnvelope(reply); }, ); return result; }