diff --git a/src/CommunityToolkit.Maui.Camera/CameraManager.android.cs b/src/CommunityToolkit.Maui.Camera/CameraManager.android.cs index f3a23aa830..8033f552f2 100644 --- a/src/CommunityToolkit.Maui.Camera/CameraManager.android.cs +++ b/src/CommunityToolkit.Maui.Camera/CameraManager.android.cs @@ -1,5 +1,5 @@ -using System.Runtime.Versioning; -using Android.Content; +using Android.Content; +using Android.Views; using AndroidX.Camera.Core; using AndroidX.Camera.Core.Impl.Utils.Futures; using AndroidX.Camera.Core.ResolutionSelector; @@ -10,6 +10,7 @@ using CommunityToolkit.Maui.Extensions; using Java.Lang; using Java.Util.Concurrent; +using System.Runtime.Versioning; using static Android.Media.Image; using Math = System.Math; @@ -30,6 +31,7 @@ partial class CameraManager Preview? cameraPreview; ResolutionSelector? resolutionSelector; ResolutionFilter? resolutionFilter; + OrientationListener? orientationListener; public void Dispose() { @@ -47,6 +49,8 @@ public NativePlatformCameraPreviewView CreatePlatformView() previewView.SetScaleType(NativePlatformCameraPreviewView.ScaleType.FitCenter); } cameraExecutor = Executors.NewSingleThreadExecutor() ?? throw new CameraException($"Unable to retrieve {nameof(IExecutorService)}"); + orientationListener = new OrientationListener(SetImageCaptureTargetRotation, context); + orientationListener.Enable(); return previewView; } @@ -134,6 +138,10 @@ protected virtual void Dispose(bool disposing) resolutionFilter?.Dispose(); resolutionFilter = null; + + orientationListener?.Disable(); + orientationListener?.Dispose(); + orientationListener = null; } } @@ -251,6 +259,20 @@ protected virtual partial ValueTask PlatformTakePicture(CancellationToken token) return ValueTask.CompletedTask; } + void SetImageCaptureTargetRotation(int rotation) + { + if (imageCapture is not null) + { + imageCapture.TargetRotation = rotation switch + { + >= 45 and < 135 => (int)SurfaceOrientation.Rotation270, + >= 135 and < 225 => (int)SurfaceOrientation.Rotation180, + >= 225 and < 315 => (int)SurfaceOrientation.Rotation90, + _ => (int)SurfaceOrientation.Rotation0 + }; + } + } + sealed class FutureCallback(Action action, Action failure) : Java.Lang.Object, IFutureCallback { public void OnSuccess(Java.Lang.Object? value) @@ -343,4 +365,19 @@ public void OnChanged(Java.Lang.Object? value) observerAction.Invoke(value); } } + + sealed class OrientationListener(Action callback, Context context) : OrientationEventListener(context) + { + readonly Action callback = callback; + + public override void OnOrientationChanged(int orientation) + { + if (orientation == OrientationUnknown) + { + return; + } + + callback.Invoke(orientation); + } + } } \ No newline at end of file