mirror of
https://github.com/SimpleMobileTools/Simple-Flashlight.git
synced 2025-06-05 21:59:19 +02:00
Add torch brightness level support for Android 13+
This commit is contained in:
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
@ -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>
|
||||||
|
Reference in New Issue
Block a user