mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2025-06-12 18:30:40 +00:00
[android] calculate EFL
This commit is contained in:
parent
383fbab7d9
commit
56ac6fe558
4 changed files with 85 additions and 1 deletions
|
@ -4,6 +4,7 @@ import android.os.Bundle
|
|||
import android.view.KeyEvent
|
||||
import android.view.WindowManager
|
||||
import androidx.core.view.WindowCompat
|
||||
import com.vodemn.lightmeter.PlatformChannels.CameraInfoPlatformChannel
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.plugin.common.EventChannel
|
||||
|
@ -17,6 +18,8 @@ class MainActivity : FlutterActivity() {
|
|||
private var volumeEventsEmitter: EventSink? = null
|
||||
private var handleVolume = false
|
||||
|
||||
private val cameraInfoPlatformChannel = CameraInfoPlatformChannel()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
|
@ -24,6 +27,8 @@ class MainActivity : FlutterActivity() {
|
|||
|
||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine)
|
||||
cameraInfoPlatformChannel.onAttachedToEngine(flutterEngine.dartExecutor.binaryMessenger, context)
|
||||
|
||||
keepScreenOnChannel = MethodChannel(
|
||||
flutterEngine.dartExecutor.binaryMessenger,
|
||||
"com.vodemn.lightmeter/keepScreenOn"
|
||||
|
@ -76,6 +81,7 @@ class MainActivity : FlutterActivity() {
|
|||
keepScreenOnChannel.setMethodCallHandler(null)
|
||||
volumeHandlingChannel.setMethodCallHandler(null)
|
||||
volumeEventChannel.setStreamHandler(null)
|
||||
cameraInfoPlatformChannel.onDestroy()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package com.vodemn.lightmeter.PlatformChannels
|
||||
|
||||
import android.content.Context
|
||||
import android.hardware.camera2.CameraCharacteristics
|
||||
import android.hardware.camera2.CameraManager
|
||||
import android.hardware.camera2.CameraMetadata.LENS_FACING_BACK
|
||||
import io.flutter.plugin.common.BinaryMessenger
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.sqrt
|
||||
|
||||
/** CameraInfoPlatformChannel */
|
||||
class CameraInfoPlatformChannel : MethodChannel.MethodCallHandler {
|
||||
private lateinit var channel: MethodChannel
|
||||
private lateinit var cameraManager: CameraManager
|
||||
private var mainCameraEfl: Double? = null
|
||||
|
||||
fun onAttachedToEngine(binaryMessenger: BinaryMessenger, context: Context) {
|
||||
channel = MethodChannel(binaryMessenger, "com.vodemn.lightmeter.CameraInfoPlatformChannel")
|
||||
cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
||||
channel.setMethodCallHandler(this)
|
||||
}
|
||||
|
||||
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
|
||||
when (call.method) {
|
||||
"mainCameraEfl" -> {
|
||||
mainCameraEfl = mainCameraEfl ?: getMainCameraFocalLength35mm()
|
||||
result.success(mainCameraEfl)
|
||||
}
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
channel.setMethodCallHandler(null)
|
||||
}
|
||||
|
||||
private fun getMainCameraFocalLength35mm(): Double? {
|
||||
return cameraManager.cameraIdList.map {
|
||||
cameraManager.getCameraCharacteristics(it)
|
||||
}.first {
|
||||
it.get(CameraCharacteristics.LENS_FACING) == LENS_FACING_BACK
|
||||
}.focalLength35mm()
|
||||
}
|
||||
|
||||
private fun CameraCharacteristics.focalLength35mm(): Double? {
|
||||
val defaultFocalLength = get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)?.first()
|
||||
val sensorSize = get(CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE)
|
||||
return if (defaultFocalLength != null && sensorSize != null) {
|
||||
// https://en.wikipedia.org/wiki/35_mm_equivalent_focal_length#Conversions
|
||||
43.27 * defaultFocalLength / sqrt(sensorSize.height.pow(2) + sensorSize.width.pow(2))
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import 'package:flutter_native_splash/flutter_native_splash.dart';
|
|||
import 'package:lightmeter/data/analytics/analytics.dart';
|
||||
import 'package:lightmeter/data/analytics/api/analytics_firebase.dart';
|
||||
import 'package:lightmeter/data/caffeine_service.dart';
|
||||
import 'package:lightmeter/data/camera_info_service.dart';
|
||||
import 'package:lightmeter/data/haptics_service.dart';
|
||||
import 'package:lightmeter/data/light_sensor_service.dart';
|
||||
import 'package:lightmeter/data/permissions_service.dart';
|
||||
|
@ -99,11 +100,13 @@ class _ApplicationWrapperState extends State<ApplicationWrapper> {
|
|||
await Future.wait([
|
||||
SharedPreferences.getInstance(),
|
||||
const LightSensorService(LocalPlatform()).hasSensor(),
|
||||
const CameraInfoService().mainCameraEfl(),
|
||||
remoteConfigService.activeAndFetchFeatures(),
|
||||
equipmentProfilesStorageService.init(),
|
||||
filmsStorageService.init(),
|
||||
]).then((value) {
|
||||
userPreferencesService = UserPreferencesService((value[0] as SharedPreferences?)!);
|
||||
userPreferencesService = UserPreferencesService((value[0] as SharedPreferences?)!)
|
||||
..cameraFocalLength = value[2] as int?;
|
||||
hasLightSensor = value[1] as bool? ?? false;
|
||||
});
|
||||
}
|
||||
|
|
18
lib/data/camera_info_service.dart
Normal file
18
lib/data/camera_info_service.dart
Normal file
|
@ -0,0 +1,18 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class CameraInfoService {
|
||||
@visibleForTesting
|
||||
static const cameraInfoPlatformChannel = MethodChannel("com.vodemn.lightmeter.CameraInfoPlatformChannel");
|
||||
|
||||
const CameraInfoService();
|
||||
|
||||
Future<int?> mainCameraEfl() async {
|
||||
if (Platform.isIOS) {
|
||||
return null;
|
||||
}
|
||||
return (await cameraInfoPlatformChannel.invokeMethod<double?>('mainCameraEfl'))?.round();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue