플랫폼 통합
(Platform integration)
https://docs.flutter.dev/platform-integration/platform-channels?tab=type-mappings-kotlin
플랫폼 채널의 통신참여 주체를 두 개로 나눌 수 있다
플러터 앱은 네이티브 호스트와 비동기 메시지를 주고받는다.
그리고 그런 메시지 교환을 지원하기 위한 클래스도 이미 플러터에 구현되어있다.
MethodChannel
MethodChannel
, MethodChannelAndroid
FlutterMethodChannel
, MethodChanneliOS
State위젯에서 메소드 채널 인스턴스를 만든다.
채널 이름은 앱 내에서 고유하면 되는데, 도메인/진짜이름
으로 정할 수 있음
만들어진 메소드 채널에 대해 호출하고자 하는 메소드를 지정
(원한다면) UI에 보여주기
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
...
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
// 1.
static const platform = MethodChannel('samples.flutter.dev/battery');
int _batteryLevel = -1;
Future<void> _getBatteryLevel() async {
int batteryLevel;
try {
// 2.
final result = await platform.invokeMethod<int>('getBatteryLevel');
batteryLevel = result ?? -1;
} on PlatformException catch (e) {
batteryLevel = -1;
}
setState(() {
_batteryLevel = batteryLevel;
});
}
Widget build(BuildContext context) {
return Material(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: _getBatteryLevel,
child: const Text('Get Battery Level'),
),
// 3.
Text('$_batteryLevel'),
],
),
),
);
}
}
프로젝트명/android/app/src/main/kotlin/com/example/batterylevel/MainActivity.kt
에 작업
코드 작성을 vscode에서 해도 되는데 안드로이드 스튜디오에서 하는게 정신건강에 좋아보였다. (vscode에 코틀린 공식 익스텐션이 없는듯)
실행은 원래 하던대로 본인 에디터(vs code 등)에서 해도 된다.
안드로이드 스튜디오 - File - Open - 플러터 프로젝트의 android폴더 선택
코드는 아래와 같다. 요약하면 이런듯
MethodChannel(대충 플러터 내장 뭐, 채널 이름).setMethodCallHandler
if (call.method == "getBatteryLevel")
result.success(응답할 값)
result.error("에러코드", "에러메세지", 에러 디테일)
package com.뭐시기.패키지이름
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
class MainActivity: FlutterActivity() {
private val CHANNEL = "samples.flutter.dev/battery"
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
call, result ->
if (call.method == "getBatteryLevel") {
val batteryLevel = getBatteryLevel()
if (batteryLevel != -1) {
result.success(batteryLevel)
} else {
result.error("UNAVAILABLE", "Battery level not available.", null)
}
} else {
result.notImplemented()
}
}
}
private fun getBatteryLevel(): Int {
val batteryLevel: Int
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
} else {
val intent = ContextWrapper(applicationContext).registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
batteryLevel = intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
}
return batteryLevel
}
}
맥북이 없어서 아직 못해봤다.
아무튼 프로젝트 이름/ios/Runner/AppDelegate.swift
에 코드 작성
공식문서는 대충 이렇게 쓴다. 안드로이드랑 별 다를게 없어보인다.
** 주의 : iOS 시뮬레이터는 배터리 API지원 안한다.
let batteryChannel = FlutterMethodChannel(name: "samples.flutter.dev/battery",
binaryMessenger: controller.binaryMessenger)
batteryChannel.setMethodCallHandler({
[weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in
guard call.method == "getBatteryLevel" else {
result(FlutterMethodNotImplemented)
return
}
self?.receiveBatteryLevel(result: result)
})
})
https://pub.dev/packages/pigeon
MethodChannel
대신 Pigeon 패키지 사용할 수 있음.
타입안전도 얻고, 구조적으로 메시지를 보낼 수 있다.
코드생성기임. (마치 이전에 본 json_serializable 처럼)
flutter pub get
flutter pub run pigeon
Automatic platform adaptations.
플랫폼 적응성에 고려되는 동작은 두 가지로 나눌 수 있음
OS동작에 해당해서 플러터가 알잘딱 플랫폼적응 해주는 것들을 나열한다.
영상이랑 그림, 기본설정 바꾸는 방법까지 있으니까 밑에 가서 보는게 빠르다. 요약할게 딱히 없다.
https://docs.flutter.dev/platform-integration/platform-adaptations