adaptive_dual_camera
Hands-free front + back photo capture with location and timestamp — native simultaneous capture where the hardware allows it, sequential everywhere else, and the same composed layout either way.
What this package is like to depend on
Last release 7 days ago
17 Aug 2026
Too new to tell
only 2 release windows
Nearly every release is documented
notes for 5 of 5 stable releases
Nothing withdrawn
no release was ever pulled
0 months old
5 releases · first in 2026
5 releases in the last 12 months
see the full history below
Release timeline
5 releases · Jul 2026 to Aug 2026Releases
latest 5-
0.8.017 Aug 2026Release notes
Open source →- The capture flow now composes the layout itself:
result.composedPhoto. PreviouslyonCompletehanded back two raw photos, so an app that saved or uploaded what it was given shipped the back camera's shot alone — the selfie, map and timestamp only existed if the caller went on to mountDualShotViewor callcomposeDualShotitself. The flow now renders the finished layout before it completes and puts the PNG on the result. Passcompose: DualShotStyle.light(or any style) to restyle it, orcompose: nullfor the old behaviour — the two raw photos are still on the result either way, and a failed compose leavescomposedPhotonull rather than losing the capture. - New
DualCaptureLabels.composingfor the extra beat this adds to the finishing screen. - Corrected docs that predated 0.5.0: the library doc and the
pubspec.yamlplugin comment still said all capture was pure Dart and the only native code was a capability probe (the simultaneous path has been a native session since 0.5.0). The example README still described a shutter-less flow (0.6.0 added the tap to start) and a language toggle the example doesn't have; the result-layout docs now say which field holds the composed image.
- The capture flow now composes the layout itself:
-
0.6.010 Aug 2026Release notes
Open source →- Camera permission is now actually requested on the simultaneous path.
The native session binds the cameras directly, so nothing ever showed the
OS camera dialog — and the location request fired in parallel cancelled
the
cameraplugin's request on the fallback path too, so users only ever saw the location popup. The plugin now requestsCAMERAitself before starting the native session (Android and iOS), and the location request waits until a camera is live so the two dialogs never collide. A denial shows the existing retry screen. - No more stale location on captures. The
getLastKnownPositionfallback is gone: it could stamp a shot with a fix from hours ago (or the emulator's default). A capture now carries a real current fix or a nulllatitude/longitude, never a guess. - The first viewfinder now waits for a shutter tap. Opening straight
into a countdown photographed people before they were ready. The first
page (the only page in simultaneous mode, the selfie page in sequential)
shows a classic shutter button and a
DualCaptureLabels.tapToStarthint; everything after the tap is automatic as before — the back page still counts down on its own, since the user's hands are busy turning the phone. - Smoother viewfinder on old devices. Countdown ticks now repaint only
the ring (a
ValueNotifierinstead of whole-pagesetState), and each live preview sits behind its ownRepaintBoundaryso overlay repaints never touch the camera layers. The composed view's back photo usesgaplessPlayback, so restyling never flashes an empty frame. - The example app no longer ships a language switcher — every string was
already the developer's to supply via
DualCaptureLabels; pass your own to reword or translate. - Simultaneous support is no longer under-reported. The Android probe
used to require a front+back combination in
CameraManager.getConcurrentCameraIds(), which is empty on plenty of hardware (and the emulator) that streams front+back just fine — soautosaid "this device can't" on devices that could. The probe now checks exactly what CameraX's concurrentbindToLifecyclechecks:FEATURE_CAMERA_CONCURRENT. The same wrong gate inside the native session (availableConcurrentCameraInfos) is gone too; actually binding the cameras remains the final arbiter, so overclaiming devices still fall back cleanly. - The back photo is no longer cropped by the layout.
DualShotViewused to cover-fit the photo into whatever box its parent gave it, which shaved the top and bottom off every shot whose aspect didn't match — read as "the footer cut off the bottom of my photo". The card now takes its shape from the photo itself (full photo, footer below) and scales down as a whole when the parent is shorter. NewDualShotView.boundaryKeyputs thesaveComposedDualShotboundary on the card itself so the saved PNG has no empty margins; wrapping the view in your ownRepaintBoundarystill works. - Simultaneous previews are laid out at the size the native side actually
reports instead of an assumed 1080×1440, fixing stretched/cropped
previews on devices with other preview resolutions (the sizes were
already sent, then ignored — and on Android they were also racy, now read
post-bind from
resolutionInfo). - A simultaneous start that times out now tells the native side to stand down instead of letting it finish binding both cameras with nobody listening.
- Failures on the simultaneous path are
debugPrinted instead of swallowed silently, so "why did it fall back?" is answerable from logs.
- Camera permission is now actually requested on the simultaneous path.
The native session binds the cameras directly, so nothing ever showed the
OS camera dialog — and the location request fired in parallel cancelled
the
-
0.0.330 Jul 2026Release notes
Open source →- Fix
initialize()throwingCan't create handler inside thread … Looper.prepare()on Android: Flutter's texture registry must be used from the platform main thread, and the plugin was calling it from its worker. Texture create/release now hop to the main thread; an integration test covers the full initialize → preview → dispose cycle on a device.
- Fix
-
0.0.230 Jul 2026Release notes
Open source →- Low-RAM (Android Go) devices always take the sequential path and cap stills at ~8MP, so a second camera pipeline never competes for memory.
-
0.0.130 Jul 2026Release notes
Open source →DualCameraController— live front/back preview textures,capturePhoto()andstartRecording()/stopRecording().- Simultaneous capture via Android concurrent cameras (API 30+) and iOS
AVCaptureMultiCamSession(A12+), falling back to one camera at a time everywhere else. Sequential video records the back clip, then re-records the front for the same duration. stagereports which camera a sequential capture is on, so apps can say "Taking back photo…" / "Taking front photo…".DualLayoutStyle— one object holding every visual knob, shared byDualLayoutView,DualCameraPreviewandDualCaptureViewso a viewfinder and its result are configured identically. Picture-in-picture, side-by-side, stacked and primary-only arrangements, or abuilderfor anything else.- Feeds and photos default to
BoxFit.contain, so the whole frame is visible rather than cropped, withbackgroundfilling the letterbox. DualCameraLabels— every user-facing string with English defaults and astatusFor(controller)that picks the right one, for wording and localisation.DualStorage— captures land in the cache directory by default; set adirectoryand/ornameBuilderto have them filed automatically.AdaptiveDualCamera.capture()/.record()for one-shot use without a preview.