Files
LockScreenWallpaper/plugins/android/src/main/java/WallpaperPlugin.kt
T
Christoph 2cfc7c5dcb feat(wallpaper): extend commands with gallery, delete image, and crop
The plugin now exposes gallery retrieval, image deletion and image crop
across Android, desktop and mobile. The Rust core and Android
bridge are wired to handle these commands, updating state as needed.

- Add gallery, delete_image, and set_image_crop commands
- across Android, desktop and mobile.
- Update permissions, defaults, and schema to enable new commands.
2026-08-20 22:06:00 +02:00

92 lines
3.8 KiB
Kotlin

package de.wechselbild.wallpaper
import android.app.Activity
import android.content.Intent
import android.net.Uri
import androidx.activity.result.ActivityResult
import app.tauri.annotation.ActivityCallback
import app.tauri.annotation.Command
import app.tauri.annotation.InvokeArg
import app.tauri.annotation.TauriPlugin
import app.tauri.plugin.Invoke
import app.tauri.plugin.Plugin
import java.io.File
import java.util.UUID
import java.util.concurrent.Executors
@InvokeArg
class SettingArgs { lateinit var name: String; var value: Boolean = false }
@InvokeArg
class GalleryArgs { var offset: Int = 0; var limit: Int = 48 }
@InvokeArg
class DeleteImageArgs { lateinit var id: String }
@TauriPlugin
class WallpaperPlugin(private val activity: Activity) : Plugin(activity) {
private val io = Executors.newSingleThreadExecutor()
@Command fun getState(invoke: Invoke) = io.execute { invoke.resolve(WallpaperStore.state(activity)) }
@Command fun getGallery(invoke: Invoke) = io.execute {
try {
val args = invoke.parseArgs(GalleryArgs::class.java)
invoke.resolve(WallpaperStore.gallery(activity, args.offset, args.limit))
} catch (error: Exception) { invoke.reject(error.message ?: "Galerie konnte nicht geladen werden") }
}
@Command fun selectImages(invoke: Invoke) {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "image/*"
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
}
startActivityForResult(invoke, intent, "selectedImages")
}
@Command fun deleteImage(invoke: Invoke) = io.execute {
try {
val args = invoke.parseArgs(DeleteImageArgs::class.java)
if (!WallpaperStore.delete(activity, args.id)) throw IllegalArgumentException("Bild wurde nicht gefunden")
invoke.resolve(WallpaperStore.state(activity))
} catch (error: Exception) { invoke.reject(error.message ?: "Bild konnte nicht gelöscht werden") }
}
@ActivityCallback
fun selectedImages(invoke: Invoke, result: ActivityResult) {
if (result.resultCode != Activity.RESULT_OK) { invoke.reject("Bildauswahl abgebrochen"); return }
val uris = mutableListOf<Uri>()
result.data?.data?.let(uris::add)
result.data?.clipData?.let { clip -> for (i in 0 until clip.itemCount) uris.add(clip.getItemAt(i).uri) }
if (uris.isEmpty()) { invoke.reject("Keine Bilder ausgewählt"); return }
io.execute {
try {
uris.forEach { uri ->
val type = activity.contentResolver.getType(uri)
val extension = when (type) { "image/png" -> "png"; "image/webp" -> "webp"; else -> "jpg" }
val target = File(WallpaperStore.directory(activity), "${System.currentTimeMillis()}-${UUID.randomUUID()}.$extension")
activity.contentResolver.openInputStream(uri).use { input -> requireNotNull(input) { "Bild konnte nicht geöffnet werden" }; target.outputStream().use(input::copyTo) }
}
invoke.resolve(WallpaperStore.state(activity))
} catch (error: Exception) { invoke.reject(error.message ?: "Bilder konnten nicht importiert werden") }
}
}
@Command fun setSetting(invoke: Invoke) {
try {
val args = invoke.parseArgs(SettingArgs::class.java)
WallpaperStore.set(activity, args.name, args.value)
if (args.name == "enabled") {
if (args.value) WallpaperRotationService.start(activity) else WallpaperRotationService.stop(activity)
}
invoke.resolve(WallpaperStore.state(activity))
} catch (error: Exception) { invoke.reject(error.message ?: "Einstellung konnte nicht gespeichert werden") }
}
@Command fun nextWallpaper(invoke: Invoke) = io.execute {
if (WallpaperStore.applyNext(activity)) invoke.resolve(WallpaperStore.state(activity)) else invoke.reject("Bitte wähle zuerst Bilder aus")
}
}