1.0.1
General
RuStore In-app updates SDK enable users to be kept up to date with the latest app version on their device. This allows them to stay informed about any performance enhancements or bug fixes that have been implemented.
User scenario example
Additionally, the SDK offers the ability to notify users of a new version and provide an option to install it. The installation process can occur in the background, while the user can track the progress of the update.
- Kotlin
- Java
See the example app to learn how to integrate Updates SDK correctly.
See the example app to learn how to integrate Updates SDK correctly.
Prerequisites
For RuStore In-app updates SDK to operate correctly, the following conditions need to be met:
- Kotlin
- Java
- Android 7.0 or later
- RuStore app version on the device is up-to-date
- User is authorized in RuStore
- RuStore app is allowed to install applications
- Android 7.0 or later
- RuStore app version on the device is up-to-date
- User is authorized in RuStore
- RuStore app is allowed to install applications
Connecting to project
- Kotlin
- Java
Connect the repository:
repositories {
maven {
url = uri("https://artifactory-external.vkpartner.ru/artifactory/maven")
}
}
Add the following code to your configuration file to inject the dependency:
dependencies {
implementation("ru.rustore.sdk:appupdate:1.0.1")
}
Connect the repository:
repositories {
maven {
url = uri("https://artifactory-external.vkpartner.ru/artifactory/maven")
}
}
Add the following code to your configuration file to inject the dependency:
dependencies {
implementation("ru.rustore.sdk:appupdate:1.0.1")
}
Create update manager
- Kotlin
- Java
Create update manager before calling library methods.
val updateManager = RuStoreAppUpdateManagerFactory.create(context)
Create update manager before calling library methods.
RuStoreAppUpdateManager ruStoreAppUpdateManager = RuStoreAppUpdateManagerFactory.INSTANCE.create(context);
Check for updates
- Kotlin
- Java
Before requesting an update, check if it is available for your application To check for updates, call the getAppUpdateInfo()
method. When this method is called, the following conditions will be verified:
- The current version of RuStore is installed on the user's device.
- The user and the app are not banned in RuStore.
- RuStore app is allowed to install applications.
- User is authorized in RuStore.
Upon calling this method, the AppUpdateInfo
object will be returned which contains information regarding any required updates. It is recommended to request and cache this object in advance, ensuring a prompt and convenient update download process for the user.
ruStoreAppUpdateManager
.getAppUpdateInfo()
.addOnSuccessListener { appUpdateInfo ->
if (appUpdateInfo.updateAvailability == UpdateAvailability.UPDATE_AVAILABLE) {
// Update available(here you can integrate the listener and start downloading)
}
}
.addOnFailureListener { throwable ->
Log.e(TAG, "getAppUpdateInfo error", throwable)
}
AppUpdateInfo
object contains a set of parameters needed to determine if an update is available:
-
:updateAvailability
— update availability:UNKNOWN (int == 0)
— by default.;UPDATE_NOT_AVAILABLE (int == 1)
— no update required.;UPDATE_AVAILABLE (int == 2)
— update needs to be downloaded or it has already been downloaded to the user's device.;DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS (int == 3)
— update is already being downloaded or installation is already running..
-
:installStatus
— update installation status, if the user has already started the update installation at the time:UNKNOWN (int == 0)
— by default.;DOWNLOADED (int == 1)
— successfully downloaded.;DOWNLOADING (int == 2)
— currently being downloaded.;FAILED (int == 3)
— error.;PENDING (int == 5)
— awaiting update..
The update download is only available if the updateAvailability
field has the UPDATE_AVAILABLE
value.
Before requesting an update, check if it is available for your application To check for updates, call the getAppUpdateInfo()
method. When this method is called, the following conditions will be verified:
- The current version of RuStore is installed on the user's device.
- The user and the app are not banned in RuStore.
- RuStore app is allowed to install applications.
- User is authorized in RuStore.
Upon calling this method, the AppUpdateInfo
object will be returned which contains information regarding any required updates. It is recommended to request and cache this object in advance, ensuring a prompt and convenient update download process for the user.
ruStoreAppUpdateManager
.getAppUpdateInfo()
.addOnSuccessListener(appUpdateInfo -> {
if (appUpdateInfo.getUpdateAvailability() == UpdateAvailability.UPDATE_AVAILABLE) {
// Update available(here you can integrate the listener and start downloading)
}
})
.addOnFailureListener(throwable ->
Log.e(TAG, "getAppUpdateInfo error", throwable)
);
AppUpdateInfo
object contains a set of parameters needed to determine if an update is available:
-
:updateAvailability
— update availability:UNKNOWN (int == 0)
— by default.;UPDATE_NOT_AVAILABLE (int == 1)
— no update required.;UPDATE_AVAILABLE (int == 2)
— update needs to be downloaded or it has already been downloaded to the user's device.;DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS (int == 3)
— update is already being downloaded or installation is already running..
-
:installStatus
— update installation status, if the user has already started the update installation at the time:UNKNOWN (int == 0)
— by default.;DOWNLOADED (int == 1)
— successfully downloaded.;DOWNLOADING (int == 2)
— currently being downloaded.;FAILED (int == 3)
— error.;PENDING (int == 5)
— awaiting update..
The update download is only available if the updateAvailability
field has the UPDATE_AVAILABLE
value.
Download and install updates
Using listener
Once AppUpdateInfo
is received, you can check whether a push update is available.
Check update status
- Kotlin
- Java
Use registerListener()
.
ruStoreAppUpdateManager.registerListener { state ->
when (state.installStatus) {
InstallStatus.DOWNLOADED -> {
// The update is ready to be installed
}
InstallStatus.DOWNLOADING -> {
val totalBytes = state.totalBytesToDownload
val bytesDownloaded = state.bytesDownloaded
// Here you can display the download progress
}
InstallStatus.FAILED -> {
Log.e(TAG, "Downloading error")
}
}
}
The state
object describes the current download status. The object content is below
-
:installStatus
— update installation status, if the user has already started the update installation at the time:UNKNOWN (int == 0)
— by default.;DOWNLOADED (int == 1)
— successfully downloaded.;DOWNLOADING (int == 2)
— currently being downloaded.;FAILED (int == 3)
— error.;PENDING (int == 5)
— awaiting update.;
-
;bytesDownloaded
— number of bytes downloaded. -
;totalBytesToDownload
— total number of bytes that need to be downloaded. -
installErrorCode
— error code during download. Error structure is described in Error Handling.
Use registerListener()
.
ruStoreAppUpdateManager.registerListener(state -> {
switch (state.getInstallStatus()) {
case InstallStatus.DOWNLOADED:
// The update is ready to be installed
break;
case InstallStatus.DOWNLOADING:
long totalBytes = installState.getTotalBytesToDownload();
long bytesDownloaded = installState.getBytesDownloaded();
// Here you can display the download progress
break;
case InstallStatus.FAILED:
Log.e(TAG, "Downloading error");
break;
}
});
The state
object describes the current download status. The object content is below
-
:installStatus
— update installation status, if the user has already started the update installation at the time:UNKNOWN (int == 0)
— by default.;DOWNLOADED (int == 1)
— successfully downloaded.;DOWNLOADING (int == 2)
— currently being downloaded.;FAILED (int == 3)
— error.;PENDING (int == 5)
— awaiting update.;
-
;bytesDownloaded
— number of bytes downloaded. -
;totalBytesToDownload
— total number of bytes that need to be downloaded. -
installErrorCode
— error code during download. Error structure is described in Error Handling.
Delete listener
- Kotlin
- Java
If you no longer need a listener, use the unregisterListener()
method to remove a listener, passing a previously registered listener to the method.
ruStoreAppUpdateManager.unregisterListener(listener)
If you no longer need a listener, use the unregisterListener()
method to remove a listener, passing a previously registered listener to the method.
ruStoreAppUpdateManager.unregisterListener(listener);
Start downloading update
Delayed update
Running an upgrade script
Update with RuStore UI
- To confirm the update, the user is presented with a RuStore UI dialogue.
- When you click the Update button, a dialogue box will appear to confirm that the update has been installed.
- If the update is successfully installed, the application will be closed.
- Kotlin
- Java
Running an upgrade script
To start the download, use the startUpdateFlow()
method.
It's important to note that the AppUpdateInfo
object becomes obsolete after a single use. To call the startUpdateFlow()
method again, request AppUpdateInfo
, again using the getAppUpdateInfo()
method.
ruStoreAppUpdateManager
.startUpdateFlow(appUpdateInfo, AppUpdateOptions.Builder().build())
.addOnSuccessListener { resultCode ->
if (resultCode == Activity.RESULT_CANCELED) {
// The user refused to download
}
}
.addOnFailureListener { throwable ->
Log.e(TAG, "startUpdateFlow error", throwable)
}
If the user confirmed downloading the update, resultCode = Activity.RESULT_OK
, if refused, resultCode = Activity.RESULT_CANCEL
.
Once you receive the DOWNLOADED
status, you can call the completeUpdate() method to install the update.
It is advisable to notify the user that the update is prepared for installation at this point.
This method may return an error.
Running an upgrade script
To start the download, use the startUpdateFlow()
method.
It's important to note that the AppUpdateInfo
object becomes obsolete after a single use. To call the startUpdateFlow()
method again, request AppUpdateInfo
, again using the getAppUpdateInfo()
method.
ruStoreAppUpdateManager
.startUpdateFlow(appUpdateInfo, new AppUpdateOptions.Builder().build())
.addOnSuccessListener(resultCode -> {
if (resultCode == Activity.RESULT_CANCELED) {
// The user refused to download
}
})
.addOnFailureListener(throwable ->
Log.e(TAG, "startUpdateFlow error", throwable)
);
If the user confirmed downloading the update, resultCode = Activity.RESULT_OK
, if refused, resultCode = Activity.RESULT_CANCEL
.
Once you receive the DOWNLOADED
status, you can call the completeUpdate() method to install the update.
It is advisable to notify the user that the update is prepared for installation at this point.
This method may return an error.
Forced update
Running an upgrade script
Update with RuStore UI
- To confirm the update, the user is presented with a RuStore UI dialogue. Until the update is installed, use of the application will be blocked.
- When you click the Update button, a dialogue box will appear to confirm that the update has been installed.
- If you then click on the 'Install' button, a full-screen dialogue box will appear asking you to install the new app version.
- Once the installation is complete, the application will restart.
If the Rustore version is 1.37 or higher, the application will restart. If the version of Rustore is lower, the application will close to install the update. It will not reopen when the update is complete.
- Kotlin
- Java
Running an upgrade script
Once you receive AppUpdateInfo
, you can check the availability of the forced update.
if (appUpdateInfo.isUpdateTypeAllowed(IMMEDIATE)) {
// Forced update available
}
The result of isUpdateTypeAllowed
is recommended for deciding whether to run a forced update, but this result does not affect the ability to run the script. Your internal app logic determines the necessity to run the update script.
To start the installation, use the startUpdateFlow()
method.
ruStoreAppUpdateManager
.startUpdateFlow(appUpdateInfo, AppUpdateOptions.Builder().appUpdateType(IMMEDIATE).build())
.addOnSuccessListener { resultCode ->
}
.addOnFailureListener { throwable ->
}
resultCode (Int)
:
Activity.RESULT_OK (-1)
— update completed, the code may not be received as the app terminates at the time of update.Activity.RESULT_CANCELED (0)
— flow interrupted by user or an error occurred. When you receive this code, you are expected to exit the app.ActivityResult.ACTIVITY_NOT_FOUND (2)
— RuStore is not installed, or an installed version does not support forced updating (RuStore versionCode
<191
))
throwable
— error starting update script.
No further action is required if the update is successful.
Running an upgrade script
Once you receive AppUpdateInfo
, you can check the availability of the forced update.
if (appUpdateInfo.isUpdateTypeAllowed(IMMEDIATE)) {
// Forced update available
}
The result of isUpdateTypeAllowed
is recommended for deciding whether to run a forced update, but this result does not affect the ability to run the script. Your internal app logic determines the necessity to run the update script.
To start the installation, use the startUpdateFlow()
method.
ruStoreAppUpdateManager
.startUpdateFlow(appUpdateInfo, new AppUpdateOptions.Builder().appUpdateType(AppUpdateType.IMMEDIATE).build()
.addOnSuccessListener(resultCode -> {
})
.addOnFailureListener(throwable ->
);
resultCode (Int)
:
Activity.RESULT_OK (-1)
— update completed, the code may not be received as the app terminates at the time of update.Activity.RESULT_CANCELED (0)
— flow interrupted by user or an error occurred. When you receive this code, you are expected to exit the app.ActivityResult.ACTIVITY_NOT_FOUND (2)
— RuStore is not installed, or an installed version does not support forced updating (RuStore versionCode
<191
))
throwable
— error starting update script.
No further action is required if the update is successful.
Silent update
Silent Update Scenario Description
Update without RuStore UI
- The user will be presented with a dialogue box to confirm the installation of the update (the update will be downloaded in the background).
- If the update is successfully installed, the application will be closed.
- Kotlin
- Java
Running an upgrade script
To start the update, call the startUpdateFlow()
method with the AppUpdateInfo
argument received in getAppUpdateInfo
() and set the update type in AppUpdateOptions
to SILENT
.
ruStoreAppUpdateManager
.startUpdateFlow(appUpdateInfo, AppUpdateOptions.Builder().appUpdateType(SILENT).build())
.addOnSuccessListener { resultCode ->
}
.addOnFailureListener { throwable ->
}
When the onSuccessListener
is triggered with resultCode = Activity.RESULT_OK
, a task for downloading the update will be scheduled.
In this particular situation, either onSuccessListener
with resultCode = Activity.RESULT_OK
or onFailureListener
can be invoked.
After calling the method, you can monitor the status of the update download in the listener.
Once you receive the DOWNLOADED
status, you can call the completeUpdate() method to install the update. It is advisable to notify the user that the update is prepared for installation at this point.
Silent update requires a separate interface to operate.
Running an upgrade script
To start the update, call the startUpdateFlow()
method with the AppUpdateInfo
argument received in getAppUpdateInfo
() and set the update type in AppUpdateOptions
to SILENT
.
ruStoreAppUpdateManager
.startUpdateFlow(appUpdateInfo, new AppUpdateOptions.Builder().appUpdateType(AppUpdateType.SILENT).build())
.addOnSuccessListener { resultCode ->
}
.addOnFailureListener { throwable ->
}
When the onSuccessListener
is triggered with resultCode = Activity.RESULT_OK
, a task for downloading the update will be scheduled.
In this particular situation, either onSuccessListener
with resultCode = Activity.RESULT_OK
or onFailureListener
can be invoked.
After calling the method, you can monitor the status of the update download in the listener.
Once you receive the DOWNLOADED
status, you can call the completeUpdate() method to install the update. It is advisable to notify the user that the update is prepared for installation at this point.
Silent update requires a separate interface to operate.
Update installation
- Kotlin
- Java
To start the installation, use the completeUpdate()
method.
ruStoreAppUpdateManager
.completeUpdate()
.addOnFailureListener { throwable ->
Log.e(TAG, "update error", throwable)
}
The update is carried out through the native android tool. If the update is successfully installed, the application will be closed.
To start the installation, use the completeUpdate()
method.
ruStoreAppUpdateManager
.completeUpdate()
.addOnFailureListener(throwable -> {
Log.e(TAG, "update error", throwable)
});
The update is carried out through the native android tool. If the update is successfully installed, the application will be closed.
Errors processing
It is not recommended to display the error to the user yourself if you get onFailure
in response. It can negatively affect the user experience.
Possible errors
RuStoreNotInstalledException
— RuStore is not installed on the user's device;RuStoreOutdatedException
— RuStore version installed on the user's device does not support this SDK;RuStoreUserUnauthorizedException
— user is not authorized in RuStore;RuStoreException
— basic RuStore error from which other errors are inherited;RuStoreInstallException(public val code: Int)
— download and installation error.ERROR_UNKNOWN(Int = 4001)
— unknown error.ERROR_DOWNLOAD(Int = 4002)
— error while downloading.ERROR_BLOCKED(Int = 4003)
— installation blocked by system.ERROR_INVALID_APK(Int = 4004)
— invalid update APK.ERROR_CONFLICT(Int = 4005)
— conflict with the current app version.ERROR_STORAGE(Int = 4006)
— insufficient device storage.ERROR_INCOMPATIBLE(Int = 4007)
— incompatible with device.ERROR_APP_NOT_OWNED(Int = 4008)
— application not purchased.ERROR_INTERNAL_ERROR(Int = 4009)
— internal error.ERROR_ABORTED(Int = 4010)
— user refused to install the update.ERROR_APK_NOT_FOUND(Int = 4011)
— APK for installation not found.ERROR_EXTERNAL_SOURCE_DENIED(Int = 4012)
— update prohibited. For example, the first method responses that an update is not available, but the user calls the second method.ERROR_ACTIVITY_SEND_INTENT(Int = 9901)
— error while sending intent for opening an activity.ERROR_ACTIVITY_UNKNOWN(Int = 9902)
— unknown error on activity opening.