Skip to content

Commit 858533e

Browse files
authored
Merge pull request #174 from KryptKode/feat/brightness-control
Add torch brightness level support for Android 13+
2 parents f20341d + c975ab1 commit 858533e

File tree

10 files changed

+257
-173
lines changed

10 files changed

+257
-173
lines changed

app/src/main/kotlin/com/simplemobiletools/flashlight/activities/MainActivity.kt

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import android.annotation.SuppressLint
44
import android.content.Intent
55
import android.content.pm.ActivityInfo
66
import android.content.pm.ShortcutInfo
7-
import android.content.res.ColorStateList
87
import android.graphics.drawable.Icon
98
import android.graphics.drawable.LayerDrawable
109
import android.os.Bundle
@@ -19,6 +18,8 @@ import com.simplemobiletools.commons.models.FAQItem
1918
import com.simplemobiletools.flashlight.BuildConfig
2019
import com.simplemobiletools.flashlight.R
2120
import com.simplemobiletools.flashlight.extensions.config
21+
import com.simplemobiletools.flashlight.helpers.CameraTorchListener
22+
import com.simplemobiletools.flashlight.helpers.MIN_BRIGHTNESS_LEVEL
2223
import com.simplemobiletools.flashlight.helpers.MyCameraImpl
2324
import com.simplemobiletools.flashlight.models.Events
2425
import kotlinx.android.synthetic.main.activity_main.*
@@ -179,10 +180,17 @@ class MainActivity : SimpleActivity() {
179180
}
180181

181182
private fun setupCameraImpl() {
182-
mCameraImpl = MyCameraImpl.newInstance(this)
183+
mCameraImpl = MyCameraImpl.newInstance(this, object : CameraTorchListener {
184+
override fun onTorchEnabled(isEnabled: Boolean) {
185+
if (mCameraImpl!!.supportsBrightnessControl()) {
186+
brightness_bar.beVisibleIf(isEnabled)
187+
}
188+
}
189+
})
183190
if (config.turnFlashlightOn) {
184191
mCameraImpl!!.enableFlashlight()
185192
}
193+
setupBrightness()
186194
}
187195

188196
private fun setupStroboscope() {
@@ -211,6 +219,16 @@ class MainActivity : SimpleActivity() {
211219
}
212220
}
213221

222+
private fun setupBrightness() {
223+
brightness_bar.max = mCameraImpl?.getMaximumBrightnessLevel() ?: MIN_BRIGHTNESS_LEVEL
224+
brightness_bar.progress = mCameraImpl?.getCurrentBrightnessLevel() ?: MIN_BRIGHTNESS_LEVEL
225+
brightness_bar.onSeekBarChangeListener { level ->
226+
val newLevel = level.coerceAtLeast(MIN_BRIGHTNESS_LEVEL)
227+
mCameraImpl?.updateBrightnessLevel(newLevel)
228+
config.brightnessLevel = newLevel
229+
}
230+
}
231+
214232
private fun cameraPermissionGranted(isSOS: Boolean) {
215233
if (isSOS) {
216234
val isSOSRunning = mCameraImpl!!.toggleSOS()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.simplemobiletools.flashlight.helpers
2+
3+
interface CameraFlash {
4+
fun initialize()
5+
fun toggleFlashlight(enable: Boolean)
6+
fun changeTorchBrightness(level: Int) {}
7+
fun getMaximumBrightnessLevel(): Int = DEFAULT_BRIGHTNESS_LEVEL
8+
fun supportsBrightnessControl(): Boolean = false
9+
fun getCurrentBrightnessLevel(): Int = DEFAULT_BRIGHTNESS_LEVEL
10+
fun unregisterListeners(){}
11+
fun release(){}
12+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.simplemobiletools.flashlight.helpers
2+
3+
interface CameraTorchListener {
4+
fun onTorchEnabled(isEnabled:Boolean)
5+
}

app/src/main/kotlin/com/simplemobiletools/flashlight/helpers/Config.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,8 @@ class Config(context: Context) : BaseConfig(context) {
4040
var forcePortraitMode: Boolean
4141
get() = prefs.getBoolean(FORCE_PORTRAIT_MODE, true)
4242
set(forcePortraitMode) = prefs.edit().putBoolean(FORCE_PORTRAIT_MODE, forcePortraitMode).apply()
43+
44+
var brightnessLevel: Int
45+
get() = prefs.getInt(BRIGHTNESS_LEVEL, DEFAULT_BRIGHTNESS_LEVEL)
46+
set(brightnessLevel) = prefs.edit().putInt(BRIGHTNESS_LEVEL, brightnessLevel).apply()
4347
}

app/src/main/kotlin/com/simplemobiletools/flashlight/helpers/Constants.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ const val STROBOSCOPE_FREQUENCY = "stroboscope_frequency"
1111
const val STROBOSCOPE_PROGRESS = "stroboscope_progress"
1212
const val FORCE_PORTRAIT_MODE = "force_portrait_mode"
1313
const val SOS = "sos"
14+
const val BRIGHTNESS_LEVEL = "brightness_level"
15+
const val MIN_BRIGHTNESS_LEVEL = 1
16+
const val DEFAULT_BRIGHTNESS_LEVEL = -1
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
@file:Suppress("DEPRECATION")
2+
3+
package com.simplemobiletools.flashlight.helpers
4+
5+
import android.graphics.SurfaceTexture
6+
import android.hardware.Camera
7+
8+
class LollipopCameraFlash : CameraFlash {
9+
private var camera: Camera? = null
10+
private var params: Camera.Parameters? = null
11+
12+
override fun toggleFlashlight(enable: Boolean) {
13+
if (camera == null || params == null || camera!!.parameters == null) {
14+
return
15+
}
16+
val flashMode = if (enable) Camera.Parameters.FLASH_MODE_ON else Camera.Parameters.FLASH_MODE_OFF
17+
params!!.flashMode = flashMode
18+
camera!!.parameters = params
19+
if (enable) {
20+
val dummy = SurfaceTexture(1)
21+
camera!!.setPreviewTexture(dummy)
22+
camera!!.startPreview()
23+
}
24+
}
25+
26+
override fun initialize() {
27+
camera = Camera.open()
28+
params = camera!!.parameters
29+
params!!.flashMode = Camera.Parameters.FLASH_MODE_OFF
30+
camera!!.parameters = params
31+
}
32+
33+
override fun release() {
34+
camera!!.release()
35+
camera = null
36+
}
37+
}

app/src/main/kotlin/com/simplemobiletools/flashlight/helpers/MarshmallowCamera.kt

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package com.simplemobiletools.flashlight.helpers
2+
3+
import android.content.Context
4+
import android.hardware.camera2.CameraCharacteristics
5+
import android.hardware.camera2.CameraManager
6+
import android.os.Build
7+
import android.os.Handler
8+
import androidx.annotation.RequiresApi
9+
import com.simplemobiletools.commons.extensions.showErrorToast
10+
import com.simplemobiletools.commons.helpers.isTiramisuPlus
11+
import com.simplemobiletools.flashlight.extensions.config
12+
import com.simplemobiletools.flashlight.models.Events
13+
import org.greenrobot.eventbus.EventBus
14+
15+
@RequiresApi(Build.VERSION_CODES.M)
16+
internal class MarshmallowPlusCameraFlash(
17+
private val context: Context,
18+
private var cameraTorchListener: CameraTorchListener? = null,
19+
) : CameraFlash {
20+
21+
private val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
22+
private var cameraId: String? = null
23+
24+
private val torchCallback = object : CameraManager.TorchCallback() {
25+
override fun onTorchModeChanged(cameraId: String, enabled: Boolean) {
26+
cameraTorchListener?.onTorchEnabled(enabled)
27+
}
28+
}
29+
30+
init {
31+
try {
32+
cameraId = manager.cameraIdList[0] ?: "0"
33+
} catch (e: Exception) {
34+
context.showErrorToast(e)
35+
}
36+
}
37+
38+
override fun toggleFlashlight(enable: Boolean) {
39+
try {
40+
if (supportsBrightnessControl() && enable) {
41+
val brightnessLevel = getCurrentBrightnessLevel()
42+
changeTorchBrightness(brightnessLevel)
43+
} else {
44+
manager.setTorchMode(cameraId!!, enable)
45+
}
46+
} catch (e: Exception) {
47+
context.showErrorToast(e)
48+
val mainRunnable = Runnable {
49+
EventBus.getDefault().post(Events.CameraUnavailable())
50+
}
51+
Handler(context.mainLooper).post(mainRunnable)
52+
}
53+
}
54+
55+
override fun changeTorchBrightness(level: Int) {
56+
if (isTiramisuPlus()) {
57+
manager.turnOnTorchWithStrengthLevel(cameraId!!, level)
58+
}
59+
}
60+
61+
override fun getMaximumBrightnessLevel(): Int {
62+
return if (isTiramisuPlus()) {
63+
val characteristics = manager.getCameraCharacteristics(cameraId!!)
64+
characteristics.get(CameraCharacteristics.FLASH_INFO_STRENGTH_MAXIMUM_LEVEL) ?: MIN_BRIGHTNESS_LEVEL
65+
} else {
66+
MIN_BRIGHTNESS_LEVEL
67+
}
68+
}
69+
70+
override fun supportsBrightnessControl(): Boolean {
71+
val maxBrightnessLevel = getMaximumBrightnessLevel()
72+
return maxBrightnessLevel > MIN_BRIGHTNESS_LEVEL
73+
}
74+
75+
override fun getCurrentBrightnessLevel(): Int {
76+
var brightnessLevel = context.config.brightnessLevel
77+
if (brightnessLevel == DEFAULT_BRIGHTNESS_LEVEL) {
78+
brightnessLevel = getMaximumBrightnessLevel()
79+
}
80+
return brightnessLevel
81+
}
82+
83+
override fun initialize() {
84+
manager.registerTorchCallback(torchCallback, Handler(context.mainLooper))
85+
}
86+
87+
override fun unregisterListeners() {
88+
manager.unregisterTorchCallback(torchCallback)
89+
}
90+
91+
override fun release() {
92+
cameraTorchListener = null
93+
}
94+
}

0 commit comments

Comments
 (0)