app/src/main/java/dev/equwal/inkrecents/SettingsActivity.kt (3666 bytes)
1 // SPDX-License-Identifier: GPL-3.0-or-later 2 // Copyright (c) 2026 equwal 3 package dev.equwal.inkrecents 4 5 import android.app.Activity 6 import android.content.Intent 7 import android.net.Uri 8 import android.provider.Settings 9 import android.widget.LinearLayout 10 import dev.equwal.inkrecents.Ui.button 11 import dev.equwal.inkrecents.Ui.header 12 import dev.equwal.inkrecents.Ui.note 13 import dev.equwal.inkrecents.Ui.row 14 15 /** 16 * The two ways this app can read the recent apps, and what the app is. 17 * 18 * Usage access is enough to put the apps in order of last use. Shizuku gives 19 * shell access, which gives the real task list and a real close. 20 */ 21 class SettingsActivity : Activity() { 22 23 private val redraw: () -> Unit = { if (!isFinishing) build() } 24 25 override fun onResume() { 26 super.onResume() 27 Shell.onChange(redraw) 28 Shell.connect(this) 29 build() 30 } 31 32 override fun onPause() { 33 super.onPause() 34 Shell.removeOnChange(redraw) 35 } 36 37 private fun build() { 38 val col = Ui.page(this, "Settings") 39 40 col.header("Usage access") 41 col.note("It puts your apps in order of last use.") 42 col.row("State", null, enabled = false, state = if (Apps.hasUsageAccess(this)) "On" else "Off") 43 col.button("Open usage access") { start(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)) } 44 45 col.header("Shizuku") 46 col.note("It gives shell access. Then the cards are the real tasks, and a card closes its task.") 47 col.row("State", null, enabled = false, state = Shell.describe(this)) 48 if (Shell.state(this) != Shell.State.READY) steps(col) 49 50 col.header("About") 51 col.row("Version", null, enabled = false, state = BuildConfig.VERSION_NAME) 52 col.row("Licence", null, enabled = false, state = "GPL-3.0-or-later") 53 col.row("Source code", REPO) { start(Intent(Intent.ACTION_VIEW, Uri.parse(REPO))) } 54 col.row("Buy me a coffee", TIP.removePrefix("https://")) { start(Intent(Intent.ACTION_VIEW, Uri.parse(TIP))) } 55 } 56 57 /** The four steps to shell access, from the device itself. */ 58 private fun steps(col: LinearLayout) { 59 val state = Shell.state(this) 60 col.note("1. Install Shizuku. It is free.") 61 if (state == Shell.State.NOT_INSTALLED) { 62 col.button("Get Shizuku") { 63 if (!start(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + Shell.SHIZUKU_PACKAGE)))) { 64 start(Intent(Intent.ACTION_VIEW, Uri.parse("https://shizuku.rikka.app/download/"))) 65 } 66 } 67 } 68 69 col.note("2. Turn on wireless debugging in Developer options.") 70 col.button("Open Developer options") { 71 if (!start(Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS))) { 72 start(Intent(Settings.ACTION_DEVICE_INFO_SETTINGS)) 73 } 74 } 75 76 col.note("3. In Shizuku, pair with the code, then press Start.") 77 if (state != Shell.State.NOT_INSTALLED) { 78 col.button("Open Shizuku") { 79 packageManager.getLaunchIntentForPackage(Shell.SHIZUKU_PACKAGE)?.let { start(it) } 80 } 81 } 82 83 col.note("4. Let Ink Recents use Shizuku.") 84 if (state == Shell.State.NO_PERMISSION) { 85 col.button("Ask for permission") { Shell.requestPermission() } 86 } 87 } 88 89 private fun start(i: Intent): Boolean = 90 runCatching { startActivity(i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); true }.getOrDefault(false) 91 92 private companion object { 93 const val REPO = "https://github.com/equwal/ink-recents" 94 const val TIP = "https://ko-fi.com/truex" 95 } 96 }