視線を用いるいくつかのMdkTarget、例えば EyeMovementML
, EyePull
, EyeJoyStick
などでは、画面中央をみつめている状態を基準値として、アプリプロセス内で新たに取得する、または以前に取得した基準値を保存してMdkOptionsに渡していないと、うまく動作しない場合があります。この基準点の取得プロセスは、通常のMdkTargetの実装とは別で実装する必要があるため、注意が必要です。
このドキュメントで、その具体的な方法について説明いたします。
基準値を取得するための専用の画面を用意し、その画面にMdkViewを追加するとします。
@Composable
fun CalibrationScreen(
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier.fillMaxSize()
) {
// Add MdkView here
// Additional UI components for calibration can be added here
}
}
MdkTargetの1つであるRegisterCenterReference
を有効なターゲットとして追加します。
private val reference = MdkTarget.RegisterCenterReference // <- Added
@Composable
fun CalibrationScreen(
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier.fillMaxSize()
) {
MdkView( // <- Added
modifier = Modifier.size(100.dp).alpha(0f),
options = MdkOptions.Builder()
.setEnabledMdkTargets(
setOf(
reference,
)
)
.build()
// Additional UI components for calibration can be added here
}
}
このMdkTarget.RegisterCenterReference
ターゲットが有効なMdkViewが動いている状態で、MdkCalibration.registerCenterReference()
関数を呼び出すことで、基準値が登録されます。この関数を呼び出す時は、ユーザーが画面中央を見るように事前にうながす必要があります。
登録された基準値は、アプリのプロセス再起動が行われるとリセットされるのでご注意ください。(保存の仕方は後述)
この関数はsuspend関数で、完了するまで以下の時間の遅延があることを考慮する必要があります。取得完了時にonFinishedコールバックが呼ばれます。
.registerCenterReference()
: 1秒(デフォルト値。引数で変更可能)
Jetpack Composeをお使いの場合、以下のようにLaunchedEffectなどで実行することが多いです。
private val reference = MdkTarget.RegisterCenterReference
@Composable
fun CalibrationScreen(
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier.fillMaxSize()
) {
MdkView(
modifier = Modifier.size(100.dp).alpha(0f),
options = MdkOptions.Builder()
.setEnabledMdkTargets(
setOf(
reference,
)
)
.build()
LaunchedEffect(Unit) { // <- Added
delay(1000L) // <- Adding a delay is recommended
MdkCalibration.registerCenterReference { ref ->
// Do something with registered reference value
println("New reference point saved $ref")
}
}
// Additional UI components for calibration can be added here
}
}
アプリが起動するたびに基準値取得を行うのは大変なので、ローカル上に基準値を保持しておくことをおすすめします。SharedPreferencesを使って保存する実装例を以下に示します。Gsonを使うと簡単に保存できます。
object Preferences(context: Context) {
private lateinit var preferences: SharedPreferences
fun init(context: Context) {
preferences = context.getSharedPreferences("mdk_prefs", Context.MODE_PRIVATE)
}
private val gson = Gson()
// Save CenterReference value
private val CENTER_REFERENCE_LOCAL = "center_reference_local"
var centerReferenceLocal: MdkFaceForReference?
get() {
val json = preferences.getString(CENTER_REFERENCE_LOCAL, null)
return json?.let {
gson.fromJson(it, MdkFaceForReference::class.java)
}
}
set(value) {
preferences.edit {
if (value == null) {
remove(CENTER_REFERENCE_LOCAL)
} else {
putString(CENTER_REFERENCE_LOCAL, gson.toJson(value))
}
}
}
}
保存した基準値は、MdkTargetのOptionsとして渡すことで、その基準値が考慮された挙動になります。
例えば、MdkTarget.EyeMovementML
では、以下のように渡します。
private val movementML = MdkTarget.EyeMovementML
@Composable
fun SampleScreen(
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier.fillMaxSize()
) {
MdkView(
modifier = Modifier.size(100.dp).alpha(0f),
options = MdkOptions.Builder()
.setEnabledMdkTargets(
setOf(
movementML,
)
)
.setActionParams(
movementML,
MdkOptions.MovementMLActionParams(
// Set reference here
centerReference = Preferences.centerReferenceLocal
)
)
.build()
)
// Additional UI components for screen can be added here
}
}