Android has a “demo mode” where you can change some parts of the system UI. This is great for screenshots. You can interface with the demo mode settings via adb or broadcast Intents (with the android.permission.DUMP permission). I have a library for sending these Intents. I also have an app to showcase the library and to let me take nice screenshots.
Library: https://github.com/NightlyNexus/DemoMode
App: https://play.google.com/store/apps/details?id=com.nightlynexus.demomodesettings
Guetencraft is my popular text-and-line-measurement and pagination tool for Minecraft to make copying and pasting books easy. Available in a JavaFX desktop app and a web page.
Use the webpage: https://nightlynexus.github.io/Gutencraft
See the demo: https://youtu.be/yOT-ZSNCexg
Read the source: https://github.com/NightlyNexus/Gutencraft

Anything with “AI” gets a bunch of downloads on Google Play. Great stuff.
https://play.google.com/store/apps/details?id=com.nightlynexus.groktheapp
Use WebSockets and an app to control your robots. Privately licensed. Email me. Eric@


Every app that uses Retrofit should use my library to inspect application-layer data totally transparently and easily.
https://github.com/NightlyNexus/logging-retrofit
I throw it into development builds of every app I build before I have set up a remote crash logging service because if I am not connected to my computer and my app crashes, I will never see that crash log without DiskCrashReporter. No setup required.
https://github.com/NightlyNexus/DiskCrashReporter
I like to have a sparse home screen on my phone, but I also want to be only a click away from my apps. So, I made a transparent home screen widget to open apps.
Get the app: https://play.google.com/store/apps/details?id=com.nightlynexus.transparentwidget
Read the source: https://github.com/NightlyNexus/TransparentWidget
Touch Blocker puts an invisible view over your screen to intercept touches. You can enable and disable it by long-pressing the power button or with a persistent floating view. My Touch Blocker app is the only app I found on the Play Store that actually works correctly and handles screen insets.
Get the app: https://play.google.com/store/apps/details?id=com.nightlynexus.touchblocker
Read the source: https://github.com/NightlyNexus/TouchBlocker
Select k items from a list of n items with equal probability. Other algorithms run at O(n + k), but depending on n is horrible when you only need a few items from a large list. My algorithm runs simply at O(k). The algorithm emulates a partial Fisher–Yates shuffle by using a hash table to point to swapped indices.
// O(selectCount)
fun <T> uniqueRolls(
availableOptions: List<T>,
selectCount: Int,
random: RandomNumberGenerator
): List<T> {
require(selectCount >= 0)
require(availableOptions.size >= selectCount)
val selection = ArrayList<T>(selectCount)
val indices = LinkedHashMap<Int, Int>(selectCount)
for (i in 0 until selectCount) { // O(selectCount)
val remainingSize = availableOptions.size - i
val roll = random.integer(remainingSize) // [0, availableOptions.size - i)
val randomIndexOfIndices = i + roll
val iIndex = indices[i] ?: i
val randomIndex = indices[randomIndexOfIndices] ?: randomIndexOfIndices
selection += availableOptions[randomIndex]
// We do not need this swap.
// indices[i] = randomIndex
indices[randomIndexOfIndices] = iIndex
}
return selection
}
Expanding on this algorithm, we can also avoid x excluded indices in only O(x + k) by prepopulating our hash table of swapped indices.
// O(exclusionIndices.size + selectCount)
fun <T> uniqueRolls(
availableOptions: List<T>,
exclusionIndices: Set<Int>,
selectCount: Int,
random: RandomNumberGenerator
): List<T> {
require(selectCount >= 0)
val availableOptionsSize = availableOptions.size
val exclusionIndicesSize = exclusionIndices.size
require(availableOptionsSize - exclusionIndicesSize >= selectCount)
// O(exclusionIndicesSize)
val indices = getSparseArrayOfShuffledIndices(
availableOptionsSize,
exclusionIndices,
selectCount
)
var remainingSize = availableOptionsSize - exclusionIndicesSize
val selection = ArrayList<T>(selectCount)
for (i in 0 until selectCount) { // O(selectCount)
// [0, availableOptionsSize - exclusionIndicesSize - i)
val roll = random.integer(remainingSize)
val randomIndexOfIndices = i + roll
val iIndex = indices[i] ?: i
val randomIndex = indices[randomIndexOfIndices] ?: randomIndexOfIndices
selection += availableOptions[randomIndex]
// We do not need this swap.
// indices[i] = randomIndex
indices[randomIndexOfIndices] = iIndex
remainingSize--
}
return selection
}
// O(exclusionIndices.size)
private fun getSparseArrayOfShuffledIndices(
availableOptionsSize: Int,
exclusionIndices: Set<Int>,
selectCount: Int
): LinkedHashMap<Int, Int> {
val exclusionIndicesSize = exclusionIndices.size
val exclusionIndicesStartIndex = availableOptionsSize - exclusionIndicesSize
var exclusionIndicesIndex = exclusionIndicesStartIndex
val indices = LinkedHashMap<Int, Int>(exclusionIndicesSize + selectCount)
for (exclusionIndex in exclusionIndices) { // O(exclusionIndices.size)
require(exclusionIndex >= 0)
require(exclusionIndex < availableOptionsSize)
if (exclusionIndex < exclusionIndicesStartIndex) {
// Although the inner while loop is nested inside the outer for loop, the loops do not
// multiply.
// We never reset exclusionIndicesIndex between iterations; exclusionIndicesIndex only ever
// increments, starting at
// exclusionIndicesStartIndex (availableOptionsSize - exclusionIndicesSize)
// and advancing through
// the tail region ([exclusionIndicesStartIndex, availableOptionsSize)).
//
// The tail region contains exactly exclusionIndicesSize indices, so
// exclusionIndicesIndex can advance at most exclusionIndicesSize steps in
// total across all iterations of the outer loop, regardless of how those
// steps are distributed between iterations.
//
// Total work = outer loop (≤ exclusionIndicesSize iterations)
// + all inner while steps (≤ exclusionIndicesSize total)
// = O(x) + O(x)
// = O(x)
while (exclusionIndices.contains(exclusionIndicesIndex)) {
exclusionIndicesIndex++
}
indices[exclusionIndex] = exclusionIndicesIndex
exclusionIndicesIndex++
}
}
return indices
}
A webpage to show the Monty Hall problem probabilities with any door and reveal counts.
Play the game: https://nightlynexus.github.io/MontyHallProblem
Read the source: https://github.com/NightlyNexus/MontyHallProblem
A webpage for measuring the byte count of text when encoded with UTF-8.
Use the webpage: https://nightlynexus.github.io/utf8size
Read the source: https://github.com/NightlyNexus/utf8size
Carcassonne Tile Counter is a webpage that lets you mark Carcassonne tiles as used as you play, so you know which tiles are still in the deck.
Use the webpage: https://nightlynexus.github.io/CarcassonneTileCounter
Read the source: https://github.com/NightlyNexus/CarcassonneTileCounter
Tongiaki Tile Counter is a webpage that lets you mark Tongiaki tiles as used as you play, so you know which tiles are still in the deck.
Use the webpage: https://nightlynexus.github.io/TongiakiTileCounter
Read the source: https://github.com/NightlyNexus/TongiakiTileCounter
Hue Lockscreen is an app that controls my Hue lightbulbs from my Android home controls interface, an interface Android allows you to launch over the lock screen. This app shows a usage of Android’s esoteric and out-of-place ControlsProviderService API that allows apps to use the home controls interface.
Read the source: https://github.com/NightlyNexus/Hue-Lockscreen
Background Remover is an Android app that uses Google’s ML Kit to select only the foreground subject of an image using only your Android device’s CPU. I made this to scan the tiles for Tongiaki Tile Counter.
Get the app: https://play.google.com/store/apps/details?id=com.nightlynexus.backgroundremover
Read the source: https://github.com/NightlyNexus/BackgroundRemover
Exif Data Remover is an Android app that makes copies of jpeg picture files without their Exif metadata file sections.
Read the source: https://github.com/NightlyNexus/ExifDataRemover
Licensed.