Комментарии 7
Методика ничего, но "цель погана" (с). Вместо удушения одного маркета со всеми назойливыми уведомлениями об обновах душить каждую программку персонально? А если она не дает возможности отключить это мракобесие (привет, Опера)? А если она вообще волюнтаристски берет, качает новую версию и пытается поставить?
Нафиг-нафиг.
Кстати, спешу поделиться готовым решением для конечных юзеров: Obtainium. Считай, пакетный менеджер. Позволяет обновлять приложухи напрямую с полутора десятков ресурсов, в том числе с GitHub, GitLab, по прямой ссылке с фильтрами, шаблонами и т. д.
Сам им пользуюсь для обновления Nekobox, Youtube ReVanced, microG и прочих приложений, которые не найти в "правильных" экосистемах.
MANAGE_EXTERNAL_STORAGE
не нужен для обновлений. Никто не мешает во внутренние файлы приложения apk грузить, которые этого разрешения не требуют для работы. У нас таким образом все прекрасно без него работает, можно apk скачать и манифест глянуть, это разрешение в нем отсутствует. https://author.today/app/android/author-today.apk
Можно даже предыдущую версию скачать и убедиться что она обновляется. https://author.today/app/android/17061/author-today.apk
Интересный код однако)
CoroutineScope(Dispatchers.IO).launch(Dispatchers.IO)
Билдер корутин launch берет из скоупа, от которого вы запускаетесь, контекст, включая пуллы потоков, джобы, хендлеры ошибок и все прочее. Зачем тут дублирование?
Кроме того, флоу в объекте Downloader мутабельны и публичны, что дает возможность эмитить в них из любого места во всей кодовой базе.
val sizeFlow = MutableSharedFlow<Progress>()
Хорошая практика - оставлять мутабельную версию флоу приватной, а наружу выставлять только иммутабельный флоу:
private val _sizeFlow = MutableSharedFlow<Progress>()
val sizeFlow = _sizeFlow.asSharedFlow()
Автообновление через GitHub releases с помощью Hilt и Retrofit в Android