[Flutter] Pedometer 라이브러리 까보기2

김영진·2021년 9월 10일
0

Flutter Pedometer

목록 보기
2/3
post-custom-banner

목적

안드로이드 네이티브 코드 분석

내용

pedometer
\
\ㅡㅡPedometerPlugin	// 플러터와 네이티브 코드가 붙는부분으로 추측됨
\ㅡㅡSensorEventListenrFactory.kt	// 안드로이드 센서로부터 직접적으로 데이터를 리슨하는 소스가 있을것으로 예상됨
\ㅡㅡSensorStreamHandler	// 안드로이드 센서로부터 받은데이터를 가공할것으로 추측됨

제일 쉬워보이는

SensorEventListenrFactory.kt

부터 보자

// pedometer로 패키징을 하는 구문이 아닐까 싶다....
package com.example.pedometer

// 센서, 센서이벤트, 센서이벤트리스너, 플러터의 이벤트채널을 임포트해서 사용할것으로 추측됨
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import io.flutter.plugin.common.EventChannel

// 이벤트채널을 파라미터로 받아서 센서이벤트리스너를 리턴하는 함수를 정의.
fun sensorEventListener(events: EventChannel.EventSink): SensorEventListener? {
    return object : SensorEventListener {
// 센서와 정확도를 오버라이딩한 정확한지 체크하는 함수인듯
        override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
// 센서 이벤트를 받아서 센서 이벤트에 걸음수를 리턴해주는 함수
        override fun onSensorChanged(event: SensorEvent) {
            val stepCount = event.values[0].toInt()
            events.success(stepCount)
        }
    }
}

정리하면 그냥 플러터의 이벤트채널을 등록한 이벤트 리스너를 리턴하는 함수.

SensorStreamHandler

package com.example.pedometer

import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.os.Looper
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.EventChannel
import android.os.Handler

// 플러터의 이벤트채널의 스트림핸들러를 상속한 클래스를 구현 
class SensorStreamHandler() : EventChannel.StreamHandler {

    private var sensorEventListener: SensorEventListener? = null
    private var sensorManager: SensorManager? = null
    private var sensor: Sensor? = null
    private lateinit var context: Context
    private lateinit var sensorName: String
    private lateinit var flutterPluginBinding: FlutterPlugin.FlutterPluginBinding

    constructor(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding, sensorType: Int) : this() {
    // 그냥 플러터 쓰면 컨택스트 등록해주는 소스인듯
        this.context = flutterPluginBinding.applicationContext
        // 걸음 수 체크하는 센서일때 "StepCount" a문자열 리턴 아닐땐 "StepDetection" 리턴
        this.sensorName = if (sensorType == Sensor.TYPE_STEP_COUNTER) "StepCount" else "StepDetection"
        // 이것도 늘 하는거인듯
        sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
        // 이것도 늘 하는거인듯
        sensor = sensorManager!!.getDefaultSensor(sensorType)
        // 이것도 늘 하는거인듯
        this.flutterPluginBinding = 
       flutterPluginBinding
    }

// 이벤트를 리슨하는 함수인듯 재정의 해서 사용하네
    override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
    // 센서가 등록 안되면 에러 리턴
        if (sensor == null) {
            events!!.error("1", "$sensorName not available",
                    "$sensorName is not available on this device");
        } else {
        // 센서 이벤트 리스너에 이벤트채널 리스너 설정
            sensorEventListener = sensorEventListener(events!!);
           // 센서매니저에 이벤트리스너, 센서, 센서매니저, 샌서 속성 세개 넣어서 할당
           sensorManager!!.registerListener(sensorEventListener,
                    sensor, SensorManager.SENSOR_DELAY_FASTEST);
        }
    }

// 센서매니저를 할당 해제하는 함수
    override fun onCancel(arguments: Any?) {
        sensorManager!!.unregisterListener(sensorEventListener);
    }

}

정리하면 생성자로 센서매니저 선언하고
onListen 매소드 실행하면 연결하고
onCancel 메소드 실행하면 연결 끊고 하는 객체 만듬

package com.example.pedometer

import android.hardware.Sensor
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.EventChannel

/** PedometerPlugin */
class PedometerPlugin : FlutterPlugin {
    private lateinit var stepDetectionChannel: EventChannel
    private lateinit var stepCountChannel: EventChannel

// 플러터랑 네이티브를 붙이는 부분
    override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    // 채널 생성
        /// Create channels
        stepDetectionChannel = EventChannel(flutterPluginBinding.binaryMessenger, "step_detection")
        stepCountChannel = EventChannel(flutterPluginBinding.binaryMessenger, "step_count")

// 핸들러 만들고
        /// Create handlers
        val stepDetectionHandler = SensorStreamHandler(flutterPluginBinding, Sensor.TYPE_STEP_DETECTOR)
        val stepCountHandler = SensorStreamHandler(flutterPluginBinding, Sensor.TYPE_STEP_COUNTER)

// 핸들러를 채널과 연결한다.
        /// Set handlers
        stepDetectionChannel.setStreamHandler(stepDetectionHandler)
        stepCountChannel.setStreamHandler(stepCountHandler)
    }

// 플러터랑 네이티브를 때는 부분
    override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
        stepDetectionChannel.setStreamHandler(null)
        stepCountChannel.setStreamHandler(null)
    }

}

핸들러 가져와서 플러터랑 붙이는 소스임.

결론

왜 걸음수가 늦게 반영되고 하루치보다 엄청 많은 양의 걸음수가 나오는지 아직 모르겠다.. 흠 그냥 센서가 이상한건가?
좀 찾아봐야겠네
TYPE_STEP_COUNTER

profile
2021.05.03) Flutter, BlockChain, Sports, StartUp
post-custom-banner

0개의 댓글