#android #kotlin #google-play #updates #auto-update
Вопрос:
Я пытаюсь внедрить обновления в приложении в новое приложение, которое я только что создал в Android Studio для тестирования. Приложение-это просто «привет, мир», но я реализовал проверку обновлений в приложении, как написано на этих двух страницах:
https://developer.android.com/guide/playcore/in-app-updates#kotlin
https://johncodeos.com/how-to-implement-in-app-updates-in-android-using-kotlin/
Мы используем Google play для работы (или фактическое название игрового магазина «частный доступ»), где мы загружаем наши бизнес-приложения, и эти приложения предназначены только для сотрудников, которые могут использовать их в магазинах. Но даже в этом случае у этих приложений есть ссылка, такая же, как у обычных (https://play.google.com/store/apps/details?id=country.company.appname.something)
Я думаю, что понимаю, как это работает (более или менее), но перед загрузкой приложения я хочу напрямую проверить по ссылке на другое приложение, работает ли оно.
Мой вопрос в том, могу ли я использовать одну из этих ссылок одного из наших приложений (на телефоне с доступом и, конечно, уже настроенном), чтобы проверить, работает ли проверка доступности обновлений, или я могу использовать ее только в новом приложении, которое я делаю, и, следовательно, мне нужно загрузить его и выполнить весь процесс с помощью этого «тестового» приложения
Я поместил здесь код, чтобы вы могли его увидеть. Некоторые закусочные предназначены только для отслеживания потока кода.
Класс UpdateInApp.kt:
package com.example.demoinappupdates
import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.snackbar.Snackbar
import com.google.android.play.core.appupdate.AppUpdateInfo
import com.google.android.play.core.appupdate.AppUpdateManager
import com.google.android.play.core.appupdate.AppUpdateManagerFactory
import com.google.android.play.core.install.InstallState
import com.google.android.play.core.install.InstallStateUpdatedListener
import com.google.android.play.core.install.model.AppUpdateType
import com.google.android.play.core.install.model.InstallStatus
import com.google.android.play.core.install.model.UpdateAvailability
class UpdateInApp(activity: Activity) : InstallStateUpdatedListener {
private var appUpdateManager: AppUpdateManager
private val MY_REQUEST_CODE = 500
private var parentActivity: Activity = activity
private var currentType = AppUpdateType.FLEXIBLE
init {
appUpdateManager = AppUpdateManagerFactory.create(parentActivity)
appUpdateManager.appUpdateInfo.addOnSuccessListener { info ->
// Check if update is available
Snackbar.make(
parentActivity.findViewById(R.id.activity_main_layout),
"Aquí, en el init, entra",
Snackbar.LENGTH_INDEFINITE).show()
if (info.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) { // UPDATE IS AVAILABLE
if (info.updatePriority() == 5) { // Priority: 5 (Immediate update flow)
if (info.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
startUpdate(info, AppUpdateType.IMMEDIATE)
}
} else if (info.updatePriority() == 4) { // Priority: 4
val clientVersionStalenessDays = info.clientVersionStalenessDays()
if (clientVersionStalenessDays != null amp;amp; clientVersionStalenessDays >= 5 amp;amp; info.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
// Trigger IMMEDIATE flow
startUpdate(info, AppUpdateType.IMMEDIATE)
} else if (clientVersionStalenessDays != null amp;amp; clientVersionStalenessDays >= 3 amp;amp; info.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
// Trigger FLEXIBLE flow
startUpdate(info, AppUpdateType.FLEXIBLE)
}
} else if (info.updatePriority() == 3) { // Priority: 3
val clientVersionStalenessDays = info.clientVersionStalenessDays()
if (clientVersionStalenessDays != null amp;amp; clientVersionStalenessDays >= 30 amp;amp; info.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
// Trigger IMMEDIATE flow
startUpdate(info, AppUpdateType.IMMEDIATE)
} else if (clientVersionStalenessDays != null amp;amp; clientVersionStalenessDays >= 15 amp;amp; info.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
// Trigger FLEXIBLE flow
startUpdate(info, AppUpdateType.FLEXIBLE)
}
} else if (info.updatePriority() == 2) { // Priority: 2
val clientVersionStalenessDays = info.clientVersionStalenessDays()
if (clientVersionStalenessDays != null amp;amp; clientVersionStalenessDays >= 90 amp;amp; info.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)) {
// Trigger IMMEDIATE flow
startUpdate(info, AppUpdateType.IMMEDIATE)
} else if (clientVersionStalenessDays != null amp;amp; clientVersionStalenessDays >= 30 amp;amp; info.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)) {
// Trigger FLEXIBLE flow
startUpdate(info, AppUpdateType.FLEXIBLE)
}
} else if (info.updatePriority() == 1) { // Priority: 1
// Trigger FLEXIBLE flow
startUpdate(info, AppUpdateType.FLEXIBLE)
} else { // Priority: 0
// Do not show in-app update
}
} else {
// UPDATE IS NOT AVAILABLE
/* Snackbar.make(
parentActivity.findViewById(R.id.activity_main_layout),
"El Snakcbar de prueba",
Snackbar.LENGTH_INDEFINITE).show() */
}
}
appUpdateManager.registerListener(this)
}
private fun startUpdate(info: AppUpdateInfo, type: Int) {
appUpdateManager.startUpdateFlowForResult(info, type, parentActivity, MY_REQUEST_CODE)
currentType = type
/* Snackbar.make(
parentActivity.findViewById(R.id.activity_main_layout),
"startupdate entra",
Snackbar.LENGTH_INDEFINITE).show() */
}
fun onResume() {
Snackbar.make(
parentActivity.findViewById(R.id.activity_main_layout),
"El Snakcbar de onresume",
Snackbar.LENGTH_INDEFINITE).setAction("ejej"){}.show()
appUpdateManager.appUpdateInfo.addOnSuccessListener { info ->
if (currentType == AppUpdateType.FLEXIBLE) {
// If the update is downloaded but not installed, notify the user to complete the update.
if (info.installStatus() == InstallStatus.DOWNLOADED)
flexibleUpdateDownloadCompleted()
} else if (currentType == AppUpdateType.IMMEDIATE) {
// for AppUpdateType.IMMEDIATE only, already executing updater
if (info.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
startUpdate(info, AppUpdateType.IMMEDIATE)
}
}
}
}
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == MY_REQUEST_CODE) {
if (resultCode != AppCompatActivity.RESULT_OK) {
// If the update is cancelled or fails, you can request to start the update again.
Log.e("ERROR", "Update flow failed! Result code: $resultCode")
}
}
}
private fun flexibleUpdateDownloadCompleted() {
Snackbar.make(
parentActivity.findViewById(R.id.activity_main_layout),
"An update has just been downloaded.",
Snackbar.LENGTH_INDEFINITE
).apply {
setAction("RESTART") { appUpdateManager.completeUpdate() }
setActionTextColor(Color.WHITE)
show()
}
}
fun onDestroy() {
appUpdateManager.unregisterListener(this)
}
override fun onStateUpdate(state: InstallState) {
if (state.installStatus() == InstallStatus.DOWNLOADED) {
flexibleUpdateDownloadCompleted()
}
}
}
Класс MainActivity.kt
package com.example.demoinappupdates
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.google.android.material.snackbar.Snackbar
class MainActivity : AppCompatActivity() {
private lateinit var inAppUpdate: UpdateInApp
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
inAppUpdate = UpdateInApp(this)
/* Snackbar.make(
this.findViewById(R.id.activity_main_layout),
"El Snakcbar de prueba",
Snackbar.LENGTH_INDEFINITE).show()*/
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
inAppUpdate.onActivityResult(requestCode,resultCode, data)
}
override fun onResume() {
super.onResume()
inAppUpdate.onResume()
}
override fun onDestroy() {
super.onDestroy()
inAppUpdate.onDestroy()
}
}
Ответ №1:
Я думаю, что это невозможно, так как то, что я пытаюсь сделать, можно сделать, только изменив идентификатор пакета, и это вызовет некоторые проблемы совместимости, основанные на том, что несколько приложений используют одно и то же.
Для записи, когда я ссылаюсь на идентификатор пакета, я имею applicationId
в виду файл build.gradle.