Add torch brightness level support for Android 13+

This commit is contained in:
darthpaul
2022-10-23 09:03:16 +01:00
parent dc66f8bd66
commit cea57e9db0
6 changed files with 85 additions and 4 deletions

View File

@ -4,12 +4,12 @@ import android.annotation.SuppressLint
import android.content.Intent import android.content.Intent
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.content.pm.ShortcutInfo import android.content.pm.ShortcutInfo
import android.content.res.ColorStateList
import android.graphics.drawable.Icon import android.graphics.drawable.Icon
import android.graphics.drawable.LayerDrawable import android.graphics.drawable.LayerDrawable
import android.os.Bundle import android.os.Bundle
import android.view.WindowManager import android.view.WindowManager
import android.widget.ImageView import android.widget.ImageView
import androidx.core.view.isVisible
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.LICENSE_EVENT_BUS import com.simplemobiletools.commons.helpers.LICENSE_EVENT_BUS
import com.simplemobiletools.commons.helpers.PERMISSION_CAMERA import com.simplemobiletools.commons.helpers.PERMISSION_CAMERA
@ -19,6 +19,7 @@ import com.simplemobiletools.commons.models.FAQItem
import com.simplemobiletools.flashlight.BuildConfig import com.simplemobiletools.flashlight.BuildConfig
import com.simplemobiletools.flashlight.R import com.simplemobiletools.flashlight.R
import com.simplemobiletools.flashlight.extensions.config import com.simplemobiletools.flashlight.extensions.config
import com.simplemobiletools.flashlight.helpers.DEFAULT_BRIGHTNESS_LEVEL
import com.simplemobiletools.flashlight.helpers.MyCameraImpl import com.simplemobiletools.flashlight.helpers.MyCameraImpl
import com.simplemobiletools.flashlight.models.Events import com.simplemobiletools.flashlight.models.Events
import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.activity_main.*
@ -53,6 +54,10 @@ class MainActivity : SimpleActivity() {
flashlight_btn.setOnClickListener { flashlight_btn.setOnClickListener {
mCameraImpl!!.toggleFlashlight() mCameraImpl!!.toggleFlashlight()
if (mCameraImpl?.supportsBrightnessControl() == true) {
brightness_bar.beInvisibleIf(brightness_bar.isVisible)
stroboscope_bar.beInvisible()
}
} }
sos_btn.setOnClickListener { sos_btn.setOnClickListener {
@ -183,6 +188,7 @@ class MainActivity : SimpleActivity() {
if (config.turnFlashlightOn) { if (config.turnFlashlightOn) {
mCameraImpl!!.enableFlashlight() mCameraImpl!!.enableFlashlight()
} }
setupBrightness()
} }
private fun setupStroboscope() { private fun setupStroboscope() {
@ -211,12 +217,23 @@ class MainActivity : SimpleActivity() {
} }
} }
private fun setupBrightness() {
brightness_bar.max = mCameraImpl?.getMaximumBrightnessLevel() ?: DEFAULT_BRIGHTNESS_LEVEL
brightness_bar.progress = config.brightnessLevel
brightness_bar.onSeekBarChangeListener { level ->
val newLevel = level.coerceAtLeast(DEFAULT_BRIGHTNESS_LEVEL)
mCameraImpl?.updateBrightnessLevel(newLevel)
config.brightnessLevel = newLevel
}
}
private fun cameraPermissionGranted(isSOS: Boolean) { private fun cameraPermissionGranted(isSOS: Boolean) {
if (isSOS) { if (isSOS) {
val isSOSRunning = mCameraImpl!!.toggleSOS() val isSOSRunning = mCameraImpl!!.toggleSOS()
sos_btn.setTextColor(if (isSOSRunning) getProperPrimaryColor() else getContrastColor()) sos_btn.setTextColor(if (isSOSRunning) getProperPrimaryColor() else getContrastColor())
} else if (mCameraImpl!!.toggleStroboscope()) { } else if (mCameraImpl!!.toggleStroboscope()) {
stroboscope_bar.beInvisibleIf(stroboscope_bar.isVisible()) stroboscope_bar.beInvisibleIf(stroboscope_bar.isVisible())
brightness_bar.beInvisible()
changeIconColor(if (stroboscope_bar.isVisible()) getProperPrimaryColor() else getContrastColor(), stroboscope_btn) changeIconColor(if (stroboscope_bar.isVisible()) getProperPrimaryColor() else getContrastColor(), stroboscope_btn)
} }
} }

View File

@ -40,4 +40,8 @@ class Config(context: Context) : BaseConfig(context) {
var forcePortraitMode: Boolean var forcePortraitMode: Boolean
get() = prefs.getBoolean(FORCE_PORTRAIT_MODE, true) get() = prefs.getBoolean(FORCE_PORTRAIT_MODE, true)
set(forcePortraitMode) = prefs.edit().putBoolean(FORCE_PORTRAIT_MODE, forcePortraitMode).apply() set(forcePortraitMode) = prefs.edit().putBoolean(FORCE_PORTRAIT_MODE, forcePortraitMode).apply()
var brightnessLevel: Int
get() = prefs.getInt(BRIGHTNESS_LEVEL, DEFAULT_BRIGHTNESS_LEVEL)
set(brightnessLevel) = prefs.edit().putInt(BRIGHTNESS_LEVEL, brightnessLevel).apply()
} }

View File

@ -11,3 +11,5 @@ const val STROBOSCOPE_FREQUENCY = "stroboscope_frequency"
const val STROBOSCOPE_PROGRESS = "stroboscope_progress" const val STROBOSCOPE_PROGRESS = "stroboscope_progress"
const val FORCE_PORTRAIT_MODE = "force_portrait_mode" const val FORCE_PORTRAIT_MODE = "force_portrait_mode"
const val SOS = "sos" const val SOS = "sos"
const val BRIGHTNESS_LEVEL = "brightness_level"
const val DEFAULT_BRIGHTNESS_LEVEL = 1

View File

@ -29,7 +29,7 @@ class MyCameraImpl(val context: Context) {
private var shouldEnableSOS = false private var shouldEnableSOS = false
private var isStroboSOS = false // are we sending SOS, or casual stroboscope? private var isStroboSOS = false // are we sending SOS, or casual stroboscope?
private var marshmallowCamera: MarshmallowCamera? = null private var marshmallowCamera: PostMarshmallowCamera? = null
@Volatile @Volatile
private var shouldStroboscopeStop = false private var shouldStroboscopeStop = false
@ -142,7 +142,7 @@ class MyCameraImpl(val context: Context) {
private fun setupMarshmallowCamera() { private fun setupMarshmallowCamera() {
if (marshmallowCamera == null) { if (marshmallowCamera == null) {
marshmallowCamera = MarshmallowCamera(context) marshmallowCamera = PostMarshmallowCamera(context)
} }
} }
@ -341,4 +341,22 @@ class MyCameraImpl(val context: Context) {
} }
} }
} }
fun getMaximumBrightnessLevel(): Int {
return if (isMarshmallow) {
marshmallowCamera?.getMaximumBrightnessLevel() ?: DEFAULT_BRIGHTNESS_LEVEL
} else DEFAULT_BRIGHTNESS_LEVEL
}
fun supportsBrightnessControl(): Boolean {
return if (isMarshmallow) {
marshmallowCamera?.supportsBrightnessControl() ?: false
} else false
}
fun updateBrightnessLevel(level: Int) {
if (isMarshmallow) {
marshmallowCamera?.changeTorchBrightness(level)
}
}
} }

View File

@ -2,14 +2,17 @@ package com.simplemobiletools.flashlight.helpers
import android.annotation.TargetApi import android.annotation.TargetApi
import android.content.Context import android.content.Context
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager import android.hardware.camera2.CameraManager
import android.os.Build import android.os.Build
import android.os.Handler import android.os.Handler
import com.simplemobiletools.commons.extensions.showErrorToast import com.simplemobiletools.commons.extensions.showErrorToast
import com.simplemobiletools.commons.helpers.isTiramisuPlus
import com.simplemobiletools.flashlight.extensions.config
import com.simplemobiletools.flashlight.models.Events import com.simplemobiletools.flashlight.models.Events
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
internal class MarshmallowCamera constructor(val context: Context) { internal class PostMarshmallowCamera constructor(val context: Context) {
private val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager private val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
private var cameraId: String? = null private var cameraId: String? = null
@ -26,6 +29,9 @@ internal class MarshmallowCamera constructor(val context: Context) {
fun toggleMarshmallowFlashlight(enable: Boolean) { fun toggleMarshmallowFlashlight(enable: Boolean) {
try { try {
manager.setTorchMode(cameraId!!, enable) manager.setTorchMode(cameraId!!, enable)
if (enable) {
changeTorchBrightness(context.config.brightnessLevel)
}
} catch (e: Exception) { } catch (e: Exception) {
context.showErrorToast(e) context.showErrorToast(e)
val mainRunnable = Runnable { val mainRunnable = Runnable {
@ -34,4 +40,24 @@ internal class MarshmallowCamera constructor(val context: Context) {
Handler(context.mainLooper).post(mainRunnable) Handler(context.mainLooper).post(mainRunnable)
} }
} }
fun changeTorchBrightness(level: Int) {
if (isTiramisuPlus()) {
manager.turnOnTorchWithStrengthLevel(cameraId!!, level)
}
}
fun getMaximumBrightnessLevel(): Int {
return if (isTiramisuPlus()) {
val characteristics = manager.getCameraCharacteristics(cameraId!!)
characteristics.get(CameraCharacteristics.FLASH_INFO_STRENGTH_MAXIMUM_LEVEL) ?: DEFAULT_BRIGHTNESS_LEVEL
} else {
DEFAULT_BRIGHTNESS_LEVEL
}
}
fun supportsBrightnessControl(): Boolean {
val maxBrightnessLevel = getMaximumBrightnessLevel()
return maxBrightnessLevel > DEFAULT_BRIGHTNESS_LEVEL
}
} }

View File

@ -105,6 +105,20 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stroboscope_btn" /> app:layout_constraintTop_toBottomOf="@+id/stroboscope_btn" />
<com.simplemobiletools.commons.views.MySeekBar
android:id="@+id/brightness_bar"
android:layout_width="@dimen/seekbar_width"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_margin"
android:paddingTop="@dimen/medium_margin"
android:paddingBottom="@dimen/medium_margin"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stroboscope_btn" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>