728x90
플러터와 안드로이드간 API통신을 하기 위한 채널을 구현해 봤다
플러터와 안드로이드 플랫폼를 연결하는 채널 구현 요약
1. 플러터에서 MethodChannel 객체를 고유한 채널명으로 만들어 준다
1-1. 안드로이드에서 만들어둔 메서드를 invoke(호출)한다
static const platform = const MethodChannel('atanasio.dev/method'); //채널명은 고유해야 한다
Future<void> getBatteryLevel() async {
try {
final int result = await platform.invokeMethod('getBatteryLevel'); // 안드로이드에서 작성한 메서드 invoke
_batteryInfo = '$result'; // int to String
} on PlatformException catch (e) {
print('error : ${e.message}');
}
}
Future<void> getAndroidVersionName() async {
try {
final String result = await platform.invokeMethod('getAndroidVersion');
_androidVersion = '$result';
} on PlatformException catch (e) {
print('error : ${e.message}');
}
}
Future<void> getAndroidModelName() async {
try {
final String result = await platform.invokeMethod('getAndroidModelName');
_androidModelName = '$result';
} on PlatformException catch (e) {
print('error : ${e.message}');
}
}
2. 안드로이드에서 다음 코드를 준비한다
package ...
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.*
class MainActivity : FlutterActivity() {
private val CHANNEL = "atanasio.dev/method" // 플러터에서 만든 채널명과 일치해야 한다.
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
// 플러터 호출 메서드 분기처리
when (call.method) {
"getBatteryLevel" -> { // 플러터에서 호출한 메서드 * invokeMethod('getBatteryLevel');
val batteryLevel = getBatteryLevel() // 함수 호출
if (batteryLevel != -1) result.success(batteryLevel) // 성공시 플러터로 콜백
else result.error("UNAVAILABLE", "Battery level not available.", null)
}
"getAndroidVersion" -> {
val androidVersionCode = getAndroidVersion()
if (androidVersionCode != null) result.success(androidVersionCode)
else result.error("UNAVAILABLE", "Android Version not available.", null)
}
"getAndroidModelName" -> {
val modelName = getAndroidModelName()
if (modelName != null) result.success(modelName)
else result.error("UNAVAILABLE", "Android deviceName 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
}
// 안드로이드 버전( 엔드유저용 )
private fun getAndroidVersion(): String {
return VERSION.RELEASE
}
// 모델명
private fun getAndroidModelName(): String {
return MODEL
}
}
플러터의 UI 코드 부분은 생략 하였습니다
필요하신분은 댓글로 요청해 주세요
나는 하나의 채널명으로 여러개의 메서드를 만들어 사용했다.
기기 기본정보에 관한 메서드였는데,
네이밍을 "atanasio.dev/androidDeviceInfo" 로 했으면 좋았을 것 같다.
값들이 null로 나와 당황했었는데
플러터에서만 빌드를 해서 그랬던것 같다
안드로이드에서 빌드를 하니 해결되었다
pub.dev에 퍼블링싱 되어 있는 패키지들이
대부분 채널을 이용해서 만들어 진걸 알수 있었다.
느낀점
- pub.dev에 이미 많은 패키지들이 존재한다는걸 알게되었다.
이것들이 채널링을 통해 만들어졌다는걸 알게되었다.
- ndk를 이용하는것도 재밌을것 같다.
- 다음엔 플러터에서 카메라 필터효과 주는걸 구현해 봐야겠다.
'컴퓨터 프로그래밍 > Flutter' 카테고리의 다른 글
[Error] Flutter & Android - path may not be null or empty string. path='null' (0) | 2021.08.12 |
---|---|
[Flutter] 플러터 작업 환경 셋팅 (macOS install) (0) | 2021.07.19 |
[Flutter] 나의 첫 플러터 앱 - 피어레스 플러스 (2) | 2021.07.13 |
[플러터] Stateless vs Stateful 이 따로 존재하는 이유, 차이점 ( feat. Bloc 패턴 ) (0) | 2021.07.10 |
플러터 키보드 화면 올라올때 오버플로우 대응(Flutter. keyboard appears widgets resize) (0) | 2021.07.05 |