Migrate subscription icons from cache to files

This commit is contained in:
Philipp Heckel 2026-04-03 21:22:34 -04:00
parent a29e55f982
commit ff128772ed
7 changed files with 49 additions and 2 deletions

View file

@ -575,6 +575,9 @@ interface SubscriptionDao {
""")
fun getLastNotificationId(subscriptionIds: Collection<Long>): String?
@Query("UPDATE subscription SET icon = :icon WHERE id = :subscriptionId")
fun updateSubscriptionIcon(subscriptionId: Long, icon: String?)
@Query("DELETE FROM subscription WHERE id = :subscriptionId")
fun remove(subscriptionId: Long)
}

View file

@ -92,6 +92,10 @@ class Repository(private val sharedPrefs: SharedPreferences, database: Database)
subscriptionDao.update(subscription)
}
fun updateSubscriptionIcon(subscriptionId: Long, icon: String?) {
subscriptionDao.updateSubscriptionIcon(subscriptionId, icon)
}
@Suppress("RedundantSuspendModifier")
@WorkerThread
suspend fun removeSubscription(subscription: Subscription) {

View file

@ -486,7 +486,7 @@ class DetailSettingsActivity : AppCompatActivity() {
}
private fun createUri(): Uri? {
val dir = File(requireContext().cacheDir, SUBSCRIPTION_ICONS)
val dir = File(requireContext().filesDir, SUBSCRIPTION_ICONS)
if (!dir.exists() && !dir.mkdirs()) {
return null
}
@ -526,7 +526,6 @@ class DetailSettingsActivity : AppCompatActivity() {
companion object {
private const val TAG = "NtfyDetailSettingsActiv"
private const val SUBSCRIPTION_ICONS = "subscriptionIcons"
private const val SUBSCRIPTION_ICON_MAX_SIZE_BYTES = 4194304
private const val SUBSCRIPTION_ICON_MAX_WIDTH = 2048
private const val SUBSCRIPTION_ICON_MAX_HEIGHT = 2048

View file

@ -61,6 +61,7 @@ import io.heckel.ntfy.msg.Poller
import io.heckel.ntfy.service.SubscriberService
import io.heckel.ntfy.service.SubscriberServiceManager
import io.heckel.ntfy.util.Log
import io.heckel.ntfy.util.SUBSCRIPTION_ICONS
import io.heckel.ntfy.util.dangerButton
import io.heckel.ntfy.util.displayName
import io.heckel.ntfy.util.formatDateShort
@ -76,8 +77,10 @@ import io.heckel.ntfy.work.PollWorker
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File
import java.util.Date
import java.util.concurrent.TimeUnit
import androidx.core.content.FileProvider
import androidx.core.view.size
import androidx.core.view.get
import androidx.core.net.toUri
@ -380,6 +383,9 @@ class MainActivity : AppCompatActivity(), AddFragment.SubscribeListener, Notific
// Permissions
maybeRequestNotificationPermission()
// FIXME 2026-05-04: Remove this migration after 1 month
migrateSubscriptionIconsFromCache()
}
private fun maybeRequestNotificationPermission() {
@ -894,6 +900,38 @@ class MainActivity : AppCompatActivity(), AddFragment.SubscribeListener, Notific
adapter.notifyItemRangeChanged(0, adapter.currentList.size)
}
// FIXME 2026-05-04: Remove this migration after 1 month
private fun migrateSubscriptionIconsFromCache() {
lifecycleScope.launch(Dispatchers.IO) {
delay(5_000) // 5 seconds
try {
val oldDir = File(cacheDir, SUBSCRIPTION_ICONS)
if (!oldDir.exists() || !oldDir.isDirectory) return@launch
val newDir = File(filesDir, SUBSCRIPTION_ICONS)
if (!newDir.exists()) newDir.mkdirs()
oldDir.listFiles()?.forEach { oldFile ->
val newFile = File(newDir, oldFile.name)
if (newFile.exists()) {
oldFile.delete()
return@forEach
}
if (oldFile.renameTo(newFile)) {
val subscriptionId = oldFile.name.toLongOrNull() ?: return@forEach
val newUri = FileProvider.getUriForFile(
this@MainActivity,
BuildConfig.APPLICATION_ID + ".provider",
newFile
)
repository.updateSubscriptionIcon(subscriptionId, newUri.toString())
}
}
oldDir.delete()
} catch (e: Exception) {
Log.w(TAG, "Failed to migrate subscription icons", e)
}
}
}
companion object {
const val TAG = "NtfyMainActivity"
const val EXTRA_SUBSCRIPTION_ID = "subscriptionId"

View file

@ -1,6 +1,7 @@
package io.heckel.ntfy.util
const val ANDROID_APP_MIME_TYPE = "application/vnd.android.package-archive"
const val SUBSCRIPTION_ICONS = "subscriptionIcons"
const val PRIORITY_MIN = 1
const val PRIORITY_LOW = 2

View file

@ -2,4 +2,5 @@
<paths>
<external-path name="external_files" path="."/>
<cache-path name="cache_files" path="."/>
<files-path name="files" path="."/>
</paths>

View file

@ -4,3 +4,4 @@ Features:
Bug fixes + maintenance:
* Undo automatic phone number linking for numbers in message body (ntfy-android#170, thanks to @acortelyou for the contribution)
* Fix subscription icons disappearing after a few days due to Android clearing cache (#1322, thanks to @mcanning for reporting)