Flutter에서 Kotlin Native와 통신하기 셈플
- Device 정보조회
- 문자열 encoding
- 문자열 decoding
- Native dialog열기
/lib/main.dart
import "package:flutter/material.dart";
import "package:flutter/cupertino.dart";
import "dart:io";
import "package:flutter/services.dart";
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
if (Platform.isIOS) {
return const CupertinoApp(
home: CupertinoNativeApp(title: "Cupertino Native App"),
);
} else {
return MaterialApp(
title: "Native communication",
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const NativeApp(title: "Android Native App"),
);
}
}
}
class CupertinoNativeApp extends StatefulWidget {
final String title;
const CupertinoNativeApp({super.key, required this.title});
@override
State<StatefulWidget> createState() => _NativeApp();
}
class NativeApp extends StatefulWidget {
final String title;
const NativeApp({super.key, required this.title});
@override
State<StatefulWidget> createState() => _NativeApp();
}
class _NativeApp extends State<NativeApp> {
final MethodChannel platform1 = const MethodChannel("com.flutter.dev/info");
final MethodChannel platform2 = const MethodChannel("com.flutter.dev/encrypt");
final MethodChannel platform3 = const MethodChannel("com.flutter.dev/dialog");
String _deviceInfo = "Unknown info.";
String _encodeText = "";
String _decodeText = "";
final TextEditingController _controller = TextEditingController();
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children: <Widget>[
Text(_deviceInfo, style: const TextStyle(fontSize: 20)),
ElevatedButton(
onPressed: () {
_getDeviceInfo();
}, child: const Text("Get Info.")
),
const SizedBox(height: 20),
TextField(
controller: _controller,
keyboardType: TextInputType.text,
),
ElevatedButton(
onPressed: () {
_getEncode(_controller.value.text);
}, child: const Text("Encode")
),
Text(_encodeText, style: const TextStyle(fontSize: 20)),
ElevatedButton(
onPressed: () {
_getDecode(_encodeText);
}, child: const Text("Decode")
),
Text(_decodeText, style: const TextStyle(fontSize: 20)),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
_showDialog();
}, child: const Text("Show Native Dialog Window")
),
],
),
),
);
}
Future<void> _getDeviceInfo() async {
String deviceInfo;
try {
final String result = await platform1.invokeMethod("getDeviceInfo");
deviceInfo = "Device Info. :\n$result";
} on PlatformException catch (e) {
deviceInfo = "Failed to get Device info ${e.message}.";
}
setState(() {
_deviceInfo = deviceInfo;
});
}
Future<void> _getEncode(String text) async {
final String result = await platform2.invokeMethod("getEncode", text);
setState(() {
_encodeText = result;
});
}
Future<void> _getDecode(String text) async {
final String result = await platform2.invokeMethod("getDecode", text);
setState(() {
_decodeText = result;
});
}
Future<void> _showDialog() async {
await platform3.invokeMethod("showDialog");
}
}
/android/app/src/main/kotlin/com/example/native_app/MainActivity.kt
package com.example.native_app
import android.app.AlertDialog
import android.os.Build
import android.util.Base64
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
private val CHANNEL1 = "com.flutter.dev/info"
private val CHANNEL2 = "com.flutter.dev/encrypt"
private val CHANNEL3 = "com.flutter.dev/dialog"
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL1).setMethodCallHandler { call, result ->
if (call.method == "getDeviceInfo") {
val deviceInfo = getDeviceInfo()
result.success(deviceInfo)
}
}
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL2).setMethodCallHandler { call, result ->
if (call.method == "getEncode") {
val data = call.arguments.toString().toByteArray();
val encodeText = Base64.encodeToString(data, Base64.DEFAULT)
result.success(encodeText)
} else if (call.method == "getDecode") {
val data = call.arguments.toString()
val decodeText = Base64.decode(data, Base64.DEFAULT)
result.success(String(decodeText))
}
}
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL3).setMethodCallHandler { call, _ ->
if (call.method == "showDialog") {
AlertDialog.Builder(this).setTitle("Flutter").setMessage("네이티브에서 출력하는 창입니다!").show()
}
}
}
private fun getDeviceInfo(): String {
val sb = StringBuffer()
sb.append(Build.DEVICE + "\n")
sb.append(Build.BRAND + "\n")
sb.append(Build.MODEL + "\n")
sb.append(Build.HARDWARE + "\n")
sb.append(Build.HOST + "\n")
return sb.toString()
}
}