mirror of
https://github.com/SimpleMobileTools/Simple-Flashlight.git
synced 2025-02-18 04:40:36 +01:00
Merge pull request #174 from KryptKode/feat/brightness-control
Add torch brightness level support for Android 13+
This commit is contained in:
commit
858533e991
@ -4,7 +4,6 @@ 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
|
||||||
@ -19,6 +18,8 @@ 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.CameraTorchListener
|
||||||
|
import com.simplemobiletools.flashlight.helpers.MIN_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.*
|
||||||
@ -179,10 +180,17 @@ class MainActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupCameraImpl() {
|
private fun setupCameraImpl() {
|
||||||
mCameraImpl = MyCameraImpl.newInstance(this)
|
mCameraImpl = MyCameraImpl.newInstance(this, object : CameraTorchListener {
|
||||||
|
override fun onTorchEnabled(isEnabled: Boolean) {
|
||||||
|
if (mCameraImpl!!.supportsBrightnessControl()) {
|
||||||
|
brightness_bar.beVisibleIf(isEnabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
if (config.turnFlashlightOn) {
|
if (config.turnFlashlightOn) {
|
||||||
mCameraImpl!!.enableFlashlight()
|
mCameraImpl!!.enableFlashlight()
|
||||||
}
|
}
|
||||||
|
setupBrightness()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupStroboscope() {
|
private fun setupStroboscope() {
|
||||||
@ -211,6 +219,16 @@ class MainActivity : SimpleActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupBrightness() {
|
||||||
|
brightness_bar.max = mCameraImpl?.getMaximumBrightnessLevel() ?: MIN_BRIGHTNESS_LEVEL
|
||||||
|
brightness_bar.progress = mCameraImpl?.getCurrentBrightnessLevel() ?: MIN_BRIGHTNESS_LEVEL
|
||||||
|
brightness_bar.onSeekBarChangeListener { level ->
|
||||||
|
val newLevel = level.coerceAtLeast(MIN_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()
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.simplemobiletools.flashlight.helpers
|
||||||
|
|
||||||
|
interface CameraFlash {
|
||||||
|
fun initialize()
|
||||||
|
fun toggleFlashlight(enable: Boolean)
|
||||||
|
fun changeTorchBrightness(level: Int) {}
|
||||||
|
fun getMaximumBrightnessLevel(): Int = DEFAULT_BRIGHTNESS_LEVEL
|
||||||
|
fun supportsBrightnessControl(): Boolean = false
|
||||||
|
fun getCurrentBrightnessLevel(): Int = DEFAULT_BRIGHTNESS_LEVEL
|
||||||
|
fun unregisterListeners(){}
|
||||||
|
fun release(){}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.simplemobiletools.flashlight.helpers
|
||||||
|
|
||||||
|
interface CameraTorchListener {
|
||||||
|
fun onTorchEnabled(isEnabled:Boolean)
|
||||||
|
}
|
@ -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,6 @@ 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 MIN_BRIGHTNESS_LEVEL = 1
|
||||||
|
const val DEFAULT_BRIGHTNESS_LEVEL = -1
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
@file:Suppress("DEPRECATION")
|
||||||
|
|
||||||
|
package com.simplemobiletools.flashlight.helpers
|
||||||
|
|
||||||
|
import android.graphics.SurfaceTexture
|
||||||
|
import android.hardware.Camera
|
||||||
|
|
||||||
|
class LollipopCameraFlash : CameraFlash {
|
||||||
|
private var camera: Camera? = null
|
||||||
|
private var params: Camera.Parameters? = null
|
||||||
|
|
||||||
|
override fun toggleFlashlight(enable: Boolean) {
|
||||||
|
if (camera == null || params == null || camera!!.parameters == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val flashMode = if (enable) Camera.Parameters.FLASH_MODE_ON else Camera.Parameters.FLASH_MODE_OFF
|
||||||
|
params!!.flashMode = flashMode
|
||||||
|
camera!!.parameters = params
|
||||||
|
if (enable) {
|
||||||
|
val dummy = SurfaceTexture(1)
|
||||||
|
camera!!.setPreviewTexture(dummy)
|
||||||
|
camera!!.startPreview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initialize() {
|
||||||
|
camera = Camera.open()
|
||||||
|
params = camera!!.parameters
|
||||||
|
params!!.flashMode = Camera.Parameters.FLASH_MODE_OFF
|
||||||
|
camera!!.parameters = params
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun release() {
|
||||||
|
camera!!.release()
|
||||||
|
camera = null
|
||||||
|
}
|
||||||
|
}
|
@ -1,37 +0,0 @@
|
|||||||
package com.simplemobiletools.flashlight.helpers
|
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
|
||||||
import android.content.Context
|
|
||||||
import android.hardware.camera2.CameraManager
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Handler
|
|
||||||
import com.simplemobiletools.commons.extensions.showErrorToast
|
|
||||||
import com.simplemobiletools.flashlight.models.Events
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
|
|
||||||
internal class MarshmallowCamera constructor(val context: Context) {
|
|
||||||
|
|
||||||
private val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
|
||||||
private var cameraId: String? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
try {
|
|
||||||
cameraId = manager.cameraIdList[0] ?: "0"
|
|
||||||
} catch (e: Exception) {
|
|
||||||
context.showErrorToast(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.M)
|
|
||||||
fun toggleMarshmallowFlashlight(enable: Boolean) {
|
|
||||||
try {
|
|
||||||
manager.setTorchMode(cameraId!!, enable)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
context.showErrorToast(e)
|
|
||||||
val mainRunnable = Runnable {
|
|
||||||
EventBus.getDefault().post(Events.CameraUnavailable())
|
|
||||||
}
|
|
||||||
Handler(context.mainLooper).post(mainRunnable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,94 @@
|
|||||||
|
package com.simplemobiletools.flashlight.helpers
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.hardware.camera2.CameraCharacteristics
|
||||||
|
import android.hardware.camera2.CameraManager
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Handler
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
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 org.greenrobot.eventbus.EventBus
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
internal class MarshmallowPlusCameraFlash(
|
||||||
|
private val context: Context,
|
||||||
|
private var cameraTorchListener: CameraTorchListener? = null,
|
||||||
|
) : CameraFlash {
|
||||||
|
|
||||||
|
private val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
||||||
|
private var cameraId: String? = null
|
||||||
|
|
||||||
|
private val torchCallback = object : CameraManager.TorchCallback() {
|
||||||
|
override fun onTorchModeChanged(cameraId: String, enabled: Boolean) {
|
||||||
|
cameraTorchListener?.onTorchEnabled(enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
try {
|
||||||
|
cameraId = manager.cameraIdList[0] ?: "0"
|
||||||
|
} catch (e: Exception) {
|
||||||
|
context.showErrorToast(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toggleFlashlight(enable: Boolean) {
|
||||||
|
try {
|
||||||
|
if (supportsBrightnessControl() && enable) {
|
||||||
|
val brightnessLevel = getCurrentBrightnessLevel()
|
||||||
|
changeTorchBrightness(brightnessLevel)
|
||||||
|
} else {
|
||||||
|
manager.setTorchMode(cameraId!!, enable)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
context.showErrorToast(e)
|
||||||
|
val mainRunnable = Runnable {
|
||||||
|
EventBus.getDefault().post(Events.CameraUnavailable())
|
||||||
|
}
|
||||||
|
Handler(context.mainLooper).post(mainRunnable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun changeTorchBrightness(level: Int) {
|
||||||
|
if (isTiramisuPlus()) {
|
||||||
|
manager.turnOnTorchWithStrengthLevel(cameraId!!, level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMaximumBrightnessLevel(): Int {
|
||||||
|
return if (isTiramisuPlus()) {
|
||||||
|
val characteristics = manager.getCameraCharacteristics(cameraId!!)
|
||||||
|
characteristics.get(CameraCharacteristics.FLASH_INFO_STRENGTH_MAXIMUM_LEVEL) ?: MIN_BRIGHTNESS_LEVEL
|
||||||
|
} else {
|
||||||
|
MIN_BRIGHTNESS_LEVEL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun supportsBrightnessControl(): Boolean {
|
||||||
|
val maxBrightnessLevel = getMaximumBrightnessLevel()
|
||||||
|
return maxBrightnessLevel > MIN_BRIGHTNESS_LEVEL
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getCurrentBrightnessLevel(): Int {
|
||||||
|
var brightnessLevel = context.config.brightnessLevel
|
||||||
|
if (brightnessLevel == DEFAULT_BRIGHTNESS_LEVEL) {
|
||||||
|
brightnessLevel = getMaximumBrightnessLevel()
|
||||||
|
}
|
||||||
|
return brightnessLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initialize() {
|
||||||
|
manager.registerTorchCallback(torchCallback, Handler(context.mainLooper))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterListeners() {
|
||||||
|
manager.unregisterTorchCallback(torchCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun release() {
|
||||||
|
cameraTorchListener = null
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +1,17 @@
|
|||||||
package com.simplemobiletools.flashlight.helpers
|
package com.simplemobiletools.flashlight.helpers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.SurfaceTexture
|
|
||||||
import android.hardware.Camera
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import com.simplemobiletools.commons.extensions.showErrorToast
|
import com.simplemobiletools.commons.extensions.showErrorToast
|
||||||
import com.simplemobiletools.commons.extensions.toast
|
import com.simplemobiletools.commons.extensions.toast
|
||||||
import com.simplemobiletools.commons.helpers.isMarshmallowPlus
|
import com.simplemobiletools.commons.helpers.isMarshmallowPlus
|
||||||
import com.simplemobiletools.commons.helpers.isNougatPlus
|
|
||||||
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.extensions.updateWidgets
|
import com.simplemobiletools.flashlight.extensions.updateWidgets
|
||||||
import com.simplemobiletools.flashlight.models.Events
|
import com.simplemobiletools.flashlight.models.Events
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
|
||||||
class MyCameraImpl(val context: Context) {
|
class MyCameraImpl private constructor(val context: Context, private var cameraTorchListener: CameraTorchListener? = null) {
|
||||||
var stroboFrequency = 1000L
|
var stroboFrequency = 1000L
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -23,15 +20,12 @@ class MyCameraImpl(val context: Context) {
|
|||||||
private var u = 200L // The length of one dit (Time unit)
|
private var u = 200L // The length of one dit (Time unit)
|
||||||
private val SOS = arrayListOf(u, u, u, u, u, u * 3, u * 3, u, u * 3, u, u * 3, u * 3, u, u, u, u, u, u * 7)
|
private val SOS = arrayListOf(u, u, u, u, u, u * 3, u * 3, u, u * 3, u, u * 3, u * 3, u, u, u, u, u, u * 7)
|
||||||
|
|
||||||
private var camera: Camera? = null
|
|
||||||
private var params: Camera.Parameters? = null
|
|
||||||
private var isMarshmallow = false
|
|
||||||
private var shouldEnableFlashlight = false
|
private var shouldEnableFlashlight = false
|
||||||
private var shouldEnableStroboscope = false
|
private var shouldEnableStroboscope = false
|
||||||
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 cameraFlash: CameraFlash? = null
|
||||||
|
|
||||||
@Volatile
|
@Volatile
|
||||||
private var shouldStroboscopeStop = false
|
private var shouldStroboscopeStop = false
|
||||||
@ -42,11 +36,10 @@ class MyCameraImpl(val context: Context) {
|
|||||||
@Volatile
|
@Volatile
|
||||||
private var isSOSRunning = false
|
private var isSOSRunning = false
|
||||||
|
|
||||||
fun newInstance(context: Context) = MyCameraImpl(context)
|
fun newInstance(context: Context, cameraTorchListener: CameraTorchListener? = null) = MyCameraImpl(context, cameraTorchListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
isMarshmallow = isMarshmallowPlus()
|
|
||||||
handleCameraSetup()
|
handleCameraSetup()
|
||||||
stroboFrequency = context.config.stroboscopeFrequency
|
stroboFrequency = context.config.stroboscopeFrequency
|
||||||
}
|
}
|
||||||
@ -57,6 +50,8 @@ class MyCameraImpl(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun toggleStroboscope(): Boolean {
|
fun toggleStroboscope(): Boolean {
|
||||||
|
handleCameraSetup()
|
||||||
|
|
||||||
if (isSOSRunning) {
|
if (isSOSRunning) {
|
||||||
stopSOS()
|
stopSOS()
|
||||||
shouldEnableStroboscope = true
|
shouldEnableStroboscope = true
|
||||||
@ -68,6 +63,8 @@ class MyCameraImpl(val context: Context) {
|
|||||||
disableFlashlight()
|
disableFlashlight()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cameraFlash!!.unregisterListeners()
|
||||||
|
|
||||||
if (!tryInitCamera()) {
|
if (!tryInitCamera()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -87,6 +84,8 @@ class MyCameraImpl(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun toggleSOS(): Boolean {
|
fun toggleSOS(): Boolean {
|
||||||
|
handleCameraSetup()
|
||||||
|
|
||||||
if (isStroboscopeRunning) {
|
if (isStroboscopeRunning) {
|
||||||
stopStroboscope()
|
stopStroboscope()
|
||||||
shouldEnableSOS = true
|
shouldEnableSOS = true
|
||||||
@ -106,6 +105,8 @@ class MyCameraImpl(val context: Context) {
|
|||||||
disableFlashlight()
|
disableFlashlight()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cameraFlash!!.unregisterListeners()
|
||||||
|
|
||||||
return if (isSOSRunning) {
|
return if (isSOSRunning) {
|
||||||
stopSOS()
|
stopSOS()
|
||||||
false
|
false
|
||||||
@ -121,58 +122,26 @@ class MyCameraImpl(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun tryInitCamera(): Boolean {
|
private fun tryInitCamera(): Boolean {
|
||||||
if (!isNougatPlus()) {
|
handleCameraSetup()
|
||||||
if (camera == null) {
|
if (cameraFlash == null) {
|
||||||
initCamera()
|
context.toast(R.string.camera_error)
|
||||||
}
|
return false
|
||||||
|
|
||||||
if (camera == null) {
|
|
||||||
context.toast(R.string.camera_error)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleCameraSetup() {
|
fun handleCameraSetup() {
|
||||||
if (isMarshmallow) {
|
|
||||||
setupMarshmallowCamera()
|
|
||||||
} else {
|
|
||||||
setupCamera()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupMarshmallowCamera() {
|
|
||||||
if (marshmallowCamera == null) {
|
|
||||||
marshmallowCamera = MarshmallowCamera(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupCamera() {
|
|
||||||
if (isMarshmallow) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (camera == null) {
|
|
||||||
initCamera()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initCamera() {
|
|
||||||
try {
|
try {
|
||||||
camera = Camera.open()
|
if (cameraFlash == null) {
|
||||||
params = camera!!.parameters
|
cameraFlash = if (isMarshmallowPlus()) MarshmallowPlusCameraFlash(context, cameraTorchListener) else LollipopCameraFlash()
|
||||||
params!!.flashMode = Camera.Parameters.FLASH_MODE_OFF
|
}
|
||||||
camera!!.parameters = params
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
EventBus.getDefault().post(Events.CameraUnavailable())
|
EventBus.getDefault().post(Events.CameraUnavailable())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkFlashlight() {
|
private fun checkFlashlight() {
|
||||||
if (camera == null) {
|
handleCameraSetup()
|
||||||
handleCameraSetup()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isFlashlightOn) {
|
if (isFlashlightOn) {
|
||||||
enableFlashlight()
|
enableFlashlight()
|
||||||
@ -188,25 +157,12 @@ class MyCameraImpl(val context: Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMarshmallow) {
|
try {
|
||||||
toggleMarshmallowFlashlight(true)
|
cameraFlash!!.initialize()
|
||||||
} else {
|
cameraFlash!!.toggleFlashlight(true)
|
||||||
try {
|
} catch (e: Exception) {
|
||||||
if (camera == null || params == null || camera!!.parameters == null) {
|
context.showErrorToast(e)
|
||||||
return
|
disableFlashlight()
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
params!!.flashMode = Camera.Parameters.FLASH_MODE_TORCH
|
|
||||||
camera!!.parameters = params
|
|
||||||
try {
|
|
||||||
camera!!.startPreview()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
context.showErrorToast(e)
|
|
||||||
disableFlashlight()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val mainRunnable = Runnable { stateChanged(true) }
|
val mainRunnable = Runnable { stateChanged(true) }
|
||||||
@ -218,22 +174,13 @@ class MyCameraImpl(val context: Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMarshmallow) {
|
try {
|
||||||
toggleMarshmallowFlashlight(false)
|
cameraFlash!!.toggleFlashlight(false)
|
||||||
} else {
|
} catch (e: Exception) {
|
||||||
try {
|
context.showErrorToast(e)
|
||||||
if (camera == null || params == null || camera!!.parameters == null) {
|
disableFlashlight()
|
||||||
return
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
params!!.flashMode = Camera.Parameters.FLASH_MODE_OFF
|
|
||||||
camera!!.parameters = params
|
|
||||||
}
|
}
|
||||||
stateChanged(false)
|
stateChanged(false)
|
||||||
releaseCamera()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stateChanged(isEnabled: Boolean) {
|
private fun stateChanged(isEnabled: Boolean) {
|
||||||
@ -242,17 +189,16 @@ class MyCameraImpl(val context: Context) {
|
|||||||
context.updateWidgets(isEnabled)
|
context.updateWidgets(isEnabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toggleMarshmallowFlashlight(enable: Boolean) {
|
|
||||||
marshmallowCamera!!.toggleMarshmallowFlashlight(enable)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun releaseCamera() {
|
fun releaseCamera() {
|
||||||
|
cameraFlash?.unregisterListeners()
|
||||||
|
|
||||||
if (isFlashlightOn) {
|
if (isFlashlightOn) {
|
||||||
disableFlashlight()
|
disableFlashlight()
|
||||||
}
|
}
|
||||||
|
|
||||||
camera?.release()
|
cameraFlash?.release()
|
||||||
camera = null
|
cameraFlash = null
|
||||||
|
cameraTorchListener = null
|
||||||
|
|
||||||
isFlashlightOn = false
|
isFlashlightOn = false
|
||||||
shouldStroboscopeStop = true
|
shouldStroboscopeStop = true
|
||||||
@ -271,56 +217,28 @@ class MyCameraImpl(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var sosIndex = 0
|
var sosIndex = 0
|
||||||
if (isNougatPlus()) {
|
handleCameraSetup()
|
||||||
while (!shouldStroboscopeStop) {
|
while (!shouldStroboscopeStop) {
|
||||||
try {
|
|
||||||
marshmallowCamera!!.toggleMarshmallowFlashlight(true)
|
|
||||||
val onDuration = if (isStroboSOS) SOS[sosIndex++ % SOS.size] else stroboFrequency
|
|
||||||
Thread.sleep(onDuration)
|
|
||||||
marshmallowCamera!!.toggleMarshmallowFlashlight(false)
|
|
||||||
val offDuration = if (isStroboSOS) SOS[sosIndex++ % SOS.size] else stroboFrequency
|
|
||||||
Thread.sleep(offDuration)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
shouldStroboscopeStop = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (camera == null) {
|
|
||||||
initCamera()
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val torchOn = camera!!.parameters ?: return@Runnable
|
cameraFlash!!.toggleFlashlight(true)
|
||||||
val torchOff = camera!!.parameters
|
val onDuration = if (isStroboSOS) SOS[sosIndex++ % SOS.size] else stroboFrequency
|
||||||
torchOn.flashMode = Camera.Parameters.FLASH_MODE_TORCH
|
Thread.sleep(onDuration)
|
||||||
torchOff.flashMode = Camera.Parameters.FLASH_MODE_OFF
|
cameraFlash!!.toggleFlashlight(false)
|
||||||
|
val offDuration = if (isStroboSOS) SOS[sosIndex++ % SOS.size] else stroboFrequency
|
||||||
val dummy = SurfaceTexture(1)
|
Thread.sleep(offDuration)
|
||||||
camera!!.setPreviewTexture(dummy)
|
} catch (e: Exception) {
|
||||||
|
|
||||||
camera!!.startPreview()
|
|
||||||
|
|
||||||
while (!shouldStroboscopeStop) {
|
|
||||||
camera!!.parameters = torchOn
|
|
||||||
val onDuration = if (isStroboSOS) SOS[sosIndex++ % SOS.size] else stroboFrequency
|
|
||||||
Thread.sleep(onDuration)
|
|
||||||
camera!!.parameters = torchOff
|
|
||||||
val offDuration = if (isStroboSOS) SOS[sosIndex++ % SOS.size] else stroboFrequency
|
|
||||||
Thread.sleep(offDuration)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (camera != null) {
|
|
||||||
camera!!.parameters = torchOff
|
|
||||||
if (!shouldEnableFlashlight || isMarshmallow) {
|
|
||||||
camera!!.release()
|
|
||||||
camera = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: RuntimeException) {
|
|
||||||
shouldStroboscopeStop = true
|
shouldStroboscopeStop = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// disable flash immediately if stroboscope is stopped and normal flash mode is disabled
|
||||||
|
if (shouldStroboscopeStop && !shouldEnableFlashlight) {
|
||||||
|
handleCameraSetup()
|
||||||
|
cameraFlash!!.toggleFlashlight(false)
|
||||||
|
cameraFlash!!.release()
|
||||||
|
cameraFlash = null
|
||||||
|
}
|
||||||
|
|
||||||
shouldStroboscopeStop = false
|
shouldStroboscopeStop = false
|
||||||
if (isStroboSOS) {
|
if (isStroboSOS) {
|
||||||
isSOSRunning = false
|
isSOSRunning = false
|
||||||
@ -343,4 +261,20 @@ class MyCameraImpl(val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getMaximumBrightnessLevel(): Int {
|
||||||
|
return cameraFlash!!.getMaximumBrightnessLevel()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCurrentBrightnessLevel(): Int {
|
||||||
|
return cameraFlash!!.getCurrentBrightnessLevel()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun supportsBrightnessControl(): Boolean {
|
||||||
|
return cameraFlash!!.supportsBrightnessControl()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateBrightnessLevel(level: Int) {
|
||||||
|
cameraFlash!!.changeTorchBrightness(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>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user