Notable changes in version 91:
Crash fixes
- Video recording no longer crashes when a recording is started and immediately stopped or when the activity is stopped mid-recording. Instead, the recording is now ended before the camera is unbound.
- Recordings are muxed with the platform muxer instead of the media3 muxer, which was silently dropping the audio track.
- Recordings that failed before writing a single byte are discarded instead of leaving a zero-byte file, and pending recordings left behind by a killed process are cleaned up on next launch.
- An out-of-range photo quality value is now rejected at entry instead of crashing the next camera bind.
- Sharing or editing a capture that is no longer accessible shows a message instead of crashing.
- The video player closes cleanly when the media service dies instead of crashing.
- The capture button no longer crashes on devices where the drawable is wrapped rather than the exact type the code cast to.
- Non-numeric input in settings no longer prints a stack trace.
Privacy and permissions
- The app no longer requests location permission unless the user has actually enabled location tagging.
- The last capture can no longer be shared out of a secure (lockscreen) camera session.
- Storage location grants the app has stopped tracking are now released instead of being held indefinitely.
ACCESS_NETWORK_STATE, pulled in transitively by media3 through CameraX's video module, is stripped from the merged manifest. The app never used this and has noINTERNETpermission to pair it with.
Camera and capture
- Switching away from video mode is refused while a recording is running.
- The gap between pressing record and the recording actually starting is now handled, so rapid taps behave predictably.
- The self-timer duration is remembered between sessions and its badge stays accurate; the capture button starts the timer rather than firing the shutter directly.
- Camera extension availability is probed once and the verdict kept for the life of the process, instead of being re-probed on every bind.
- Zoom updates read a cached zoom state rather than querying the camera on every step.
- The mode tab strip stays in sync with the actual camera mode, ignores stale scroll positions, and only changes mode while it is genuinely being dragged.
- The level indicator is left alone in QR scan mode, and the barcode toggle message names the format it switched to.
- Screen brightness is handed back to the system when front-camera self-illumination ends.
- Only request location for geotagging from the fused provider when using it is enabled
- Overhaul fallback geotagging implementation used on most platforms by always choosing the most accurate recent location from the available providers
- Stop location apps for geotagging when the activity is paused
- Stop attaching overly stale locations to captures for geotagging when not recent location is available
Gallery
- Gallery actions stay hidden until the media they act on has loaded.
- The details sheet now shows resolution and duration.
- Capture timestamps fall back to the stored value when Exif has been stripped.
Accessibility
- Camera, settings, and on-screen controls are labelled for screen readers, with descriptions kept in sync with the icons they carry.
- Gallery slides announce what they contain.
Settings
- Settings are persisted on every exit path from the menu.
- Back closes the settings panel instead of sending the camera away.
- Tapping the photo quality row opens the keyboard.
- The focus timeout "Off" option is recognized correctly.
- The never-enabled file name format settings were removed.
Testing
- Added over a dozen new instrumented regression suites covering video capture, self-timer, mode tabs, photo quality, in-app gallery, share, edit, SAF tree grants, captured items, the settings dialog, and the video player, plus shared wake/wait/recording helpers.
Dependency updates
- Android Gradle Plugin version 9.3.1
- Kotlin version 2.4.10
- Gradle version 9.6.1
- CameraX version 1.6.1
- update forked CameraX Exif class to 1.6.1
- update forked AndroidX ExifInterface classes to 1.4.2
- Material Components version 1.14.0
- AndroidX Core KTX version 1.19.0
- AndroidX Constraint Layout version 2.2.2
- ZXing version 3.5.4
- Android SDK version 37
- Android build tools version 37.0.0
- Android NDK version 29.0.14206865
A full list of changes from the previous release (version 90) is available through the Git commit log between the releases.
This app is available through the Play Store with the app.grapheneos.camera.play app id. Play Store releases go through review and it usually takes around 1 to 2 days before the Play Store pushes out the update to users. Play Store releases use Play Signing, so we use a separate app id from the releases we publish ourselves to avoid conflicts and to distinguish between them. Each release is initially pushed out through the Beta channel followed by the Stable channel.
Releases of the app signed by GrapheneOS with the app.grapheneos.camera app id are published in the GrapheneOS App Store which provides fully automatic updates. Each release is initially pushed out through the Alpha channel, followed by the Beta channel and then finally the Stable channel. These releases are also bundled as part of GrapheneOS and published on GitHub.
GrapheneOS users must obtain GrapheneOS app updates through our App Store since verified boot metadata is required for out-of-band system app updates on GrapheneOS as part of extending verified boot to them.