do some optimisations for pre SDK 29 devices

This commit is contained in:
darthpaul 2022-07-13 16:39:18 +01:00
parent 6bc74d8066
commit 9c021c655b
7 changed files with 99 additions and 30 deletions

View File

@ -7,6 +7,7 @@ import android.hardware.SensorManager
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.provider.MediaStore
import android.util.Log
import android.view.*
@ -31,9 +32,11 @@ import java.util.concurrent.TimeUnit
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, CameraXPreviewListener {
private val TAG = "MainActivity"
private val FADE_DELAY = 5000L
private val CAPTURE_ANIMATION_DURATION = 100L
companion object {
private const val TAG = "MainActivity"
private const val FADE_DELAY = 5000L
private const val CAPTURE_ANIMATION_DURATION = 100L
}
lateinit var mTimerHandler: Handler
private lateinit var mOrientationEventListener: OrientationEventListener
@ -49,14 +52,8 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
private var mCurrVideoRecTimer = 0
var mLastHandledOrientation = 0
@Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
window.addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
useDynamicTheme = false
super.onCreate(savedInstanceState)
appLaunched(BuildConfig.APPLICATION_ID)
@ -67,6 +64,22 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
supportActionBar?.hide()
checkWhatsNewDialog()
setupOrientationEventListener()
if (isRPlus()) {
setShowWhenLocked(true)
setTurnScreenOn(true)
window.insetsController?.hide(WindowInsets.Type.statusBars())
} else if (isOreoMr1Plus()) {
setShowWhenLocked(true)
setTurnScreenOn(true)
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
} else {
window.addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD or
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
}
}
override fun onResume() {
@ -238,8 +251,8 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
mFocusCircleView = FocusCircleView(applicationContext)
view_holder.addView(mFocusCircleView)
mTimerHandler = Handler()
mFadeHandler = Handler()
mTimerHandler = Handler(Looper.getMainLooper())
mFadeHandler = Handler(Looper.getMainLooper())
setupPreviewImage(true)
val initialFlashlightState = FLASH_OFF
@ -439,8 +452,13 @@ class MainActivity : SimpleActivity(), PhotoProcessor.MediaSavedListener, Camera
view.isClickable = value != .0f
}
@Suppress("DEPRECATION")
private fun hideNavigationBarIcons() {
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LOW_PROFILE
if (isRPlus()) {
window.insetsController?.hide(WindowInsets.Type.systemBars())
} else {
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LOW_PROFILE
}
}
private fun showTimer() {

View File

@ -1,8 +1,10 @@
package com.simplemobiletools.camera.activities
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.core.content.res.ResourcesCompat
import com.simplemobiletools.camera.BuildConfig
import com.simplemobiletools.camera.R
import com.simplemobiletools.camera.extensions.config
@ -14,6 +16,7 @@ import com.simplemobiletools.commons.helpers.NavigationIcon
import com.simplemobiletools.commons.models.FAQItem
import com.simplemobiletools.commons.models.RadioItem
import java.util.Locale
import kotlin.system.exitProcess
import kotlinx.android.synthetic.main.activity_settings.*
class SettingsActivity : SimpleActivity() {
@ -77,7 +80,7 @@ class SettingsActivity : SimpleActivity() {
// make sure the corners at ripple fit the stroke rounded corners
if (settings_purchase_thank_you_holder.isGone()) {
settings_use_english_holder.background = resources.getDrawable(R.drawable.ripple_top_corners, theme)
settings_use_english_holder.background = ResourcesCompat.getDrawable(resources, R.drawable.ripple_top_corners, theme)
}
settings_purchase_thank_you_holder.setOnClickListener {
@ -97,13 +100,13 @@ class SettingsActivity : SimpleActivity() {
settings_use_english.isChecked = config.useEnglish
if (settings_use_english_holder.isGone() && settings_purchase_thank_you_holder.isGone()) {
settings_keep_settings_visible_holder.background = resources.getDrawable(R.drawable.ripple_all_corners, theme)
settings_keep_settings_visible_holder.background = ResourcesCompat.getDrawable(resources, R.drawable.ripple_all_corners, theme)
}
settings_use_english_holder.setOnClickListener {
settings_use_english.toggle()
config.useEnglish = settings_use_english.isChecked
System.exit(0)
exitProcess(0)
}
}
@ -172,8 +175,8 @@ class SettingsActivity : SimpleActivity() {
settings_save_photos_holder.setOnClickListener {
FilePickerDialog(this, config.savePhotosFolder, false, showFAB = true) {
val path = it
handleSAFDialog(it) {
if (it) {
handleSAFDialog(it) { success ->
if (success) {
config.savePhotosFolder = path
settings_save_photos.text = getLastPart(config.savePhotosFolder)
}
@ -206,6 +209,7 @@ class SettingsActivity : SimpleActivity() {
}
}
@SuppressLint("SetTextI18n")
private fun updatePhotoQuality(quality: Int) {
settings_photo_quality.text = "$quality%"
}

View File

@ -90,7 +90,7 @@ class ChangeResolutionDialogX(
if (isFrontCamera) {
config.frontVideoResIndex = selectionIndex
} else {
config.backPhotoResIndex = selectionIndex
config.backVideoResIndex = selectionIndex
}
dialog?.dismiss()
callback.invoke()

View File

@ -12,6 +12,8 @@ import com.simplemobiletools.camera.extensions.getRandomMediaName
import com.simplemobiletools.camera.models.MediaOutput
import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.isOreoPlus
import com.simplemobiletools.commons.helpers.isQPlus
import java.io.File
import java.io.OutputStream
@ -25,6 +27,7 @@ class MediaOutputHelper(
companion object {
private const val TAG = "MediaOutputHelper"
private const val MODE = "rw"
private const val EXTERNAL_VOLUME = "external"
private const val IMAGE_MIME_TYPE = "image/jpeg"
private const val VIDEO_MIME_TYPE = "video/mp4"
}
@ -53,37 +56,56 @@ class MediaOutputHelper(
fun getVideoMediaOutput(): MediaOutput {
return if (is3rdPartyIntent) {
if (outputUri != null) {
val fileDescriptor = openFileDescriptor(outputUri)
if (fileDescriptor != null) {
MediaOutput.FileDescriptorMediaOutput(fileDescriptor, outputUri)
if (isOreoPlus()) {
val fileDescriptor = openFileDescriptor(outputUri)
if (fileDescriptor != null) {
MediaOutput.FileDescriptorMediaOutput(fileDescriptor, outputUri)
} else {
errorHandler.showSaveToInternalStorage()
getMediaStoreOutput(isPhoto = false)
}
} else {
errorHandler.showSaveToInternalStorage()
getMediaStoreOutput(isPhoto = false)
val path = activity.getRealPathFromURI(outputUri)
if (path != null) {
MediaOutput.FileMediaOutput(File(path), outputUri)
} else {
errorHandler.showSaveToInternalStorage()
getMediaStoreOutput(isPhoto = false)
}
}
} else {
getMediaStoreOutput(isPhoto = false)
}
} else {
getFileDescriptorMediaOutput() ?: getMediaStoreOutput(isPhoto = false)
if (isOreoPlus()) {
getFileDescriptorMediaOutput() ?: getMediaStoreOutput(isPhoto = false)
} else {
getFileMediaOutput() ?: getMediaStoreOutput(isPhoto = false)
}
}
}
private fun getMediaStoreOutput(isPhoto: Boolean): MediaOutput.MediaStoreOutput {
val contentValues = getContentValues(isPhoto)
val contentUri = if (isPhoto) {
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
MediaStore.Images.Media.getContentUri(EXTERNAL_VOLUME)
} else {
MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
MediaStore.Video.Media.getContentUri(EXTERNAL_VOLUME)
}
return MediaOutput.MediaStoreOutput(contentValues, contentUri)
}
@Suppress("DEPRECATION")
private fun getContentValues(isPhoto: Boolean): ContentValues {
val mimeType = if (isPhoto) IMAGE_MIME_TYPE else VIDEO_MIME_TYPE
return ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, getRandomMediaName(isPhoto))
put(MediaStore.MediaColumns.MIME_TYPE, mimeType)
put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM)
if (isQPlus()) {
put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM)
} else {
put(MediaStore.MediaColumns.DATA, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString())
}
}
}
@ -131,6 +153,21 @@ class MediaOutputHelper(
return mediaOutput
}
private fun getFileMediaOutput(): MediaOutput.FileMediaOutput? {
var mediaOutput: MediaOutput.FileMediaOutput? = null
val canWrite = canWriteToFilePath(mediaStorageDir)
Log.i(TAG, "getMediaOutput: canWrite=${canWrite}")
if (canWrite) {
val path = activity.getOutputMediaFile(false)
val uri = getUriForFilePath(path)
if (uri != null) {
mediaOutput = MediaOutput.FileMediaOutput(File(path), uri)
}
}
Log.i(TAG, "FileDescriptorMediaOutput: $mediaOutput")
return mediaOutput
}
private fun openFileDescriptor(uri: Uri): ParcelFileDescriptor? {
return try {
Log.i(TAG, "uri: $uri")

View File

@ -51,7 +51,7 @@ class VideoQualityManager(
fun getUserSelectedQuality(cameraSelector: CameraSelector): Quality {
var selectionIndex = if (cameraSelector == CameraSelector.DEFAULT_FRONT_CAMERA) config.frontVideoResIndex else config.backVideoResIndex
selectionIndex = selectionIndex.coerceAtLeast(0)
return getSupportedQualities(cameraSelector)[selectionIndex].toCameraXQuality()
return getSupportedQualities(cameraSelector).getOrElse(selectionIndex) { VideoQuality.HD }.toCameraXQuality()
}
fun getSupportedQualities(cameraSelector: CameraSelector): List<VideoQuality> {

View File

@ -431,7 +431,7 @@ class CameraXPreview(
}
}
@SuppressLint("MissingPermission")
@SuppressLint("MissingPermission", "NewApi")
private fun startRecording() {
val videoCapture = videoCapture ?: throw IllegalStateException("Camera initialization failed.")
@ -441,6 +441,10 @@ class CameraXPreview(
FileDescriptorOutputOptions.Builder(mediaOutput.fileDescriptor).build()
.let { videoCapture.output.prepareRecording(activity, it) }
}
is MediaOutput.FileMediaOutput -> {
FileOutputOptions.Builder(mediaOutput.file).build()
.let { videoCapture.output.prepareRecording(activity, it) }
}
is MediaOutput.MediaStoreOutput -> {
MediaStoreOutputOptions.Builder(contentResolver, mediaOutput.contentUri).setContentValues(mediaOutput.contentValues).build()
.let { videoCapture.output.prepareRecording(activity, it) }

View File

@ -3,6 +3,7 @@ package com.simplemobiletools.camera.models
import android.content.ContentValues
import android.net.Uri
import android.os.ParcelFileDescriptor
import java.io.File
import java.io.OutputStream
sealed class MediaOutput(
@ -23,5 +24,10 @@ sealed class MediaOutput(
override val uri: Uri,
) : MediaOutput(uri)
data class FileMediaOutput(
val file: File,
override val uri: Uri,
) : MediaOutput(uri)
object BitmapOutput : MediaOutput(null)
}