Recently Written · git

ink-recents

Ink Recents: a recent-apps switcher drawn for e-ink readers. No animation, swipe up to close, swipe down to close the others.

git clone https://github.com/equwal/ink-recents

Log | Files | Refs


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 }