Android — In-app Update Manager

Salim Karsanbas
Paycell Tech Team
Published in
4 min readJun 10, 2024

Mobil uygulama dünyasında, uygulamanızın güncel kalması kullanıcı memnuniyeti açısından kritik öneme sahiptir. In-app update (uygulama içi güncelleme) bu konuda önemli bir rol oynar. Bu makalede, in-app update’in ne olduğunu, neden gerekli olduğunu ve nasıl yönetebileceğinizi anlatacağım.

In-App Update Nedir ve Nasıl Çalışır?

In-app update, kullanıcıların uygulamadan çıkmadan uygulamayı güncellemelerine olanak tanır. Bu özellik, kullanıcıların en son özelliklere ve önemli güvenlik güncellemelerine hemen erişmesini sağlar.

Neden In-App Update Kullanmalıyız?

  • Kullanıcılar, yeni özelliklere hemen erişebilir, bu da kullanıcı memnuniyetini artırır.
  • Kullanıcılar, en son güvenlik güncellemeleriyle korunur.
  • Kritik hata düzeltmeleri, anında kullanıcılara ulaşır.
  • Kullanıcılar, uygulamayı terk etmeden güncellemeleri alır, bu da deneyimi iyileştirir.

In-App Update Türleri

In-app update, iki farklı şekilde sunulabilir:

  1. Anında Güncelleme (Immediate Update):

Genellikle “Force Update” olarak bildiğimiz güncelleme türünün karşılığıdır. Bu türdeki güncelleme, kullanıcıların uygulamayı kullanmaya devam etmeleri için güncellemeyi yapmalarını gerektirir. Kullanıcılar güncelleme tamamlanana kadar uygulamayı kullanamazlar. Kritik güvenlik güncellemeleri veya önemli hata düzeltmeleri için kullanabilirsiniz.

Immediate Update

In-app update yapısında kullanıcılar güncellemeyi indirdikten sonra uygulama otomatik olarak yeniden başlatılır.

2. Esnek Güncelleme (Flexible Update):

Esnek güncellemeler, kullanıcıların uygulamayı kullanmaya devam ederken arka planda güncellemenin indirilmesini sağlar. Güncelleme tamamlandığında, kullanıcı bilgilendirilir ve uygulamayı yeniden başlatması istenir. Bu sayede kullanıcı deneyimini kesintiye uğratmadan yeni özellikleri sunabilirsiniz.

Flexible update

Kotlin ile In-App Update Nasıl Entegre Edilir?

İlk adım olarak, in-app update için gerekli kütüphaneyi projenize dahil etmeniz gerekiyor. Bunun için build.gradle dosyanıza aşağıdaki bağımlılığı ekleyin:

dependencies {
implementation("com.google.android.play:app-update:2.1.0")
implementation("com.google.android.play:app-update-ktx:2.1.0")
}

Ardından hangi güncelleme türünü kullanacağımızı ve hangisinin kullanılabilir olduğunu kontrol etmemiz gerekiyor. Güncelleme olup olmadığı bilgisiAppUpdateManagerile kontrol edilir.

updateAvailability() fonksiyonu, mevcut güncelleme durumunu kontrol eder.

appUpdateInfo.isFlexibleUpdateAllowed -> Flexible update uygunluğunu kontrol eder
appUpdateInfo.isImmediateUpdateAllowed -> Immediate update uygunluğunu kontrol eder


var appUpdateManager: AppUpdateManager? = null
var updateType = -1 // AppUpdateType.IMMEDIATE veya AppUpdateType.FLEXIBLE

fun init(activity: Activity, launcher: ActivityResultLauncher<IntentSenderRequest>) {
appUpdateManager = AppUpdateManagerFactory.create(activity)
activityResultLauncher = launcher
}

private fun checkUpdate() {
appUpdateManager?.appUpdateInfo?.addOnSuccessListener { appUpdateInfo ->
val isUpdateAvailable =
appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE
val isUpdateAllowed = when (updateType) {
AppUpdateType.FLEXIBLE -> appUpdateInfo.isFlexibleUpdateAllowed
AppUpdateType.IMMEDIATE -> appUpdateInfo.isImmediateUpdateAllowed
else -> false
}

// güncelleme uygunluğu kontrol edildikten sonra istekte bulunulur
if (isUpdateAvailable && isUpdateAllowed) {
requestUpdate(appUpdateInfo)
}
}?.addOnFailureListener { failure->
// hata caselerini mutlaka yönetmelisiniz
}
}

private fun requestUpdate(appUpdateInfo: AppUpdateInfo) {
val updateOptions = AppUpdateOptions.newBuilder(updateType).build()
val intentSenderForResultStarter =
IntentSenderForResultStarter { intentSender, requestCode, fillInIntent, flagsMask, flagsValues, extraFlags, bundle ->
activityResultLauncher.launch(IntentSenderRequest.Builder(intentSender).build())
}

// Güncellemeyi başlatın
appUpdateManager?.startUpdateFlowForResult(
appUpdateInfo,
intentSenderForResultStarter,
updateOptions,
IN_APP_UPDATE_REQUEST_CODE
)
}

Güncelleme için istekte bulunduktan sonra hata alınmaz ise seçtiğiniz tür native olarak kullanıcıya gösterilir. Güncellemenin sonucunu aşağıdaki koddan takip edebilirsiniz.

activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), result -> {
if (result.getResultCode() == RESULT_OK) {
// indirme başarılı
} else {
// güncelleme kullanıcı tarafında reddedildi veya başka bir
}
});

Güncellemenin ne durumda olduğunu kontrol edebilmek için in-app updatein InstallStateUpdatedListener interfaceine register olmanız gerekir.

private val installStateUpdatedListener = InstallStateUpdatedListener {
when (it.installStatus()) {
InstallStatus.DOWNLOADED -> {
// burada kullanıcı güncellemeyi indirmiştir ve güncellemenin
// yüklenebilmesi için uygulamanın baştan başlatılması gerekir
}
InstallStatus.INSTALLED -> {}
InstallStatus.CANCELED -> {}
InstallStatus.DOWNLOADING -> {}
InstallStatus.FAILED -> {}
InstallStatus.INSTALLING -> {}
InstallStatus.PENDING -> {}
InstallStatus.UNKNOWN -> {}
InstallStatus.REQUIRES_UI_INTENT -> {}
}
}

override fun onResume() {
super.onResume()
when (inAppUpdateManager.updateType) {
AppUpdateType.FLEXIBLE -> {
inAppUpdateManager.registerListener()
}
AppUpdateType.IMMEDIATE -> {
inAppUpdateManager.appUpdateManager.appUpdateInfo
.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability() == UpdateAvailability.DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS) {
try {
inAppUpdateManager.appUpdateManager.startUpdateFlowForResult(
appUpdateInfo,
inAppUpdateManager.updateType,
requireActivity(),
IN_APP_UPDATE_REQUEST_CODE
)
} catch (e: IntentSender.SendIntentException) {
throw RuntimeException(e)
}
}
}
}
}
}

override fun onDestroy() {
super.onDestroy()
if (inAppUpdateManager.updateType == AppUpdateType.FLEXIBLE) {
inAppUpdateManager.unregisterListener()
}
}

Güncelleme arka planda indirildikten sonra uygulamanın yeniden başlatılması gerekir.

appUpdateManager.completeUpdate()

Bu kod ile indirilen güncellemenin kurulması sağlanır. Ancak kullanıcı uygulama içinde gezinirken bir anda uygulamanın kapatılması kullanıcı deneyimini kötü etkilecektir. Bunun önüne geçebilmek için kullanıcıyı uygulamayı yeniden başlatması için uyarmak deneyim açısından daha doğru bir seçim olacaktır.

Sonuç

Güvenlik açıklarıyla mücadele etmek, yeni özellikler sunmak ve kullanıcı deneyimini sürekli olarak iyileştirmek için in-app update yapısı projelerimiz için bir avantajlı bir yapıdır. Kendi projenize entegre ettiğiniz in-app update yapısıyla kullanıcıların en son güncellemeleri anında yakalamalarını sağlayabilirsiniz.

--

--