action: torch

This commit is contained in:
Josia Pietsch 2024-11-03 19:33:21 +01:00
parent d703a139f3
commit 7efe05011f
Signed by: jrpie
GPG key ID: E70B571D66986A2D
5 changed files with 144 additions and 2 deletions

View file

@ -1,14 +1,22 @@
package de.jrpie.android.launcher
import android.os.Build
import android.os.Build.VERSION_CODES
import androidx.preference.PreferenceManager
import de.jrpie.android.launcher.actions.TorchManager
import de.jrpie.android.launcher.preferences.LauncherPreferences
class Application : android.app.Application() {
var torchManager: TorchManager? = null
override fun onCreate() {
super.onCreate()
if (Build.VERSION.SDK_INT >= VERSION_CODES.M) {
torchManager = TorchManager(this)
}
val preferences = PreferenceManager.getDefaultSharedPreferences(this)
LauncherPreferences.init(preferences, this.resources)
}
}
}

View file

@ -5,10 +5,15 @@ import android.content.Intent
import android.content.SharedPreferences.Editor
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.hardware.camera2.CameraAccessException
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.media.AudioManager
import android.os.Build
import android.os.SystemClock
import android.view.KeyEvent
import android.widget.Toast
import de.jrpie.android.launcher.Application
import de.jrpie.android.launcher.R
import de.jrpie.android.launcher.apps.AppFilter
import de.jrpie.android.launcher.apps.AppInfo.Companion.INVALID_USER
@ -37,7 +42,7 @@ enum class LauncherAction(
"launcher:chooseFromFavorites",
R.string.list_other_list_favorites,
R.drawable.baseline_favorite_24,
{ context -> openAppsList(context, true)}
{ context -> openAppsList(context, true) }
),
VOLUME_UP(
"launcher:volumeUp",
@ -77,6 +82,12 @@ enum class LauncherAction(
R.drawable.baseline_lock_24px,
LauncherDeviceAdmin::lockScreen
),
TORCH(
"launcher:toggleTorch",
R.string.list_other_torch,
R.drawable.baseline_flashlight_on_24,
::toggleTorch
),
NOP("launcher:nop", R.string.list_other_nop, R.drawable.baseline_not_interested_24, {});
override fun invoke(context: Context, rect: Rect?): Boolean {
@ -171,6 +182,19 @@ private fun audioVolumeDown(context: Context) {
}
/* End media player actions */
private fun toggleTorch(context: Context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Toast.makeText(
context,
context.getString(R.string.alert_requires_android_m),
Toast.LENGTH_LONG
).show()
return
}
(context.applicationContext as Application).torchManager?.toggleTorch(context)
}
private fun expandNotificationsPanel(context: Context) {
/* https://stackoverflow.com/a/15582509 */
try {

View file

@ -0,0 +1,91 @@
package de.jrpie.android.launcher.actions
import android.annotation.SuppressLint
import android.content.Context
import android.hardware.camera2.CameraAccessException
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.os.Build
import android.os.Build.VERSION_CODES
import android.os.Handler
import android.os.Looper
import android.widget.Toast
import androidx.annotation.RequiresApi
import de.jrpie.android.launcher.R
@RequiresApi(VERSION_CODES.M)
class TorchManager(context: Context) {
private val camera = getCameraId(context)
private var torchEnabled = false
private val torchCallback = object : CameraManager.TorchCallback() {
override fun onTorchModeChanged(cameraId: String, enabled: Boolean) {
synchronized(this@TorchManager) {
if (cameraId == camera) {
torchEnabled = enabled
}
}
}
}
init {
registerCallback(context)
}
private fun getCameraId(context: Context): String? {
val cameraManager =
context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
return cameraManager.cameraIdList.firstOrNull { c ->
cameraManager
.getCameraCharacteristics(c)
.get(CameraCharacteristics.FLASH_INFO_AVAILABLE) ?: false
}
}
private fun registerCallback(context: Context) {
val cameraManager =
context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
cameraManager.registerTorchCallback(
torchCallback,
Handler(Looper.getMainLooper())
)
}
fun toggleTorch(context: Context) {
synchronized(this) {
val cameraManager =
context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
if (camera == null) {
Toast.makeText(
context,
context.getString(R.string.alert_no_torch_found),
Toast.LENGTH_LONG
).show()
return
}
try {
if (!torchEnabled && Build.VERSION.SDK_INT >= VERSION_CODES.TIRAMISU) {
cameraManager.turnOnTorchWithStrengthLevel(
camera,
cameraManager.getCameraCharacteristics(camera)
.get(CameraCharacteristics.FLASH_INFO_STRENGTH_MAXIMUM_LEVEL) ?: 1
)
} else {
cameraManager.setTorchMode(camera, !torchEnabled)
}
} catch (e: CameraAccessException) {
Toast.makeText(
context,
context.getString(R.string.alert_torch_access_exception),
Toast.LENGTH_LONG
).show()
}
}
}
}

View file

@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?android:textColor"
android:pathData="M6,2h12v3h-12z" />
<path
android:fillColor="?android:textColor"
android:pathData="M6,7v1l2,3v11h8V11l2,-3V7H6zM12,15.5c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5s1.5,0.67 1.5,1.5S12.83,15.5 12,15.5z" />
</vector>

View file

@ -234,10 +234,13 @@
<string name="settings">Settings</string>
<string name="ic_menu_alt">More options</string>
<string name="alert_cant_expand_status_bar_panel">Error: Can\'t expand status bar.\nThis action is using functionality that is not part of the published Android API. Unfortunately, it does not seem to work on your device.</string>
<string name="alert_requires_android_m">This functionality requires Android 6.0 or later.</string>
<string name="snackbar_app_hidden">App hidden. You can make it visible again in settings.</string>
<string name="undo">Undo</string>
<string name="list_other_expand_settings_panel">Quick Settings</string>
<string name="toast_device_admin_not_enabled">µLauncher needs to be a device admin in order to lock the screen.</string>
<string name="device_admin_explanation">This is required for the lock screen action.</string>
<string name="device_admin_description">Enable the lock screen action</string>
<string name="alert_no_torch_found">No camera with torch detected.</string>
<string name="alert_torch_access_exception">Error: Can\'t access torch.</string>
</resources>