3.0.0
General
RuStore In-app updates SDK supports the current version of the application on the user's device. This helps the user see updates, evaluate performance improvements and the result of bug fixes.
User scenario example
Use RuStore In-app updates SDK to implement various update methods. Currently supported: delayed, silent (without UI from RuStore) and forced update.
Check out the sample application to learn how to properly integrate the update SDK.
Prerequisites
For the RuStore In-app updates SDK to work, the following conditions must be met.
- Data about the application has been loaded in the Push Notifications > Projects section from RuStore Console.
- The application has been moderated (it is not necessary to publish the application).
Signature and package name of various types of builds of your application (debug, release, etc.) may differ from each other. In this case, you should create in the section Push notifications > Projects from RuStore Console a project for each type of assembly.
- Android OS version 7.0 or higher.
- The version of RuStore on the user’s device is current.
- The user is authorized in RuStore.
- The RuStore application is allowed to install applications.
Connecting to the project
To connect the package to your project, run the following command.
flutter pub add flutter_rustore_update
This command will add a line to the pubspec.yaml file.
dependencies:
flutter_rustore_update: ^3.0.0
Check for updates
Before requesting an update, check to see if an update is available for your application. To check for updates, call the methodinfo(). When calling this method, the following conditions are checked.
- 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.
info object, which will contain information about the need for an update. Request this object in advance and cache it to prompt the user to start downloading the update without delay and at the user's convenience.
RustoreUpdateClient.info().then((info) {
print(info);
}).catchError((err) {
print(err);
});
info contains a set of parameters necessary to determine whether an update is available.
-
updateAvailability— update availability:UNKNOWN (int == 0)— by default;UPDATE_NOT_AVAILABLE (int == 1)— no update needed;UPDATE_AVAILABLE (int == 2)— an update is required to be downloaded or an update has already been downloaded to the user's device;DEVELOPER_TRIGGERED_UPDATE_IN_PROGRESS (int == 3)— the update is already downloading or installation has already started.
-
installStatus— update installation status if the user is already installing the update at the current time:UNKNOWN (int == 0)— by default;DOWNLOADED (int == 1)— downloaded;DOWNLOADING (int == 2)— downloading;FAILED (int == 3)— error;PENDING (int == 5)— in anticipation.
An update download can only be started if the updateAvailability field contains the valueUPDATE_AVAILABLE.
Download and install updates
Using listener
After confirming the availability of the update (AppUpdateInfo), you can request the update download status - to do this, run the update download status listener.
Check update status
For a silent update, it is recommended to implement your own interface.
Use the method listener().
RustoreUpdateClient.listener((state) {
switch (state.installStatus) {
case INSTALL_STATUS_DOWNLOADED:
// The update is ready to install.
break;
case INSTALL_STATUS_DOWNLOADING:
// Here you can display the download progress
break;
case INSTALL_STATUS_FAILED:
print("err ${state.installErrorCode}");
break;
}
});
The state object describes the current download status. Below is the contents of the object.
-
installStatus— update installation status if the user is already installing the update at the current time:UNKNOWN (int == 0)— by default;DOWNLOADED (int == 1)— downloaded;DOWNLOADING (int == 2)— downloading;FAILED (int == 3)— error;PENDING (int == 5)— in anticipation;
The update SDK does not have a special status for the situation when the user has canceled the update download. If the user aborted the update during the download phase, installStatus returns the original status UNKNOWN (0) with a Download button.
If the user has already downloaded the update, but canceled the installation, then installStatus will return the value DOWNLOADED (1).
Let's consider the following options.
- The user started downloading the update, but canceled the download - in this case:
updateAvailability-UPDATE_AVAILABLE(2);installStatus-UNKNOWN(0).
- The user downloaded the update file, but did not install it - in this case:
updateAvailability-UPDATE_AVAILABLE(2);installStatus-DOWNLOADED(1).
bytesDownloaded— number of bytes downloaded;totalBytesToDownload— the total number of bytes to download;installErrorCode— error code during download. Error codes are described in the section Error handling.
Start downloading update
Delayed update
Description of deferred update scenario
Update with UI from RuStore
- The user will be shown a dialog with the RuStore UI to confirm the update.
- When you click the Update button, a dialog box will appear to confirm the installation of the update.
Run update script
To start downloading an application update, call the download() method.
The AppUpdateInfo object becomes invalid after a single use. To call the startUpdateFlow() method again, request AppUpdateInfo using the info() method again.
RustoreUpdateClient.download().then((value) {
print("download code ${value.code}");
if (value.code == ACTIVITY_RESULT_CANCELED) {
// The user refused to download
}
}).catchError((err) {
print("download err ${err}");
}
);
If the user confirmed downloading the update, then resultCode = ACTIVITY_RESULT_OK, if he refused, then resultCode = ACTIVITY_RESULT_CANCELED.
After receiving the INSTALL_STATUS_DOWNLOADED status, you can call the install update method.
It is recommended to notify the user that the update is ready for installation.
The method may return an error.
Forced update
Description of the forced update scenario
Update with UI from RuStore
- The user will be shown a full-screen dialog with the RuStore UI to confirm the update. Application use will be blocked until the update is installed.
- When you click the Update button, a dialog box will appear to confirm the installation of the update.
- Next, when you click on the Install button, a full-screen dialog about installing a new version of the application will appear.
- Once the installation is complete, the application will restart.
The application will be restarted if the Rustore version is greater than or equal to 1.37. If the version of Rustore is lower, the application will close to install the update and will not be reopened when the update is completed.
Run update script
To start downloading a forced application update, call the immediate() method.
RustoreUpdateClient.immediate().then((value) {
print("silent code ${value.code}");
}).catchError((err) {
print("immediate err ${err}");
}
);
resultCode (Int):
ACTIVITY_RESULT_OK (-1)- the update has been completed, the code may not be received because the application is being terminated at the time of the update.ACTIVITY_RESULT_CANCELED (0)- the flow was interrupted by the user, or an error occurred. When you receive this code, you are expected to exit the application.ACTIVITY_RESULT_NOT_FOUND (2)- RuStore is not installed, or a version is installed that does not support forced updating (RuStore versionCode<191).
throwable — error starting the update script.
If the update is successful, no further action is required.
Silent update
Description of silent update scenario
Update without UI from RuStore
The user will be shown a dialog box to confirm the installation of the update (the update will be downloaded in the background).
Run update script
To start downloading a silent application update, call the silent() method.
RustoreUpdateClient.silent().then((value) {
print("silent code ${value.code}");
}).catchError((err) {
print("silent err ${err}");
}
);
Calling then with code = ACTIVITY_RESULT_OK will register a task to download the update.
In this scenario, only then can be called with ACTIVITY_RESULT_OK, or catchError.
After calling the method, you can monitor the update download status in the listener.
After receiving the INSTALL_STATUS_DOWNLOADED status, you can call the install update method. It is recommended to notify the user that the update is ready for installation.
For a silent update, it is recommended to implement your own interface.
Update installation
Once the update file download is complete, you can start installing the update. The update occurs through the native Android tool. To start the update installation, use the following methods:
completeUpdateFlexible()- update and restart the application;completeUpdateSilent()- update and close the application.
It is recommended to notify the user that the update is ready for installation.
Flexible upgrade completion
RustoreUpdateClient.completeUpdateFlexible().catchError((err) {
print("completeUpdateFlexible err ${err}");
});
Update with UI from RuStore:
-
The user will be shown a UI dialog to complete the update.
-
If the update is successful, the application will be restarted.
Silent upgrade completion
RustoreUpdateClient.completeUpdateSilent().catchError((err) {
print("completeUpdateSilent err ${err}");
});
Update without UI from RuStore:
- The update completion UI dialog will not be shown.
- If the update is successful, the application will be closed.
Errors processing
All errors in the plugin are implemented using constants. Description of constants in the file const.dart.
Error list
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.
List of dependencies for app update
ru.rustore.sdk:core:0.1.10— GNU Lesser General Public License v3.0;ru.rustore.sdk:analytics:0.1.5— GNU Lesser General Public License v3.0;org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20— The Apache Software License, Version 2.0;org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4— The Apache Software License, Version 2.0;androidx.core:core-ktx:1.9.0— The Apache Software License, Version 2.0;androidx.appcompat:appcompat:1.5.1— The Apache Software License, Version 2.0;androidx.activity:activity:1.5.1— The Apache Software License, Version 2.0.