Skip to content

Commit 9233b73

Browse files
[Android] Sync ImageCapture Use Case w/ Display Rotation (#2523)
* sync display rotation w/ use case * callback approach --------- Co-authored-by: James Crutchley <ne0rmatrix@gmail.com>
1 parent 0a4dd43 commit 9233b73

File tree

1 file changed

+39
-2
lines changed

1 file changed

+39
-2
lines changed

src/CommunityToolkit.Maui.Camera/CameraManager.android.cs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using System.Runtime.Versioning;
2-
using Android.Content;
1+
using Android.Content;
2+
using Android.Views;
33
using AndroidX.Camera.Core;
44
using AndroidX.Camera.Core.Impl.Utils.Futures;
55
using AndroidX.Camera.Core.ResolutionSelector;
@@ -10,6 +10,7 @@
1010
using CommunityToolkit.Maui.Extensions;
1111
using Java.Lang;
1212
using Java.Util.Concurrent;
13+
using System.Runtime.Versioning;
1314
using static Android.Media.Image;
1415
using Math = System.Math;
1516

@@ -30,6 +31,7 @@ partial class CameraManager
3031
Preview? cameraPreview;
3132
ResolutionSelector? resolutionSelector;
3233
ResolutionFilter? resolutionFilter;
34+
OrientationListener? orientationListener;
3335

3436
public void Dispose()
3537
{
@@ -47,6 +49,8 @@ public NativePlatformCameraPreviewView CreatePlatformView()
4749
previewView.SetScaleType(NativePlatformCameraPreviewView.ScaleType.FitCenter);
4850
}
4951
cameraExecutor = Executors.NewSingleThreadExecutor() ?? throw new CameraException($"Unable to retrieve {nameof(IExecutorService)}");
52+
orientationListener = new OrientationListener(SetImageCaptureTargetRotation, context);
53+
orientationListener.Enable();
5054

5155
return previewView;
5256
}
@@ -134,6 +138,10 @@ protected virtual void Dispose(bool disposing)
134138

135139
resolutionFilter?.Dispose();
136140
resolutionFilter = null;
141+
142+
orientationListener?.Disable();
143+
orientationListener?.Dispose();
144+
orientationListener = null;
137145
}
138146
}
139147

@@ -251,6 +259,20 @@ protected virtual partial ValueTask PlatformTakePicture(CancellationToken token)
251259
return ValueTask.CompletedTask;
252260
}
253261

262+
void SetImageCaptureTargetRotation(int rotation)
263+
{
264+
if (imageCapture is not null)
265+
{
266+
imageCapture.TargetRotation = rotation switch
267+
{
268+
>= 45 and < 135 => (int)SurfaceOrientation.Rotation270,
269+
>= 135 and < 225 => (int)SurfaceOrientation.Rotation180,
270+
>= 225 and < 315 => (int)SurfaceOrientation.Rotation90,
271+
_ => (int)SurfaceOrientation.Rotation0
272+
};
273+
}
274+
}
275+
254276
sealed class FutureCallback(Action<Java.Lang.Object?> action, Action<Throwable?> failure) : Java.Lang.Object, IFutureCallback
255277
{
256278
public void OnSuccess(Java.Lang.Object? value)
@@ -343,4 +365,19 @@ public void OnChanged(Java.Lang.Object? value)
343365
observerAction.Invoke(value);
344366
}
345367
}
368+
369+
sealed class OrientationListener(Action<int> callback, Context context) : OrientationEventListener(context)
370+
{
371+
readonly Action<int> callback = callback;
372+
373+
public override void OnOrientationChanged(int orientation)
374+
{
375+
if (orientation == OrientationUnknown)
376+
{
377+
return;
378+
}
379+
380+
callback.Invoke(orientation);
381+
}
382+
}
346383
}

0 commit comments

Comments
 (0)