mirror of
https://github.com/SimpleMobileTools/Simple-Camera.git
synced 2025-04-01 01:10:13 +02:00
Merge pull request #330 from KryptKode/feat/camera-x
Updates/Fixes for CameraX implementation
This commit is contained in:
commit
91bc6ccf60
@ -63,13 +63,13 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:d1d5402388'
|
||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:7c48da6bef'
|
||||
implementation 'androidx.documentfile:documentfile:1.0.1'
|
||||
implementation "androidx.exifinterface:exifinterface:1.3.3"
|
||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.1"
|
||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.0"
|
||||
implementation 'androidx.window:window:1.1.0-alpha02'
|
||||
|
||||
def camerax_version = '1.1.0-rc02'
|
||||
def camerax_version = '1.1.0'
|
||||
implementation "androidx.camera:camera-core:$camerax_version"
|
||||
implementation "androidx.camera:camera-camera2:$camerax_version"
|
||||
implementation "androidx.camera:camera-video:$camerax_version"
|
||||
|
@ -10,10 +10,11 @@ import com.simplemobiletools.commons.dialogs.FilePickerDialog
|
||||
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.LICENSE_GLIDE
|
||||
import com.simplemobiletools.commons.helpers.NavigationIcon
|
||||
import com.simplemobiletools.commons.models.FAQItem
|
||||
import com.simplemobiletools.commons.models.RadioItem
|
||||
import java.util.Locale
|
||||
import kotlinx.android.synthetic.main.activity_settings.*
|
||||
import java.util.*
|
||||
|
||||
class SettingsActivity : SimpleActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -23,7 +24,7 @@ class SettingsActivity : SimpleActivity() {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
setupToolbar(settings_toolbar, NavigationIcon.Arrow)
|
||||
setupPurchaseThankYou()
|
||||
setupCustomizeColors()
|
||||
setupUseEnglish()
|
||||
|
@ -8,13 +8,19 @@ import com.simplemobiletools.camera.activities.SimpleActivity
|
||||
import com.simplemobiletools.camera.extensions.config
|
||||
import com.simplemobiletools.camera.models.MySize
|
||||
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
||||
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
|
||||
import com.simplemobiletools.commons.extensions.setupDialogStuff
|
||||
import com.simplemobiletools.commons.models.RadioItem
|
||||
import kotlinx.android.synthetic.main.dialog_change_resolution.view.*
|
||||
import kotlinx.android.synthetic.main.dialog_change_resolution.view.change_resolution_photo
|
||||
import kotlinx.android.synthetic.main.dialog_change_resolution.view.change_resolution_photo_holder
|
||||
import kotlinx.android.synthetic.main.dialog_change_resolution.view.change_resolution_video
|
||||
import kotlinx.android.synthetic.main.dialog_change_resolution.view.change_resolution_video_holder
|
||||
|
||||
class ChangeResolutionDialog(val activity: SimpleActivity, val isFrontCamera: Boolean, val photoResolutions: ArrayList<MySize>,
|
||||
val videoResolutions: ArrayList<MySize>, val openVideoResolutions: Boolean, val callback: () -> Unit) {
|
||||
private var dialog: AlertDialog
|
||||
class ChangeResolutionDialog(
|
||||
val activity: SimpleActivity, val isFrontCamera: Boolean, val photoResolutions: ArrayList<MySize>,
|
||||
val videoResolutions: ArrayList<MySize>, val openVideoResolutions: Boolean, val callback: () -> Unit
|
||||
) {
|
||||
private var dialog: AlertDialog? = null
|
||||
private val config = activity.config
|
||||
|
||||
init {
|
||||
@ -23,16 +29,18 @@ class ChangeResolutionDialog(val activity: SimpleActivity, val isFrontCamera: Bo
|
||||
setupVideoResolutionPicker(this)
|
||||
}
|
||||
|
||||
dialog = AlertDialog.Builder(activity)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.setOnDismissListener { callback() }
|
||||
.create().apply {
|
||||
activity.setupDialogStuff(view, this, if (isFrontCamera) R.string.front_camera else R.string.back_camera) {
|
||||
if (openVideoResolutions) {
|
||||
view.change_resolution_video_holder.performClick()
|
||||
}
|
||||
activity.getAlertDialogBuilder()
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.setOnDismissListener { callback() }
|
||||
.apply {
|
||||
val titleId = if (isFrontCamera) R.string.front_camera else R.string.back_camera
|
||||
activity.setupDialogStuff(view, this, titleId) { alertDialog ->
|
||||
dialog = alertDialog
|
||||
if (openVideoResolutions) {
|
||||
view.change_resolution_video_holder.performClick()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupPhotoResolutionPicker(view: View) {
|
||||
@ -49,7 +57,7 @@ class ChangeResolutionDialog(val activity: SimpleActivity, val isFrontCamera: Bo
|
||||
} else {
|
||||
config.backPhotoResIndex = it
|
||||
}
|
||||
dialog.dismiss()
|
||||
dialog?.dismiss()
|
||||
}
|
||||
}
|
||||
view.change_resolution_photo.text = items.getOrNull(selectionIndex)?.title
|
||||
@ -68,7 +76,7 @@ class ChangeResolutionDialog(val activity: SimpleActivity, val isFrontCamera: Bo
|
||||
} else {
|
||||
config.backVideoResIndex = it
|
||||
}
|
||||
dialog.dismiss()
|
||||
dialog?.dismiss()
|
||||
}
|
||||
}
|
||||
view.change_resolution_video.text = items.getOrNull(selectionIndex)?.title
|
||||
|
@ -10,6 +10,7 @@ import com.simplemobiletools.camera.extensions.config
|
||||
import com.simplemobiletools.camera.models.MySize
|
||||
import com.simplemobiletools.camera.models.VideoQuality
|
||||
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
||||
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
|
||||
import com.simplemobiletools.commons.extensions.setupDialogStuff
|
||||
import com.simplemobiletools.commons.models.RadioItem
|
||||
import kotlinx.android.synthetic.main.dialog_change_resolution.view.change_resolution_photo
|
||||
@ -22,9 +23,9 @@ class ChangeResolutionDialogX(
|
||||
private val isFrontCamera: Boolean,
|
||||
private val photoResolutions: List<MySize> = listOf(),
|
||||
private val videoResolutions: List<VideoQuality>,
|
||||
private val callback: () -> Unit
|
||||
private val callback: () -> Unit,
|
||||
) {
|
||||
private var dialog: AlertDialog
|
||||
private var dialog: AlertDialog? = null
|
||||
private val config = activity.config
|
||||
|
||||
private val TAG = "ChangeResolutionDialogX"
|
||||
@ -34,20 +35,27 @@ class ChangeResolutionDialogX(
|
||||
setupVideoResolutionPicker(this)
|
||||
}
|
||||
|
||||
dialog = AlertDialog.Builder(activity)
|
||||
activity.getAlertDialogBuilder()
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.create().apply {
|
||||
activity.setupDialogStuff(view, this, if (isFrontCamera) R.string.front_camera else R.string.back_camera)
|
||||
.apply {
|
||||
val titleId = if (isFrontCamera) R.string.front_camera else R.string.back_camera
|
||||
activity.setupDialogStuff(view, this, titleId) { alertDialog ->
|
||||
dialog = alertDialog
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupPhotoResolutionPicker(view: View) {
|
||||
val items = getFormattedResolutions(photoResolutions)
|
||||
val items = photoResolutions.mapIndexed { index, resolution ->
|
||||
val megapixels = resolution.megaPixels
|
||||
val aspectRatio = resolution.getAspectRatio(activity)
|
||||
RadioItem(index, "${resolution.width} x ${resolution.height} ($megapixels MP, $aspectRatio)")
|
||||
}
|
||||
var selectionIndex = if (isFrontCamera) config.frontPhotoResIndex else config.backPhotoResIndex
|
||||
selectionIndex = Math.max(selectionIndex, 0)
|
||||
selectionIndex = selectionIndex.coerceAtLeast(0)
|
||||
|
||||
view.change_resolution_photo_holder.setOnClickListener {
|
||||
RadioGroupDialog(activity, items, selectionIndex) {
|
||||
RadioGroupDialog(activity, ArrayList(items), selectionIndex) {
|
||||
selectionIndex = it as Int
|
||||
Log.w(TAG, "setupPhotoResolutionPicker: selectionIndex=$it")
|
||||
view.change_resolution_photo.text = items[selectionIndex].title
|
||||
@ -56,7 +64,7 @@ class ChangeResolutionDialogX(
|
||||
} else {
|
||||
config.backPhotoResIndex = it
|
||||
}
|
||||
dialog.dismiss()
|
||||
dialog?.dismiss()
|
||||
callback.invoke()
|
||||
}
|
||||
}
|
||||
@ -70,35 +78,27 @@ class ChangeResolutionDialogX(
|
||||
RadioItem(index, "${videoQuality.width} x ${videoQuality.height} ($megapixels MP, $aspectRatio)")
|
||||
}
|
||||
|
||||
val videoQuality = if (isFrontCamera) config.frontVideoQuality else config.backVideoQuality
|
||||
var selectionIndex = videoResolutions.indexOf(videoQuality)
|
||||
var selectionIndex = if (isFrontCamera) config.frontVideoResIndex else config.backVideoResIndex
|
||||
selectionIndex = selectionIndex.coerceAtLeast(0)
|
||||
Log.i(TAG, "videoResolutions=$videoResolutions")
|
||||
Log.i(TAG, "setupVideoResolutionPicker: selectionIndex=$selectionIndex")
|
||||
|
||||
view.change_resolution_video_holder.setOnClickListener {
|
||||
RadioGroupDialog(activity, ArrayList(items), selectionIndex) {
|
||||
selectionIndex = it as Int
|
||||
val selectedItem = items[selectionIndex]
|
||||
val selectedQuality = videoResolutions[selectionIndex]
|
||||
view.change_resolution_video.text = selectedItem.title
|
||||
if (isFrontCamera) {
|
||||
config.frontVideoQuality = selectedQuality
|
||||
config.frontVideoResIndex = selectionIndex
|
||||
} else {
|
||||
config.backVideoQuality = selectedQuality
|
||||
config.backPhotoResIndex = selectionIndex
|
||||
}
|
||||
dialog.dismiss()
|
||||
dialog?.dismiss()
|
||||
callback.invoke()
|
||||
}
|
||||
}
|
||||
view.change_resolution_video.text = items.getOrNull(selectionIndex)?.title
|
||||
}
|
||||
|
||||
private fun getFormattedResolutions(resolutions: List<MySize>): ArrayList<RadioItem> {
|
||||
val items = ArrayList<RadioItem>(resolutions.size)
|
||||
val sorted = resolutions.sortedByDescending { it.width * it.height }
|
||||
sorted.forEachIndexed { index, size ->
|
||||
val megapixels = String.format("%.1f", (size.width * size.height.toFloat()) / 1000000)
|
||||
val aspectRatio = size.getAspectRatio(activity)
|
||||
items.add(RadioItem(index, "${size.width} x ${size.height} ($megapixels MP, $aspectRatio)"))
|
||||
}
|
||||
return items
|
||||
val selectedItem = items.getOrNull(selectionIndex)
|
||||
view.change_resolution_video.text = selectedItem?.title
|
||||
Log.i(TAG, "setupVideoResolutionPicker: selectedItem=$selectedItem")
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package com.simplemobiletools.camera.helpers
|
||||
import android.content.Context
|
||||
import android.os.Environment
|
||||
import androidx.camera.core.CameraSelector
|
||||
import com.simplemobiletools.camera.models.VideoQuality
|
||||
import com.simplemobiletools.commons.helpers.BaseConfig
|
||||
import java.io.File
|
||||
|
||||
@ -63,20 +62,6 @@ class Config(context: Context) : BaseConfig(context) {
|
||||
get() = prefs.getInt(FRONT_PHOTO_RESOLUTION_INDEX, 0)
|
||||
set(frontPhotoResIndex) = prefs.edit().putInt(FRONT_PHOTO_RESOLUTION_INDEX, frontPhotoResIndex).apply()
|
||||
|
||||
var backVideoQuality: VideoQuality
|
||||
get() {
|
||||
val backQuality = prefs.getString(BACK_VIDEO_QUALITY, VideoQuality.UHD.name)
|
||||
return VideoQuality.values().first { it.name == backQuality }
|
||||
}
|
||||
set(backVideoQuality) = prefs.edit().putString(BACK_VIDEO_QUALITY, backVideoQuality.name).apply()
|
||||
|
||||
var frontVideoQuality: VideoQuality
|
||||
get() {
|
||||
val frontQuality = prefs.getString(FRONT_VIDEO_QUALITY, VideoQuality.UHD.name)
|
||||
return VideoQuality.values().first { it.name == frontQuality }
|
||||
}
|
||||
set(frontVideoQuality) = prefs.edit().putString(FRONT_VIDEO_QUALITY, frontVideoQuality.name).apply()
|
||||
|
||||
var frontVideoResIndex: Int
|
||||
get() = prefs.getInt(FRONT_VIDEO_RESOLUTION_INDEX, 0)
|
||||
set(frontVideoResIndex) = prefs.edit().putInt(FRONT_VIDEO_RESOLUTION_INDEX, frontVideoResIndex).apply()
|
||||
|
@ -10,11 +10,8 @@ import android.util.Log
|
||||
import android.util.Size
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.camera.core.CameraSelector
|
||||
import androidx.camera.video.Quality
|
||||
import com.simplemobiletools.camera.extensions.config
|
||||
import com.simplemobiletools.camera.extensions.toCameraXQuality
|
||||
import com.simplemobiletools.camera.models.CameraSelectorImageQualities
|
||||
import com.simplemobiletools.camera.models.CameraSelectorVideoQualities
|
||||
import com.simplemobiletools.camera.models.MySize
|
||||
|
||||
class ImageQualityManager(
|
||||
@ -69,7 +66,7 @@ class ImageQualityManager(
|
||||
val index = if (cameraSelector == CameraSelector.DEFAULT_FRONT_CAMERA) config.frontPhotoResIndex else config.backPhotoResIndex
|
||||
return imageQualities.filter { it.camSelector == cameraSelector }
|
||||
.flatMap { it.qualities }
|
||||
.sortedByDescending { it.pixels}
|
||||
.sortedByDescending { it.pixels }
|
||||
.distinctBy { it.pixels }
|
||||
.map { Size(it.width, it.height) }
|
||||
.also {
|
||||
@ -85,5 +82,6 @@ class ImageQualityManager(
|
||||
.flatMap { it.qualities }
|
||||
.sortedByDescending { it.pixels }
|
||||
.distinctBy { it.pixels }
|
||||
.filter { it.megaPixels != "0.0" }
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,20 @@
|
||||
package com.simplemobiletools.camera.helpers
|
||||
|
||||
import android.util.Log
|
||||
import androidx.camera.core.Camera
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.camera.core.CameraSelector
|
||||
import androidx.camera.lifecycle.ProcessCameraProvider
|
||||
import androidx.camera.video.Quality
|
||||
import androidx.camera.video.QualitySelector
|
||||
import com.simplemobiletools.camera.extensions.config
|
||||
import com.simplemobiletools.camera.extensions.toCameraXQuality
|
||||
import com.simplemobiletools.camera.extensions.toVideoQuality
|
||||
import com.simplemobiletools.camera.models.CameraSelectorVideoQualities
|
||||
import com.simplemobiletools.camera.models.VideoQuality
|
||||
|
||||
class VideoQualityManager(private val config: Config) {
|
||||
class VideoQualityManager(
|
||||
private val activity: AppCompatActivity,
|
||||
) {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "VideoQualityHelper"
|
||||
@ -19,14 +22,14 @@ class VideoQualityManager(private val config: Config) {
|
||||
private val CAMERA_SELECTORS = arrayOf(CameraSelector.DEFAULT_BACK_CAMERA, CameraSelector.DEFAULT_FRONT_CAMERA)
|
||||
}
|
||||
|
||||
private val config = activity.config
|
||||
private val videoQualities = mutableListOf<CameraSelectorVideoQualities>()
|
||||
|
||||
fun initSupportedQualities(
|
||||
cameraProvider: ProcessCameraProvider,
|
||||
camera: Camera,
|
||||
) {
|
||||
fun initSupportedQualities(cameraProvider: ProcessCameraProvider) {
|
||||
if (videoQualities.isEmpty()) {
|
||||
for (camSelector in CAMERA_SELECTORS) {
|
||||
cameraProvider.unbindAll()
|
||||
val camera = cameraProvider.bindToLifecycle(activity, camSelector)
|
||||
try {
|
||||
if (cameraProvider.hasCamera(camSelector)) {
|
||||
QualitySelector.getSupportedQualities(camera.cameraInfo)
|
||||
@ -34,6 +37,7 @@ class VideoQualityManager(private val config: Config) {
|
||||
.also { allQualities ->
|
||||
val qualities = allQualities.map { it.toVideoQuality() }
|
||||
videoQualities.add(CameraSelectorVideoQualities(camSelector, qualities))
|
||||
|
||||
}
|
||||
Log.i(TAG, "bindCameraUseCases: videoQualities=$videoQualities")
|
||||
}
|
||||
@ -45,11 +49,9 @@ class VideoQualityManager(private val config: Config) {
|
||||
}
|
||||
|
||||
fun getUserSelectedQuality(cameraSelector: CameraSelector): Quality {
|
||||
return if (cameraSelector == CameraSelector.DEFAULT_FRONT_CAMERA) {
|
||||
config.frontVideoQuality.toCameraXQuality()
|
||||
} else {
|
||||
config.backVideoQuality.toCameraXQuality()
|
||||
}
|
||||
var selectionIndex = if (cameraSelector == CameraSelector.DEFAULT_FRONT_CAMERA) config.frontVideoResIndex else config.backVideoResIndex
|
||||
selectionIndex = selectionIndex.coerceAtLeast(0)
|
||||
return getSupportedQualities(cameraSelector)[selectionIndex].toCameraXQuality()
|
||||
}
|
||||
|
||||
fun getSupportedQualities(cameraSelector: CameraSelector): List<VideoQuality> {
|
||||
|
@ -5,6 +5,7 @@ import android.content.Context
|
||||
import android.hardware.SensorManager
|
||||
import android.hardware.display.DisplayManager
|
||||
import android.util.Log
|
||||
import android.util.Size
|
||||
import android.view.*
|
||||
import android.view.GestureDetector.SimpleOnGestureListener
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
@ -57,7 +58,7 @@ class CameraXPreview(
|
||||
private val displayManager = activity.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
|
||||
private val mediaSoundHelper = MediaSoundHelper()
|
||||
private val windowMetricsCalculator = WindowMetricsCalculator.getOrCreate()
|
||||
private val videoQualityManager = VideoQualityManager(config)
|
||||
private val videoQualityManager = VideoQualityManager(activity)
|
||||
private val imageQualityManager = ImageQualityManager(activity)
|
||||
private val exifRemover = ExifRemover(contentResolver)
|
||||
|
||||
@ -74,7 +75,7 @@ class CameraXPreview(
|
||||
in 225 until 315 -> Surface.ROTATION_90
|
||||
else -> Surface.ROTATION_0
|
||||
}
|
||||
|
||||
Log.i(TAG, "onOrientationChanged: rotation=$rotation")
|
||||
preview?.targetRotation = rotation
|
||||
imageCapture?.targetRotation = rotation
|
||||
videoCapture?.targetRotation = rotation
|
||||
@ -109,10 +110,13 @@ class CameraXPreview(
|
||||
private fun startCamera(switching: Boolean = false) {
|
||||
Log.i(TAG, "startCamera: ")
|
||||
imageQualityManager.initSupportedQualities()
|
||||
|
||||
val cameraProviderFuture = ProcessCameraProvider.getInstance(activity)
|
||||
cameraProviderFuture.addListener({
|
||||
try {
|
||||
cameraProvider = cameraProviderFuture.get()
|
||||
val provider = cameraProviderFuture.get()
|
||||
cameraProvider = provider
|
||||
videoQualityManager.initSupportedQualities(provider)
|
||||
bindCameraUseCases()
|
||||
setupCameraObservers()
|
||||
} catch (e: Exception) {
|
||||
@ -142,9 +146,7 @@ class CameraXPreview(
|
||||
cameraSelector,
|
||||
preview,
|
||||
captureUseCase,
|
||||
).also {
|
||||
videoQualityManager.initSupportedQualities(cameraProvider, it)
|
||||
}
|
||||
)
|
||||
|
||||
preview?.setSurfaceProvider(previewView.surfaceProvider)
|
||||
setupZoomAndFocus()
|
||||
@ -187,20 +189,31 @@ class CameraXPreview(
|
||||
}
|
||||
|
||||
private fun buildImageCapture(aspectRatio: Int, rotation: Int): ImageCapture {
|
||||
return ImageCapture.Builder()
|
||||
return Builder()
|
||||
.setCaptureMode(CAPTURE_MODE_MAXIMIZE_QUALITY)
|
||||
.setFlashMode(flashMode)
|
||||
.setJpegQuality(config.photoQuality)
|
||||
.setTargetRotation(rotation)
|
||||
.apply {
|
||||
imageQualityManager.getUserSelectedResolution(cameraSelector)?.let { resolution ->
|
||||
val rotatedResolution = getRotatedResolution(rotation, resolution)
|
||||
Log.i(TAG, "buildImageCapture: rotation=$rotation")
|
||||
Log.i(TAG, "buildImageCapture: resolution=$resolution")
|
||||
setTargetResolution(resolution)
|
||||
Log.i(TAG, "buildImageCapture: rotatedResolution=$rotatedResolution")
|
||||
setTargetResolution(rotatedResolution)
|
||||
} ?: setTargetAspectRatio(aspectRatio)
|
||||
}
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun getRotatedResolution(rotationDegrees: Int, resolution: Size): Size {
|
||||
return if (rotationDegrees == Surface.ROTATION_0 || rotationDegrees == Surface.ROTATION_180) {
|
||||
Size(resolution.height, resolution.width)
|
||||
} else {
|
||||
Size(resolution.width, resolution.height)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildPreview(aspectRatio: Int, rotation: Int): Preview {
|
||||
return Preview.Builder()
|
||||
.setTargetRotation(rotation)
|
||||
@ -211,7 +224,7 @@ class CameraXPreview(
|
||||
private fun buildVideoCapture(): VideoCapture<Recorder> {
|
||||
val qualitySelector = QualitySelector.from(
|
||||
videoQualityManager.getUserSelectedQuality(cameraSelector),
|
||||
FallbackStrategy.lowerQualityOrHigherThan(Quality.SD),
|
||||
FallbackStrategy.higherQualityOrLowerThan(Quality.SD),
|
||||
)
|
||||
val recorder = Recorder.Builder()
|
||||
.setQualitySelector(qualitySelector)
|
||||
@ -350,7 +363,7 @@ class CameraXPreview(
|
||||
if (bitmap != null) {
|
||||
listener.onImageCaptured(bitmap)
|
||||
} else {
|
||||
cameraErrorHandler.handleImageCaptureError(ImageCapture.ERROR_CAPTURE_FAILED)
|
||||
cameraErrorHandler.handleImageCaptureError(ERROR_CAPTURE_FAILED)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,16 @@ import android.util.Size
|
||||
import com.simplemobiletools.camera.R
|
||||
|
||||
data class MySize(val width: Int, val height: Int) {
|
||||
companion object {
|
||||
private const val ONE_MEGA_PIXEL = 1000000
|
||||
}
|
||||
|
||||
val ratio = width / height.toFloat()
|
||||
|
||||
val pixels: Int = width * height
|
||||
|
||||
val megaPixels: String = String.format("%.1f", (width * height.toFloat()) / ONE_MEGA_PIXEL)
|
||||
|
||||
fun isSixteenToNine() = ratio == 16 / 9f
|
||||
|
||||
private fun isFiveToThree() = ratio == 5 / 3f
|
||||
|
@ -1,254 +1,283 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/settings_scrollview"
|
||||
android:id="@+id/settings_coordinator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/settings_holder"
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/settings_app_bar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/settings_color_customization_label"
|
||||
style="@style/SettingsSectionLabelStyle"
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/settings_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/color_customization" />
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/color_primary"
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
app:title="@string/settings"
|
||||
app:titleTextAppearance="@style/AppTheme.ActionBar.TitleTextStyle" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/settings_nested_scrollview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
android:scrollbars="none"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/settings_color_customization_holder"
|
||||
android:id="@+id/settings_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/medium_margin"
|
||||
android:background="@drawable/section_holder_stroke"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_customize_colors_holder"
|
||||
style="@style/SettingsHolderTextViewOneLinerStyle"
|
||||
<TextView
|
||||
android:id="@+id/settings_color_customization_label"
|
||||
style="@style/SettingsSectionLabelStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_all_corners">
|
||||
android:text="@string/color_customization" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_customize_colors_label"
|
||||
style="@style/SettingsTextLabelStyle"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:id="@+id/settings_color_customization_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/medium_margin"
|
||||
android:background="@drawable/section_holder_stroke"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_customize_colors_holder"
|
||||
style="@style/SettingsHolderTextViewOneLinerStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/customize_colors" />
|
||||
android:background="@drawable/ripple_all_corners">
|
||||
|
||||
</RelativeLayout>
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_customize_colors_label"
|
||||
style="@style/SettingsTextLabelStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/customize_colors" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/settings_general_settings_label"
|
||||
style="@style/SettingsSectionLabelStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/general_settings" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/settings_general_settings_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/medium_margin"
|
||||
android:background="@drawable/section_holder_stroke"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_purchase_thank_you_holder"
|
||||
style="@style/SettingsHolderTextViewOneLinerStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_top_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_purchase_thank_you"
|
||||
style="@style/SettingsTextLabelStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/purchase_simple_thank_you" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_use_english_holder"
|
||||
style="@style/SettingsHolderCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_background">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_use_english"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/use_english_language" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_keep_settings_visible_holder"
|
||||
style="@style/SettingsHolderCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_bottom_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_keep_settings_visible"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/keep_settings_visible" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/settings_shutter_label"
|
||||
style="@style/SettingsSectionLabelStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/shutter" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/settings_shutter_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/medium_margin"
|
||||
android:background="@drawable/section_holder_stroke"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_sound_holder"
|
||||
style="@style/SettingsHolderCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_top_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_sound"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/shutter_sound" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_volume_buttons_as_shutter_holder"
|
||||
style="@style/SettingsHolderCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_bottom_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_volume_buttons_as_shutter"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/volume_buttons_as_shutter" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/settings_saving_label"
|
||||
style="@style/SettingsSectionLabelStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/saving_label" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/settings_saving_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/medium_margin"
|
||||
android:background="@drawable/section_holder_stroke"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_save_photo_metadata_holder"
|
||||
style="@style/SettingsHolderCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_top_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_save_photo_metadata"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save_photo_metadata" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_flip_photos_holder"
|
||||
style="@style/SettingsHolderCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_background">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_flip_photos"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/flip_front_camera_photos_horizontally" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_save_photos_holder"
|
||||
style="@style/SettingsHolderTextViewStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_background">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_save_photos_label"
|
||||
style="@style/SettingsTextLabelStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save_photos" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_save_photos"
|
||||
style="@style/SettingsTextValueStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/settings_save_photos_label"
|
||||
tools:text="Internal/DCIM" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_photo_quality_holder"
|
||||
style="@style/SettingsHolderTextViewStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_bottom_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_photo_quality_label"
|
||||
style="@style/SettingsTextLabelStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/photo_compression_quality" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_photo_quality"
|
||||
style="@style/SettingsTextValueStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/settings_photo_quality_label"
|
||||
tools:text="80%" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/settings_general_settings_label"
|
||||
style="@style/SettingsSectionLabelStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/general_settings" />
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/settings_general_settings_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/medium_margin"
|
||||
android:background="@drawable/section_holder_stroke"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_purchase_thank_you_holder"
|
||||
style="@style/SettingsHolderTextViewOneLinerStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_top_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_purchase_thank_you"
|
||||
style="@style/SettingsTextLabelStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/purchase_simple_thank_you" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_use_english_holder"
|
||||
style="@style/SettingsHolderCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_background">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_use_english"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/use_english_language" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_keep_settings_visible_holder"
|
||||
style="@style/SettingsHolderCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_bottom_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_keep_settings_visible"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/keep_settings_visible" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/settings_shutter_label"
|
||||
style="@style/SettingsSectionLabelStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/shutter" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/settings_shutter_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/medium_margin"
|
||||
android:background="@drawable/section_holder_stroke"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_sound_holder"
|
||||
style="@style/SettingsHolderCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_top_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_sound"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/shutter_sound" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_volume_buttons_as_shutter_holder"
|
||||
style="@style/SettingsHolderCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_bottom_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_volume_buttons_as_shutter"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/volume_buttons_as_shutter" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/settings_saving_label"
|
||||
style="@style/SettingsSectionLabelStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/saving_label" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/settings_saving_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/medium_margin"
|
||||
android:background="@drawable/section_holder_stroke"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_save_photo_metadata_holder"
|
||||
style="@style/SettingsHolderCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_top_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_save_photo_metadata"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save_photo_metadata" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_flip_photos_holder"
|
||||
style="@style/SettingsHolderCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_background">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
android:id="@+id/settings_flip_photos"
|
||||
style="@style/SettingsCheckboxStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/flip_front_camera_photos_horizontally" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_save_photos_holder"
|
||||
style="@style/SettingsHolderTextViewStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_background">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_save_photos_label"
|
||||
style="@style/SettingsTextLabelStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save_photos" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_save_photos"
|
||||
style="@style/SettingsTextValueStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/settings_save_photos_label"
|
||||
tools:text="Internal/DCIM" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_photo_quality_holder"
|
||||
style="@style/SettingsHolderTextViewStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ripple_bottom_corners">
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_photo_quality_label"
|
||||
style="@style/SettingsTextLabelStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/photo_compression_quality" />
|
||||
|
||||
<com.simplemobiletools.commons.views.MyTextView
|
||||
android:id="@+id/settings_photo_quality"
|
||||
style="@style/SettingsTextValueStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/settings_photo_quality_label"
|
||||
tools:text="80%" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
Loading…
x
Reference in New Issue
Block a user